fuzz初战-fuzz Xpdf3.02详解
字数 1343 2025-08-29 08:30:18

Fuzz初战:Fuzz Xpdf 3.02详解

1. AFL++安装与配置

1.1 安装依赖项

首先需要安装AFL++的依赖项,确保系统具备编译和运行AFL++的基本环境。

1.2 检验和构建AFL++

  1. 下载AFL++源代码
  2. 执行构建命令:make
  3. 安装:sudo make install

1.3 验证安装

输入AFL_fuzz命令进行验证,确认安装成功。

AFL++特点

  • 覆盖引导的fuzzer
  • 为每个变异的输入收集覆盖信息
  • 支持插桩技术
  • 当源代码可用时,AFL可以使用检测,在每个基本块(函数、循环等)的开头插入函数调用

2. Xpdf编译与插桩

2.1 正常编译Xpdf

首先进行正常编译,验证Xpdf可以正常构建。

2.2 插桩编译

  1. 删除之前编译的Xpdf
  2. 使用AFL++提供的编译器进行插桩编译:
    CC=afl-clang-fast CXX=afl-clang-fast++ ./configure
    make
    

3. Fuzz过程

3.1 常见问题解决

在fuzz过程中可能会遇到核心转储(core dump)通知问题,解决方法:

echo core | sudo tee /proc/sys/kernel/core_pattern

3.2 运行Fuzzer

使用以下命令启动fuzzing:

afl-fuzz -i input_dir -o output_dir ./xpdf @@

3.3 结果分析

  • 通常几分钟后就会出现crash
  • 检查output_dir/crashes目录中的崩溃样本
  • 可以测试这些样本是否确实会导致Xpdf崩溃

4. 漏洞分析与调试

4.1 准备调试环境

  1. 删除之前插桩的Xpdf
  2. 重新编译正常且可调试的Xpdf版本(使用-g选项)

4.2 崩溃分析

  1. 使用gdb加载崩溃样本:
    gdb --args ./xpdf crash_sample
    
  2. 运行程序直到崩溃
  3. 查看函数调用栈(backtrace)

4.3 漏洞原理

通过分析发现存在无限递归问题,调用链如下:

Object::fetch --> XRef::fetch --> Parser::getObj --> Parser::makeStream --> Object::dictLookup --> Dict::lookup --> Object::fetch

关键点

  • 涉及PDF文档结构中的Catalog和交叉引用表(xref table)
  • Catalog是PDF文档的根目录对象,负责指向文档的其他重要部分
  • 交叉引用表(xref table)描述文件中的对象如何相互引用

4.4 调试技巧

  1. 在确定会循环的位置设置断点
  2. 连续执行几次(continue命令)
  3. 这样可以保证有循环节追踪的同时,程序不会立即崩溃

5. PDF文档结构相关知识

5.1 Catalog对象

  • PDF文档结构中的重要对象
  • PDF文档的根目录对象
  • 位于PDF文件的最顶层
  • 负责指向文档的其他重要部分

5.2 交叉引用表(xref table)

  • 描述文件中的对象如何相互引用
  • 包含所有对象的偏移量信息
  • 是PDF文件解析的关键数据结构

5.3 页面处理流程

对于PDF中的每一页:

  1. 调用catalog->getPage(page)获取页码
  2. 执行Page::display,实际上是调用displaySlice输出

6. 漏洞修复方案

官方修复方法是在循环中添加限制,当循环达到一定次数时自动跳出,防止无限递归。

修复关键点:

  • 添加循环计数器
  • 设置最大递归深度
  • 超过限制时返回错误或终止处理

7. 总结

通过本次fuzz实践,我们:

  1. 成功搭建了AFL++ fuzzing环境
  2. 对Xpdf进行了插桩编译
  3. 发现了导致崩溃的漏洞
  4. 通过调试分析了漏洞成因(无限递归)
  5. 了解了PDF文档的基本结构
  6. 学习了官方修复方案

这个案例展示了如何从fuzz发现崩溃到最终分析出漏洞原理的完整过程,对于学习软件安全测试和漏洞分析具有很好的参考价值。

Fuzz初战:Fuzz Xpdf 3.02详解 1. AFL++安装与配置 1.1 安装依赖项 首先需要安装AFL++的依赖项,确保系统具备编译和运行AFL++的基本环境。 1.2 检验和构建AFL++ 下载AFL++源代码 执行构建命令: make 安装: sudo make install 1.3 验证安装 输入 AFL_fuzz 命令进行验证,确认安装成功。 AFL++特点 : 覆盖引导的fuzzer 为每个变异的输入收集覆盖信息 支持插桩技术 当源代码可用时,AFL可以使用检测,在每个基本块(函数、循环等)的开头插入函数调用 2. Xpdf编译与插桩 2.1 正常编译Xpdf 首先进行正常编译,验证Xpdf可以正常构建。 2.2 插桩编译 删除之前编译的Xpdf 使用AFL++提供的编译器进行插桩编译: 3. Fuzz过程 3.1 常见问题解决 在fuzz过程中可能会遇到核心转储(core dump)通知问题,解决方法: 3.2 运行Fuzzer 使用以下命令启动fuzzing: 3.3 结果分析 通常几分钟后就会出现crash 检查output_ dir/crashes目录中的崩溃样本 可以测试这些样本是否确实会导致Xpdf崩溃 4. 漏洞分析与调试 4.1 准备调试环境 删除之前插桩的Xpdf 重新编译正常且可调试的Xpdf版本(使用-g选项) 4.2 崩溃分析 使用gdb加载崩溃样本: 运行程序直到崩溃 查看函数调用栈(backtrace) 4.3 漏洞原理 通过分析发现存在无限递归问题,调用链如下: 关键点 : 涉及PDF文档结构中的Catalog和交叉引用表(xref table) Catalog是PDF文档的根目录对象,负责指向文档的其他重要部分 交叉引用表(xref table)描述文件中的对象如何相互引用 4.4 调试技巧 在确定会循环的位置设置断点 连续执行几次(continue命令) 这样可以保证有循环节追踪的同时,程序不会立即崩溃 5. PDF文档结构相关知识 5.1 Catalog对象 PDF文档结构中的重要对象 PDF文档的根目录对象 位于PDF文件的最顶层 负责指向文档的其他重要部分 5.2 交叉引用表(xref table) 描述文件中的对象如何相互引用 包含所有对象的偏移量信息 是PDF文件解析的关键数据结构 5.3 页面处理流程 对于PDF中的每一页: 调用 catalog->getPage(page) 获取页码 执行 Page::display ,实际上是调用 displaySlice 输出 6. 漏洞修复方案 官方修复方法是在循环中添加限制,当循环达到一定次数时自动跳出,防止无限递归。 修复关键点: 添加循环计数器 设置最大递归深度 超过限制时返回错误或终止处理 7. 总结 通过本次fuzz实践,我们: 成功搭建了AFL++ fuzzing环境 对Xpdf进行了插桩编译 发现了导致崩溃的漏洞 通过调试分析了漏洞成因(无限递归) 了解了PDF文档的基本结构 学习了官方修复方案 这个案例展示了如何从fuzz发现崩溃到最终分析出漏洞原理的完整过程,对于学习软件安全测试和漏洞分析具有很好的参考价值。