fuzz初战-fuzz Xpdf3.02详解
sn0w 历史精选 331浏览 · 2025-03-10 08:37

安装AFL++

安装依赖项

检验和构建AFL++

输入AFL_fuzz进行验证

image.png


AFL 是一个覆盖引导的fuzzer,这意味着它为每个变异的输入收集覆盖信息,可以进行插桩,当源代码可用时,AFL 可以使用检测,在每个基本块(函数、循环等)的开头插入函数调用。

fuzz使用说明

Xpdf编译

正常编译之后就可以使用

Xpdf使用

这里可以看到我们编译成功了 但是这个是没有进行插桩直接编译的 因此我们要删掉 重新用构建XPDF

afl-clang-fast 编译器构建 xpdf

fuzz过程

遇到了一个报错用这个指令就好

image.png


它表明系统的核心转储(core dump)通知已配置为发送到一个外部实用工具

我们关闭核心转储就好

image.png


大概跑个几分钟就会出现一个crash 我们的fuzz就成功了

image.png


这里是三个crashes 我们可以测试一下 这个是不是会出现崩溃



接下来我们就进一步调试跟进分析这个Xpdf的CVE漏洞

先看一下CVE官方描述

接下来删掉之前插桩的Xpdf 重新编译正常并且可以调试的xpdf

image.png


直接c发现程序卡在了这个位置 此时已经崩溃出现错误 然后看一下函数调用栈发现

image.png


如果CVE描述的一样在无限制的递归

我们通过一步步调试去查看原因

先静态分析看流程

这里因为我们这个xpdf 是没有设置密码的 所以ownerpassword和userpassword 都是0 然后进入PDFDoc

这里基本就是会通过一次修改为小写大写来判断文件是否存在 如果存在的化就进入setup这部分

这部分检测你的header 和 xref 表 还有catalog

简单介绍一下

Catalog是 PDF 文件结构中的一个重要对象,它是 PDF 文档的根目录对象,通常位于 PDF 文件的最顶层,负责指向文档的其他重要部分。PDF 文件的结构是层次化的, 就是其中的“根”对象

交叉引用表(xref table)是 PDF 文件中的一个重要结构,它用于描述文件中的对象如何相互引用。

这部分也基本是一些检测 我们继续走

image.png


  也就是对于 pdf 中的每一页,调用 displayPage 将其转文字输出。跟进 displayPage

catalog->getPage(page)来获取页码 我们这里只有一页所以是1 然后执行 Page:display

  是直接调用 displaySlice 输出。跟进:

在调试过程中 是在这一段导致的 contents.fetch(xref, &obj); 无限递归

image.png


content是object, Ref 二元组为 (num=7, gen=0)

我们这里可以分析一下函数调用连 有一个思路是 在确定已经会循坏的位置断点 连续c几次 这样可以保证有循坏节追踪的同时 程序不会崩溃

可以看出是

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

我们照着这个思路去跟进 可以加快我们的调试速度

Object::fetch

这里的type就是objRef 还记得我们ptype看的contents吗 是object类型的 因此我们用*Object::fetch(XRef *xref, Object *obj)调用的时候 其实是用的contents的变量

XRef::fetch

Parser::getObj

Parser::makeStream

dict->dictLookup("Length", &obj);这里是通过查找Length然后赋值给obj

image.png


image.png


dictLookup的参数也就是dict的变量

Dict :: lookup

这里也是关键点 可以看到e->val也是object类型 并且此时的二元组为num=7 gen=0

image.png


继续跟进发现:

image.png


实际调用的是 xref->fetch(7, 0, &newobj),和我们一开始调用的一样 至此形成闭环

递归链条:

image.png


修复



可以看到官方修复是把循坏加了一个限制 循坏到一定次数就会跳转

image.png






0 条评论
某人
表情
可输入 255