0x00:前言
记录一次漏洞调试的学习过程,实验环境的一些文件我已上传到GitHub上,欢迎下载,欢迎志同道合的朋友一起交流学习。
0x01:实验环境
- Windows XP SP3(虚拟机)
- Adobe Reader 9.3.4(版本不能高于9.3.4)
- IDA_Pro_v6.8_and_Hex-Rays_Decompiler_(ARM,x64,x86)_Green(静态分析)
- PdfStreamDumper.exe(PDF二进制分析工具)
- Ollydbg(动态调试)
- msf.pdf(漏洞文件)
漏洞文件的生成:
msfconsole
search cve-2010-2883
use exploit/windows/fileformat/adobe_cooltype_sing
set payload windows/exec
set cmd calc.exe
exploit
Adobe Reader 9.3.4+PdfStreamDumper.exe+msf.pdf下载地址:
https://github.com/ThunderJie/CVE/tree/master/CVE-2010-2883
0x02:涉及知识点
- Stack Overflow(栈溢出)
- Heap Spray(堆喷射)
- 文件偏移计算
- OD动态调试
- IDA静态分析等
0x03:漏洞分析
- IDA静态分析CoolType.dll找到漏洞点
搜索字符串“SING”找到溢出点,可以看到这里strcat()函数之前未对uniqueName长度进行检测就复制,造成溢出搜索字符串“SING”找到溢出点,可以看到这里strcat()函数之前未对uniqueName长度进行检测就复制,造成溢出
- PDFStreamDumper分析文件偏移
TTF(TrueTypeFont)是Apple公司和Microsoft公司共同推出的字体文件格式,随着windows的流行,已经变成最常用的一种字体文件表示方式,官方文档对TTF中SING表的TableEntry定义如下:
typedef sturct_SING
{
char tag[4]; //"SING"
ULONG checkSum;//校验和
ULONG offset; //相对文件偏移
ULONG length; //数据长度
} TableEntry;
我们通过PDFStreamDumper导入漏洞文件,找到TableEntry 从TableEntry结构入口偏移0x11c即为SING表真实数据,也就是从00 00 01 00开始的部分
又根据SING表的数据结构,再偏移0x10即为uniqueName域,如下图:
strcat函数执行后,将00 00 00 3A之后的数据复制到ebp指定地址直到下图的NULL为止
- OD进行动态调试
打开Adobe Reader 用OD附加此程序,F9运行,crtl+g设置断点在0x803DD9F处,Adobe Reader中打开msf.pdf自动中断在0x803DD89F处运行一步将数据窗口的值跟随EAX的值,对比PDFStreamDumper的值,这段汇编将已经在内存里的uniqueName域copy至程序所运行的栈中
选中所有的shelloce,在上面下内存访问断点,F9运行,开始寻找执行shellcode的代码。
F9运行第一次断在这里,取出了一个byte比较,没有到关键点,继续运行
继续运行有很多比较的地方,运行到这里是循环取出4byte的数据,但是还没有到关键点,继续运行
一直运行到这里,终于到关键点了,这里有一个调用虚表的指令,一开始虚表是存在栈上的,但是被我们溢出覆盖成了恶意地址
软件因为自带DEP保护,需要用到Heap Spray技术和构造ROP链来绕过,ROP的地址选取的是0x4a82a714和0x4a80cb38两处地址,因为在Adobe Reader各个版本中这个dll上的这两个地址不会改变,如下图
继续运行可以看到调用在icucnv36.dll中的内容
运行分析第一处ROP
pop esp
retn
查看堆栈情况变化
继续运行来到第二处ROP
pop ecx
retn
时刻关注堆栈情况
继续运行来到第三处ROP
mov dword ptr ds:[ecx],eax
retn
时刻关注堆栈情况
运行来到第四次ROP,这里保存了CreateFileA函数地址
pop eax
retn
时刻关注堆栈情况
继续运行,这里跳转到函数地址准备调用函数
这里打开或创建了iso88591文件
继续运行了几次之后发现后面的rop链是为了调用这三个函数,CreateFileMappingA()函数实现创建文件内存映射,后面两个函数作用是将shellcode拷贝到内存可执行段,实现方法和前面很相似,就不放那么多照片了。
继续运行到这里可以看到正在执行shellcode部分
运行到了这里终于要到了调用计算器的地方
最终调用到计算器,完成测试
0x04:总结
第一次记录关于调试CVE漏洞的文章,实践起来确实加深了对漏洞的理解,虽然原理只是运用了一个栈溢出,可是实践起来却涉及了许许多多的技术,以前做过一些ctf中pwn的题目对栈溢出漏洞原理比较熟悉,可能有些地方没有说清楚,如果有不懂的地方欢迎交流。
参考资料:
《漏洞战争 软件漏洞分析精要》
https://blog.csdn.net/qq_31481187/article/details/74093072
https://blog.csdn.net/andy7002/article/details/74276469?utm_source=blogxgwz9