安装AFL++

首先强烈建议新开一个20.04的虚拟机用来安装。

请查看此篇博客:

AFL++学习日志(一)开始Fuzz与crashes分析 - Mundi’s Space

在安装依赖这一步,请安装clang

获取源码这一步,请将仓库git到$HOME下并编译

make install之后再将文件夹添加到环境变量(以使用afl-clang-fast)

1
export PATH=$PATH:$HOME/AFLplusplus

要进行黑盒测试还需要安装qemu模块。进在目录下的 qemu-mode 文件夹中有构建脚本 build_qemu_support.sh,运行之即可安装。新版本会自动安装

期间可能会出现缺少依赖的情况,缺什么安装什么即可。

如果缺乏ninja参考:QEMU源码编译安装【教程】 - From_Zero - 博客园

如果缺乏 libtool,使用 sudo apt install libtool 后仍然可能提示缺少,这是再执行 sudo apt install libtool-bin 即可。

-Q参数即进行黑盒测试。

测试第一个练习

Fuzzing101/Exercise 1 at main · antonio-morales/Fuzzing101

第二个练习:对libexif-0.6.14进行fuzz

Fuzzing101/Exercise 2 at main · antonio-morales/Fuzzing101

介绍:

官方页面:libexif C EXIF 库

因为这是一个库,所以我们需要有一个工具来调用它。这里我们使用官方项目维护的一个简单命令行工具exif

然后我们需要获取一些exif图像样本作为我们模糊测试的语料库,例如这个仓库:ianare/exif-samples: Sample images for testing Exif metadata retrieval.

然后我们进行插桩编译libexif和exif简单命令行工具,这里我们根据官方文档进行configure和make:

1
2
3
4
5
If your libexif is installed in a non-standard location, you must point
configure at the location of its libexif.pc file using the pkg-config
path, like this:

./configure PKG_CONFIG_PATH=/usr/local/lib/pkgconfig

编译libexif:

1
2
3
4
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/"
make
make install

这里因为我的clang版本是10.0.0,无法使用afl-clang-lto,所以我还是使用afl-clang-fast,并禁止共享库,配置安装位路径。

编译exif命令行工具:

1
2
3
4
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_libexif/install/" PKG_CONFIG_PATH=$HOME/fuzzing_libexif/install/lib/pkgconfig
make
make install

可以看到根据官方文档指定了PKG_CONFIG_PATH的路径。

然后便可以使用afl-fuzz进行fuzz。

第三个练习:tcpdump-4.9.2

Fuzzing101/Exercise 3 at main · antonio-morales/Fuzzing101

我们开始使用ASan工具:

AddressSanitizer(ASan)是一个用于C和C++的快速内存错误检测器,它由一个编译器仪表模块和一个运行时库组成。它最初由谷歌(Konstantin Serebryany, Derek Bruening, Alexander Potapenko, Dmitry Vyukov)开发,并于2011年5月首次发布。

AddressSanitizer是开源的,从3.1版本开始与LLVM编译器工具链集成。虽然它最初是作为LLVM的一个项目开发的,但它已经被移植到了GCC,并被包含在GCC的4.8版本中。

**_您可以在以下链接_**中找到关于AddressSanitizer的更多信息。

1
2
3
4
5
6
7
8
9
cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --enable-shared=no --prefix="$HOME/fuzzing_tcpdump/install/"
AFL_USE_ASAN=1 make

cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/
AFL_USE_ASAN=1 CC=afl-clang-lto ./configure --prefix="$HOME/fuzzing_tcpdump/install/"
AFL_USE_ASAN=1 make
AFL_USE_ASAN=1 make install

现在,我们在调用configure和make之前设置AFL_USE_ASAN=1。

AFL_USE_ASAN=1 ,是指开启ASAN辅助,这个玩意是基于clang的一个内存错误检测器,可以检测到常见的内存漏洞,如栈溢出,堆溢出,double free,uaf等等

由于AFL呢是基于崩溃报错来反馈漏洞的,但很多时候,少量的字节 堆溢出是不会引起崩溃报错的,这样就需要额外开启ASAN来辅助挖掘漏洞

第四个练习:LibTIFF 4.0.4 for CVE-2016-9297

本节学习使用LCOV测量代码覆盖率。

1
sudo apt install lcov

现在我们需要使用--coverage标志(编译器和链接器)重建 libTIFF:

1
2
3
4
5
6
7
rm -r $HOME/fuzzing_tiff/install
cd $HOME/fuzzing_tiff/tiff-4.0.4/
make clean

CFLAGS="--coverage" LDFLAGS="--coverage" ./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared
make
make install

然后我们可以通过键入以下内容来收集代码覆盖率数据:

1
2
3
4
5
cd $HOME/fuzzing_tiff/tiff-4.0.4/
lcov --zerocounters --directory ./
lcov --capture --initial --directory ./ --output-file app.info
$HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w $HOME/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff
lcov --no-checksum --directory ./ --capture --output-file app2.info

每条命令的含义:

  • lcov --zerocounters --directory ./:重置以前的计数器
  • lcov --capture --initial --directory ./ --output-file app.info:返回包含每条检测线的零覆盖率的“基线”覆盖率数据文件
  • $HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w $HOME/fuzzing_tiff/tiff-4.0.4/test/images/palette-1c-1b.tiff:运行您要分析的应用程序。您可以使用不同的输入多次运行它
  • lcov --no-checksum --directory ./ --capture --output-file app2.info:将当前覆盖状态保存到 app2.info 文件中

生成 HTML 输出:

1
genhtml --highlight --legend -output-directory ./html-coverage/ ./app2.info

如果一切顺利,就会在html-coverage文件夹中创建代码覆盖率报告。只需打开./html-coverage/index.html文件,您应该会看到如下内容:

现在可以浏览不同的文件夹和文件,并查看每行执行的次数。

同样地,使用ASAN可以定位到出错的代码位置和当时的栈跟踪等信息。配合lcov可以更好地了解问题

第五个练习:LibXML2 2.9.4

本节学到了并发fuzz:

共享实例

使用共享实例是并行模糊测试的更好方法。在这种情况下,每个 fuzzer 实例都会收集其他 fuzzer 找到的任何测试用例。

您通常一次只有一个主实例:

1
./afl-fuzz -i afl_in -o afl_out -M Master -- ./program @@

和 N-1 个从站:

1
2
3
4
./afl-fuzz -i afl_in -o afl_out -S Slave1 -- ./program @@
./afl-fuzz -i afl_in -o afl_out -S Slave2 -- ./program @@
...
./afl-fuzz -i afl_in -o afl_out -S SlaveN -- ./program @@

不过需要你使用不同的种子以增加成功率。

再结合ASAN,方便调试错误。

参考文章:

AFL学习记录(三)——qemu 模式的测试 - cj的小站

antonio-morales/Fuzzing101: An step by step fuzzing tutorial. A GitHub Security Lab initiative

⬆︎TOP