Fuzzing101:Exercise 1 - Xpdf 翻译+解题

Fuzzing101:Exercise 1 - Xpdf 翻译+解题

题目部分翻译

题目链接:https://github.com/antonio-morales/Fuzzing101/tree/main/Exercise%201

对于这个练习,我们将模糊测试Xpdf PDF查看器。目标是在Xpdf 3.0.2中找到CVE-2019-13288的crash/PoC。

有关 CVE-2019-13288漏洞的更多信息:

CVE-2019-13288是一个漏洞,可能通过一个精心制作的文件导致无限递归。

由于程序中每个被调用的函数都在堆栈上分配一个堆栈帧,如果一个函数被递归调用太多次,就会导致堆栈内存耗尽和程序崩溃。

因此,远程攻击者可以利用这一点进行 DoS 攻击。

你可在以下链接找到更多有关「不受控制递归」漏洞的资料: https://cwe.mitre.org/data/definitions/674.html

你会学到什么

在完成这个练习之后,你将会知道使用AFL进行fuzzing的基础,例如:

  • 使用插装编译目标应用程序
  • 运行模糊测试器(afl-fuzz)
  • 使用调试器(GDB)处理崩溃

开始前阅读

  • AFL 使用一种非确定性测试算法,因此两个模糊会话永远不会相同。这就是为什么我强烈建议设置一个固定的种子(- s 123)。这样,你的模糊结果将类似于这里显示的,这将使你更容易按照练习。

  • 如果发现新的漏洞,请向项目提交安全报告。如果您需要帮助或对流程有任何疑问,GitHub 安全实验室可以帮助您。

环境

        所有的练习都在Ubuntu 20.04.2 LTS上进行了测试。强烈建议您使用相同的操作系统版本,以避免不同的模糊结果。

下载并构建目标

让我们首先得到我们的fuzzing目标。为您想要fuzzing的项目创建一个新的目录

cd $HOME
mkdir fuzzing_xpdf && cd fuzzing_xpdf/

要使您的环境完全准备就绪,您可能需要安装一些其他工具(即make和gcc)

sudo apt install build-essential

下载Xpdf 3.02:

wget https://dl.xpdfreader.com/old/xpdf-3.02.tar.gz
tar -xvzf xpdf-3.02.tar.gz

 构建Xpdf:

cd xpdf-3.02
sudo apt update && sudo apt install -y build-essential gcc
./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install

是时候构建测试了。首先, 您需要下载一些PDF示例:

cd $HOME/fuzzing_xpdf
mkdir pdf_examples && cd pdf_examples
wget https://github.com/mozilla/pdf.js-sample-files/raw/master/helloworld.pdf
wget http://www.africau.edu/images/default/sample.pdf
wget https://www.melbpc.org.au/wp-content/uploads/2017/10/small-example-pdf-file.pdf

现在,我们可以使用以下命令测试pdfinfo二进制文件:

$HOME/fuzzing_xpdf/install/bin/pdfinfo -box -meta $HOME/fuzzing_xpdf/pdf_examples/helloworld.pdf

您应该看到以下的结果:

Fuzzing101:Exercise 1 - Xpdf 翻译+解题_第1张图片

安装AFL++

本课程中,我们将使用AFL++的最新版本(目前为4.09c)

本地安装(推荐选项):

安装依赖项:

sudo apt-get update
sudo apt-get install -y build-essential python3-dev automake git flex bison libglib2.0-dev libpixman-1-dev python3-setuptools
sudo apt-get install -y lld-11 llvm-11 llvm-11-dev clang-11 || sudo apt-get install -y lld llvm llvm-dev clang 
sudo apt-get install -y gcc-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-plugin-dev libstdc++-$(gcc --version|head -n1|sed 's/.* //'|sed 's/\..*//')-dev

检查并构建AFL++

cd $HOME
git clone https://github.com/AFLplusplus/AFLplusplus && cd AFLplusplus
export LLVM_CONFIG="llvm-config-11"
make distrib
sudo make install

现在,如果一切顺利,您应该能够运行afl-fuzz。只需输入 afl-fuzz

你应该可以看到以下的结果:

Fuzzing101:Exercise 1 - Xpdf 翻译+解题_第2张图片

认识AFL++

AFL 是一种覆盖率引导的模糊器,这意味着它会收集每个变异输入的覆盖率信息,以发现新的执行路径和潜在的错误。当源代码可用时,AFL 可以使用检测,在每个基本块(函数、循环等)的开头插入函数调用

为了为我们的目标应用程序启用检测,我们需要使用 AFL 的编译器来编译代码。

首先,我们将清理所有先前编译的目标文件和可执行文件:

rm -r $HOME/fuzzing_xpdf/install
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean

现在我们将使用afl-clang-fast编译器构建 xpdf:

export LLVM_CONFIG="llvm-config-11"
CC=$HOME/AFLplusplus/afl-clang-fast CXX=$HOME/AFLplusplus/afl-clang-fast++ ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install

现在,您可以使用以下命令运行模糊器:

afl-fuzz -i $HOME/fuzzing_xpdf/pdf_examples/ -o $HOME/fuzzing_xpdf/out/ -s 123 -- $HOME/fuzzing_xpdf/install/bin/pdftotext @@ $HOME/fuzzing_xpdf/output

每个选项的简要说明:

  • -i表示我们必须放置输入案例的目录(也称为文件示例)
  • -o表示 AFL++ 将存储变异文件的目录
  • -s表示要使用的静态随机种子
  • @@是占位符目标的命令行,AFL 将用每个输入文件名替换它

Fuzzing101:Exercise 1 - Xpdf 翻译+解题_第3张图片

您可以看到红色的“uniq.crashes”值,显示发现的唯一崩溃的数量。您可以在该目录中找到这些崩溃文件$HOME/fuzzing_xpdf/out/。一旦发现第一次崩溃,您就可以停止模糊器,这就是我们将要解决的问题。根据您的计算机性能,可能需要长达一两个小时的时间才会发生崩溃。

在这个阶段,你已经学会了:

  • 如何使用 afl 编译器和检测来编译目标
  • 如何启动 afl++
  • 如何检测目标的独特崩溃

下一个是什么?我们没有关于这个错误的任何信息,只是程序崩溃了......是时候进行调试和分类了!

重现崩溃情况:

在目录中找到崩溃对应的文件$HOME/fuzzing_xpdf/out/。文件名类似于id:000000,sig:11,src:001504+000002,time:924544,op:splice,rep:16

Fuzzing101:Exercise 1 - Xpdf 翻译+解题_第4张图片

将此文件作为 pdftotext 二进制文件的输入传递:

$HOME/fuzzing_xpdf/install/bin/pdftotext '$HOME/fuzzing_xpdf/out/default/crashes/' $HOME/fuzzing_xpdf/output

它将导致分段错误并导致程序崩溃。

Fuzzing101:Exercise 1 - Xpdf 翻译+解题_第5张图片

 Debug the crash to find the problem

使用 gdb 找出程序因该输入而崩溃的原因。

  • 您可以查看GDB Primer,了解 GDB 的简要入门知识

首先,您需要使用调试信息重建 Xpdf 以获取符号堆栈跟踪:

rm -r $HOME/fuzzing_xpdf/install
cd $HOME/fuzzing_xpdf/xpdf-3.02/
make clean
CFLAGS="-g -O0" CXXFLAGS="-g -O0" ./configure --prefix="$HOME/fuzzing_xpdf/install/"
make
make install

现在,您可以运行 GDB:

gdb --args $HOME/fuzzing_xpdf/install/bin/pdftotext $HOME/fuzzing_xpdf/out/default/crashes/ $HOME/fuzzing_xpdf/output

然后,在 GDB 中输入:

>> run

 如果一切顺利,您应该看到以下输出:

然后输入bt以获取回溯:

Fuzzing101:Exercise 1 - Xpdf 翻译+解题_第6张图片

滚动调用堆栈,您将看到许多“Parser::getObj”方法的调用,这似乎表明无限递归。如果您访问CVE-2019-13288 : In Xpdf 4.01.01, the Parser::getObj() function in Parser.cc may cause infinite recursion via a crafted file. A remote at,您可以看到描述与我们从 GDB 获得的回溯相匹配。

你可能感兴趣的:(Fuzzing101,安全)