CVE-2013-3893 – Analysis of the New IE 0-Day
By Gal Badishi | October 7, 2013
Recently, an exploit targeting a 0-day vulnerability in Internet Explorer has been spotted in the wild. This vulnerability exists in all versions of Internet Explorer, from IE 6 to IE 11, but the attacks found in the wild only target IE 8 and 9 on Windows XP and Windows 7, and are believed to be part of an APT campaign targeting the Asia-Pacific region. As of today, no official patch for the vulnerability exists, although Microsoft has issued a FixIt that aims to mitigate the risk of the attack. We will now provide some technical details of the exploitation techniques used in the 0-day vulnerability.
The use-after-free vulnerability resides in the javascript engine in mshtml.dll, where a div object can be allocated and freed, but a reference to the freed object still remains and its use can be triggered by the attacker. By replacing the freed contents with crafted data, the attacker can achieve code execution. The exploit code has been programmed to detect many languages (EN, ZH, FR, DE, JA, PT, KO, RU), but only contains a unique ROP-chain for English, Chinese, Korean and Japanese. If the exploitation is successful, a targeted malware is dropped onto the attacked machine in order to steal sensitive information.
In this post we will concentrate on the exploitation techniques used in order to achieve code execution, before the malicious payload gets a chance to run. Let’s follow the exploitation steps as they are found in the actual exploit.
The first order of business is to allocate div objects. The attacker chose to allocate 10,000 objects, but such a high number is not necessary, as the same result can be obtained with a relatively small number of allocations. Each instance of the allocated div object has a title attribute with its value being the address 0×12121202 repeated 20 or 22 times, depending on whether IE 8 or IE 9 is targeted.
The next order of business is to free the title attribute in the array of div objects. Freeing even a single object is enough to get the vulnerability-triggering into motion, but the attacker chose to free 5,000 out of the 10,000 allocations. We will continue to see places in which it is not exactly clear what the attacker’s considerations were.
After freeing the objects, a sup and audio elements are created to handle the capture events, which are triggered by the javascript code itself, by calling the setCapture() method. The handler starts by calling document.write(“”), which releases the CTreeNode objects representing the aforementioned allocated objects:
021cbc90 6a5d02fe 0053ef34 0053ef00 0053ef00 mshtml!CTreeNode::Release+0x27 (FPO: [0,0,0])
021cbcf4 6a5d07e0 0053ef00 00000001 00000001 mshtml!CMarkup::DestroySplayTree+0x37c
021cbd60 6a5d1f3c 00000000 00000001 0053ef00 mshtml!CMarkup::UnloadContents+0x380
021cbd7c 6a5d1ec3 0053ef00 00000001 00000001 mshtml!CMarkup::TearDownMarkupHelper+0x55
021cbda8 6a49ee78 00000001 00000001 0053f188 mshtml!CMarkup::TearDownMarkup+0x55
021cbe10 6a403685 0053f188 00000000 00000003 mshtml!COmWindowProxy::SwitchMarkup+0x5b8
021cbf0c 6a400ea1 004dc280 00000000 00000000 mshtml!CDocument::open+0x426
021cbf88 6a4b554e 004dc280 00511350 0153bce0 mshtml!CDocument::write+0x7c
Which leads us to a HeapFree:
At this point the attacker chooses to spray the heap with ROP gadgets that depend on the version of the operating system and of Microsoft Office on the target computer. On Windows 7, the attacker constructs the ROP-chain over a non-ASLR-compatible MS Office DLL named hxds.dll, loaded using the following piece of code:
try{location.href='ms-help://'} catch(e){}
Combining the ROP-chain heap-spray and the fact that hxds.dll resides in a known location in memory, the attacker is able to bypass DEP and ASLR. All of these exploitation techniques are thwarted by Cyvera TRAPS.
The insertion of the heap-spraying code in the middle of the vulnerability-triggering code is somewhat unnatural. Nevertheless, the attacker follows to create a new array of div objects the same way it did before, filling the previously freed CTreeNode objects with the new content. The freed objects are filled with the address 0×12121202, which contains a pointer to 0×12121212:
The CTreeNode object is being referenced in mshtml!CElement::Doc. When mshtml!CElement::Doc is called with 0×12121202 it dereferences the pointer, adds 0×70 to it, and then performs a call to the calculated address (which means it will call the address that resides in 0×12121282):
At 0×12121282 resides a pointer to the pivoting code, which differs depending on the operating system’s version. On Windows XP it uses msvcrt.dll due to the lack of ASLR, on Vista/Windows 7 it uses hxds.dll which is a non-ASLR-compatible module. The stack-pivoting code in hxds.dll goes as follows:
We can see the stack-trace leading to that:
0234cda0 6a13265f 00000000 02d676d0 00355c68 hxds!DllGetClassObject+0x11f90
0234ce24 6a1bb174 0234ce48 00000000 00000000 mshtml!CDoc::PumpMessage+0x4b4
0234cee0 6a28025d 02d67700 00000001 02d676d0 mshtml!CDoc::SetMouseCapture+0xe7
0234cf08 69f8b1c9 00379268 0000ffff 011f9db0 mshtml!CElement::setCapture+0x51
The stack is pivoted to the ROP-chain sprayed on the heap. The ROP-chain starts with several ROP-nops, but it is not clear whether there is any need for that. The ROP-gadgets themselves simply call VirtualProtect to change the memory protection to PAGE_READWRITE_EXECUTE for the pages containing the attacker’s shellcode (marked by 0×41414141 in this figure):
The shellcode itself starts with resolving the addresses of functions from system DLLs using the very common technique of parsing the export tables of those DLLs, and then continues with its malicious activity.
An old version of Cyvera TRAPS was tested against the exploit found in the wild, and stopped the exploitation attempt in 6 different places, again proving its effectiveness against 0-day attacks. Cyvera TRAPS nips the exploit in the bud, without the payload ever getting a chance to run, maintaining a pristine state of the machine. Additionally, recent versions of Cyvera TRAPS stopped actual variants of the exploit in Cyvera’s customers’ production environments protected by TRAPS.
I would like to thank Shahar S., a senior researcher in Cyvera, for the technical analysis presented in this post.