Fuzzing101-exe4

介绍

本文是 Fuzzing101 训练的第四篇,fuzz 对象是 libtiff 4.0.4,目标是找到 CVE-2016-9297 的漏洞崩溃,并测量崩溃的代码覆盖率。

CVE-2016-9297:越界读取漏洞,可以通过精心设计的 TIFF_SETGET_C16ASCII 或 TIFF_SETGET_C32_ASCII 标记值触发。越界读取是当程序读取超出预期缓冲区末尾或开头之前的数据时发生的漏洞。将造成的结果是它允许远程攻击者导致拒绝服务或可能从进程内存中获取潜在的敏感信息。

将会学到的知识

  • 如何使用 LCOV 测量代码覆盖率
  • 如何使用代码覆盖率数据来提高 fuzzing 的有效性

环境与搭建

下载并构建目标

为新项目创建一个文件夹:

1
2
cd $HOME
mkdir fuzzing_tiff && cd fuzzing_tiff/

下载并解压 libtiff 4.0.4:

1
2
wget https://download.osgeo.org/libtiff/tiff-4.0.4.tar.gz
tar -xzvf tiff-4.0.4.tar.gz

构建和安装 libtiff:

1
2
3
4
cd tiff-4.0.4/
./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared
make
make install

作为目标二进制文件,我们可以对位于 /bin 文件夹中的 tiffinfo 二进制文件进行模糊测试。 作为种子输入语料库,我们将使用 /test/images/ 文件夹中的示例图像。

要测试一切是否正常,只需键入:

1
$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

将会看到

image-20220419102952750

-j -c -r -s -w 是为了提高代码覆盖率并增加发现错误的机会。

代码覆盖率

代码覆盖率是一种软件指标,显示每行代码被触发的次数。通过使用代码覆盖率,我们将了解模糊器已到达代码的哪些部分并可视化模糊测试过程。

先安装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/index.html 文件,将会看到如下内容:

image-20220419150017463

模糊测试

现在我们将在启用 ASAN 的情况下编译 libtiff。

清理所有之前编译的目标文件和可执行文件:

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

调用 make 之前设置 AFL_USE_ASAN=1:

1
2
3
4
export LLVM_CONFIG="llvm-config-11"
CC=afl-clang-lto ./configure --prefix="$HOME/fuzzing_tiff/install/" --disable-shared
AFL_USE_ASAN=1 make -j4
AFL_USE_ASAN=1 make install

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

1
afl-fuzz -m none -i $HOME/fuzzing_tiff/tiff-4.0.4/test/images/ -o $HOME/fuzzing_tiff/out/ -s 123 -- $HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w @@

image-20220419153414672

ASan 诊断

1
$HOME/fuzzing_tiff/install/bin/tiffinfo -D -j -c -r -s -w /home/gyx/fuzzing_tiff/out/default/crashes/id:000000,sig:06,src:000092,time:104764,execs:96551,op:havoc,rep:8

image-20220419153905071

测量 PoC 的代码覆盖率

也就是把之前 代码覆盖率 部分再执行一遍,并将目标文件改成 crash 的文件就行,即

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/gyx/fuzzing_tiff/out/default/crashes/id:000000,sig:06,src:000092,time:104764,execs:96551,op:havoc,rep:8
lcov --no-checksum --directory ./ --capture --output-file app2.info
1
genhtml --highlight --legend -output-directory ./html-coverage/ ./app2.info

image-20220419155938393