Fuzzing101-Xpdf
Fuzzing101-Xpdf
环境
插桩编译
1 |
|
- 设置
CC
与CXX
环境变量,从而使用afl-clang-fast
进行编译插桩 - 编辑配置文件,指定安装目录
编译过程如下图,途中会显示afl-cc++
Fuzzing
1 |
|
-i
参数指定需要fuzzing
的目标文件-s
参数指定使用的静态随机种子@@
为生成文件样本进行输入,而不是标准输入output
路径是pdftotext
文件执行后所生成的静态文件
在fuzzing
之前需要在命令行输入echo core >/proc/sys/kernel/core_pattern
,为了能够存储程序崩溃的情况
fuzzing
速度非常快,一分钟就出crash
样本了
复现崩溃
会发现打印了十分多的信息,这是因为使用afl++
插桩时会开启内存泄漏探测,因此在复现时应该使用原来的编译器编译
1 |
|
-g
参数增加调试信息-O0
关闭优化方便调试
重新运行一次样本
调试
使用gdb
分析一下崩溃的原因
- 首先使用
gdb
加载pdftotext
- 其次,设置参数
- 最后运行,输入
bt
查看栈回溯,可以看到会不断调用getObj
函数,因此可能是不断递归造成的崩溃
函数调用流程
1 |
|
源码分析
函数递归开头在getObj
函数中处理流数据,会使用makeStream
函数处理数据
通过dictLookup
函数搜索Length
获取流数据的长度
![11](D:\pwn\fuzz\Fuzzing101\Exercise 1\img\11.png)
通过键值搜索对象,若是对象不为空则调用fetch
函数
若对象是引用对象则会调用XRef::fetch
函数,这里就是漏洞存在点,这里并没有判断引用的对象是否是自身。
在XRef::fetch
内部又调用了getObj
函数
通过源码分析发现pdf
对象内部是可以调用间接对象的,但是代码没有判断当前对象与调用的间接对象是否是相同对象,那么则会发送crash
样本发生的情况,会不断递归调用getObj
函数
pdf相关知识
为了分析crash
样本崩溃的原因需要掌握pdf
相关知识
这个网站介绍的非常详细https://lazymind.me/2017/10/pdf-structure/,这里简单记录一下
PDF
文档结构是由许多PDF
对象组成PDF
对象分为直接对象与间接对象直接对象类型
- 布尔类型
- 数值类型
- 字符串
- 名称
- 数组
- 字典
- 流对象
- 空对象
间接对象
1 |
|
crash样本分析
下图是样本的部分数据流,可以发现在7 0 obj
间接对象中又交叉引用了7 0 R
即对象本身与源码分析的情况一致,间接对象本身引用了自身导致了递归调用
崩溃样本构造
一个正常pdf
的例子
正常pdf
的数据流
修改后的pdf
的数据流
构造成功
参考链接
https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%201
https://github.com/zxyle/PDF-Explained/blob/master/chapter2.md
https://lazymind.me/2017/10/pdf-structure/
https://juejin.cn/post/7023691050757652494#heading-18
https://blog.csdn.net/fxbjye/article/details/115460327
https://lazymind.me/2017/10/pdf-structure/