Today, we released a Fix it workaround tool to address a new IE vulnerability that had been actively exploited in extremely limited, targeted attacks.  This Fix it makes a minor modification to mshtml.dll when it is loaded in memory to address the vulnerability. This Fix it workaround tool is linked from Security Advisory 2887505 that describes this issue.  The exploit we analyzed worked only on Windows XP or Windows 7 running Internet Explorer 8 or 9.  Here are the links to both apply and uninstall the Fix it solution:

Enable Fix itDisable Fix it

The Exploit

The exploit was attacking a Use After Free vulnerability in IE’s HTML rendering engine (mshtml.dll) and was implemented entirely in Javascript (no dependencies on Java, Flash etc), but did depend on a Microsoft Office DLL which was not compiled with ASLR (Address Space Layout Randomization) enabled. This DLL (hxds.dll) is loaded into IE by the HTML href attribute shown below:

try { location.href = 'ms-help://' } catch (e) { }

The purpose of this DLL in the context of this exploit is to bypass ASLR by providing executable code at known addresses in memory, so that a hardcoded ROP (Return Oriented Programming) chain can be used to mark the pages containing shellcode (in the form of Javascript strings) as executable. This can be seen by the fact that ALL the gadgets used by the ROP chain were contained in hxds.dll.

Control over the EIP (x86 Instruction Pointer) was gained by reallocating erroneously freed memory on the Low Fragmentation Heap via maliciously formatted Javascript strings, and then waiting for a Virtual Function to be called on the freed object. The attacker gained control over EIP, and made it point into the heap around address 0x12121212 which contained a ROP chain. Below is the contents of the ROP chain:

Addr            Data                 Significance
12121212  51c3b376    //ret
12121216  51c3b376    //ret
1212121a  51c3b376    //ret
1212121e  51c3b376    //ret
12121222  51c3b376    //ret
12121226  51c3b376    //ret
1212122a  51c3b376    //ret
1212122e  51c3b376    //ret
12121232  51c3b376    //ret
12121236  51c3b376    //ret
1212123a  51c3b376    //ret
1212123e  51c3b376    //ret
12121242  51c3b376    //ret
12121246  51c3b376    //ret
1212124a  51c3b376    //ret
1212124e  51c3b376    //ret
12121252  51c3b376    //ret
12121256  51c3b376    //ret
1212125a  51c3b376    //ret
1212125e  51c3b376    //ret
12121262  51c3b376    //ret
12121266  51c3b376    //ret
1212126a  51c3b376    //ret
1212126e  51c3b376    //ret
12121272  51c3b376    //ret
12121276  51c3b376    //ret
1212127a  51c3b376    //ret
1212127e  51c2046e    //pop edi;  ret
12121282  51be4a41    //xchg eax, esp;  ret                     stack pivot. we call into here
12121286  51c2046e    //pop edi;  ret
1212128a  51bd10b8    //VirtualProtect IAT entry in hxds
1212128e  51c0e455    //mov eax, [edi];  pop edi;  ret          move VirtualProtect address in to eax and waste next ROP chain link
12121292  51c3b376    //ret
12121296  51bd71f4    //push eax;  ret                          push VirtualProtect address, and ret into it
1212129a  121212da    return address after VirtualProtect (Shellcode)
1212129e  12121212    lpAddress                                 //VirtualProtect(lpAddress = 12121212, dwSize = 00001000,
121212a2  00001000    dwSize                                    //flNewProtect = 00000040 = PAGE_EXECUTE_READWRITE,
121212a6  00000040    flNewProtect                              //   lpflOldProtect = 12120a0c)
121212aa  12120a0c    lpflOldProtect                            //

EMET 4.0

EMET 4.0 can be used to help protect against the exploit we analyzed that attempts to exploit this vulnerability. The specific mitigations to enable are as follows:

    • Mandatory ASLR
    • ROP
      • Enable MemProt
      • Enable Caller
      • Enable SimExecFlow
      • Enable StackPivot
    • Heap Spray
      • Find the value of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EMET\iexplore.exe\ *\Internet Explorer\iexplore.exe
      • Open HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EMET\_settings_\VALUE_FROM_STEP_1\heap_pages
      • Add 0x12121212 to the list

FixIt

We also built an appcompat shim as a temporary Advanced Workaround to help protect against attempts to exploit this vulnerability.

There are only 23 patched bytes in whole Fix it to mitigate the vulnerability. The 23 patched bytes occur in two locations-the caller to redirect execution to the shim code, and the shim code itself. Here is an explanation of the patched bytes and what they do in IE9 running on Windows 7:

Before Fix it:

mshtml!CDoc::SetMouseCapture [j:\win7\inetcore\mshtml\src\site\base\ipwnd.cxx @ 3211]:
8bff            mov     edi,edi
55              push    ebp
8bec            mov     ebp,esp
81eca0000000    sub     esp,0A0h
53              push    ebx
8b5d08          mov     ebx,dword ptr [ebp+8]
56              push    esi
57              push    edi
8bf9            mov     edi,ecx
f7879807000000100000 test dword ptr [edi+798h],1000h
8bf0            mov     esi,eax
0f855b000400 jne mshtml!CDoc::SetMouseCapture+0x21 (6ca068f1)
85db            test    ebx,ebx
0f855a000400    jne     mshtml!CDoc::SetMouseCapture+0x32 (6ca068f8)
53              push    ebx
e88d2affff      call    mshtml!CDoc::ClearMouseCapture (6c9b9331)

mshtml!_NULL_IMPORT_DESCRIPTOR+0x420b:
 0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al 
0000 add byte ptr [eax],al

After FixIt:

mshtml!CDoc::SetMouseCapture [j:\win7\inetcore\mshtml\src\site\base\ipwnd.cxx @ 3211]:
8bff            mov     edi,edi
55              push    ebp
8bec            mov     ebp,esp
81eca0000000    sub     esp,0A0h
53              push    ebx
8b5d08          mov     ebx,dword ptr [ebp+8]
56              push    esi
57              push    edi
8bf9            mov     edi,ecx
f7879807000000100000 test dword ptr [edi+798h],1000h
8bf0            mov     esi,eax
0f855b000400    jne     mshtml!CDoc::SetMouseCapture+0x21 (6c6d68f1)
85db            test    ebx,ebx
0f856d8d6700 jne mshtml!_NULL_IMPORT_DESCRIPTOR+0x420b (6cd0f60b)
53              push    ebx
e88d2affff      call    mshtml!CDoc::ClearMouseCapture (6c689331)

mshtml!_NULL_IMPORT_DESCRIPTOR+0x420b:
66f743260100 test word ptr [ebx+26h],1 
0f848d7298ff je mshtml!CDoc::SetMouseCapture+0x227 (6c6968a4) 
e9dc729cff jmp mshtml!CDoc::SetMouseCapture+0x32 (6c6d68f8)

As you can see, the code in the NULL_IMPORT_DESCRIPTOR is the actual logic in this FixIt that stops the vulnerability. It all depended on checking a flag in one of the C++ objects.

This was a complicated FixIt to build because of all the variations with all the versions we had to shim, so thanks to everyone who helped in examining this case! Specifically, thanks to Michael Howell and Han Li on the IE team for helping test many of the different combinations IE Versions/Languages/Operating Systems, and Elias Bachaalany for advice on safe shim code locations within the address space.

- Neil Sikka, MSRC Engineering
@neilsikka