fuzz闭源pdf查看器
字数 1156 2025-08-03 16:49:17
闭源PDF查看器模糊测试技术详解
1. 背景与挑战
PDF查看器作为广泛使用的软件,历史上存在大量安全漏洞。对闭源PDF查看器进行模糊测试面临两个主要挑战:
- 非终止程序问题:PDF查看器不会自行终止,导致模糊器无法确定何时开始下一次测试迭代
- 输入最小化问题:需要高效测量代码覆盖率以创建高质量的初始输入集
2. 非终止程序解决方案
2.1 核心思路
通过程序跟踪技术找到查看器的"最后一个基本块",然后对其进行补丁使程序能够终止。
2.2 实施步骤
-
程序跟踪与检测
- 使用DynamoRIO框架进行动态二进制检测
- 命令示例:
drrun.exe -t drcov -dump_text Program.exe - 生成包含执行基本块顺序的跟踪信息
-
识别最后一个基本块
- 提供多个有效PDF生成多个跟踪
- 分析跟踪末端寻找共同的基本块
-
补丁技术
- 直接覆盖:使用9字节指令序列(Xor eax, eax; push eax; push ExitProcess地址; ret)
- 添加新节区:当基本块空间不足时,在PE文件中添加新可执行节区
- 使用LIEF框架修改PE文件
-
补丁效果
- 成功应用于FoxitReader、PDFXChangeViewer、XNView等查看器
- 补丁后程序行为明确,便于模糊器判断测试完成
3. 输入最小化解决方案
3.1 语料库蒸馏
核心算法:
corpus = []
inputs = [I1, I2, .... In]
for input in inputs:
new_blocks = execute(program, input)
if new_blocks:
corpus.append(input)
3.2 自定义调试器方法
-
静态检测
- 使用0xCC断点指令修补每个基本块
- 断点同时应用于磁盘二进制文件和内存中的二进制
-
调试器处理
- 捕获int3断点事件
- 恢复原始字节
- 调整指令指针并继续执行
-
性能优化
- 第一次迭代较慢(FoxitReader约16秒)
- 后续迭代显著加快(约1.5秒)
- 断点数量大幅减少(从48,323降至2,212)
-
实际应用
- 成功测试Adobe Acrobat Reader、PowerPoint、FoxitReader等
- 从80,000个PDF中筛选出220个独特样本(耗时约1.5天)
4. 模糊测试结果
- 测试周期:约2个月
- 发现独特崩溃:43个
- 报告给Zero Day Initiative的漏洞:
- ZDI-CAN-7423:Foxit Reader解析越界读导致RCE
- ZDI-CAN-7353:Foxit Reader解析越界读导致信息泄露
- ZDI-CAN-7073:Foxit Reader解析越界读导致信息泄露
5. 工具与框架
- 动态二进制检测:DynamoRIO
- PE文件修改:LIEF框架
- 调试器开发:自定义调试器处理断点事件
6. 关键要点
- 程序终止补丁显著提高了模糊测试效率
- 静态断点+调试器方法解决了动态检测的性能问题
- 高质量的初始语料库对模糊测试效果至关重要
- 该方法可推广到其他类型闭源软件的测试中