Fuzzing101-exe3

介绍

本文是 Fuzzing101 训练的第三篇,fuzz 对象是 4.9.2 版本的 TCPdump 数据包分析器。目标是找到 CVE-2017-13028 漏洞崩溃。

CVE-2017-13028 是一个越界读取漏洞,可以通过 BOOTP 数据包(引导协议)触发。越界读取是当程序读取超出预期缓冲区末尾或开头之前的数据时发生的漏洞。

将会学到的知识

  • 什么是 ASan
  • 如何使用 ASan
  • ASan 对崩溃分类的展示

环境与搭建

下载并构建目标

为项目创建一个文件夹

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

下载并解压 tcpdump-4.9.2.tar.gz

1
2
wget https://github.com/the-tcpdump-group/tcpdump/archive/refs/tags/tcpdump-4.9.2.tar.gz
tar -xzvf tcpdump-4.9.2.tar.gz

我们还需要下载 TCPdump 需要的跨平台库 libpcap。下载并解压 libpcap-1.8.0.tar.gz:

1
2
wget https://github.com/the-tcpdump-group/libpcap/archive/refs/tags/libpcap-1.8.0.tar.gz
tar -xzvf libpcap-1.8.0.tar.gz

我们需要重命名libpcap-libpcap-1.8.0libpcap-1.8.0. 否则,tcpdump 找不到libpcap.a本地路径:

1
mv libpcap-libpcap-1.8.0/ libpcap-1.8.0

构建并安装 libpcap:

1
2
3
cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/
./configure --enable-shared=no
make

构建和安装 tcpdump:

1
2
3
4
cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/
./configure --prefix="$HOME/fuzzing_tcpdump/install/"
make
make install

键入以下指令查看是否配置成功:

1
$HOME/fuzzing_tcpdump/install/sbin/tcpdump -h

image-20220417215248476

种子语料库创建

种子语料库:为提供模糊的初始覆盖而准备的一个小型初始语料库。种子语料库不是由fuzzers自己创建的,通常是从现有的测试输入准备的,或者可以手工制作以提供有趣的覆盖范围。它们经常与模糊目标一起检入源代码。

我们可以在 $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/tests 中找到很多 .pcacp 示例,可以用以下命令行运行这些 .pcacp 文件:

1
$HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r [.pcap file]

例如:

1
$HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r ./tests/geneve.pcap

image-20220418102119412

ASan

AddressSanitizer (ASan)**是用于 C 和 C++ 的快速内存错误检测器。它由一个编译器检测模块和一个运行时库组成。该工具能够发现对堆、堆栈和全局对象的越界访问,以及释放后使用、双重释放和内存泄漏**错误。如今被移值到 >=4.8 版本的 GCC 中。

在启用 ASan 的情况下构建

现在我们将构建启用 ASAN 的 tcpdump(和 libpcap)。

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

1
2
3
4
5
6
rm -r $HOME/fuzzing_tcpdump/install
cd $HOME/fuzzing_tcpdump/libpcap-1.8.0/
make clean

cd $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/
make clean

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

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

模糊测试

运行模糊器

1
afl-fuzz -m none -i $HOME/fuzzing_tcpdump/tcpdump-tcpdump-4.9.2/tests/ -o $HOME/fuzzing_tcpdump/out/ -s 123 -- $HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r @@

参数解释:

  • -i:输入目录
  • -m:内存限制
  • -o:输出目录
  • -s:设置固定种子
  • @@:指代文件
  • -:间隔符

这里使用了-m参数,是因为在使用ASAN模式下对内存的消耗非常大,这里指定-m none就是指定禁用内存限制。

结果:

image-20220418173532342

利用 ASan 诊断

调试使用 ASan 构建的程序比前面的练习要容易得多。我们只需要想程序提供崩溃文件就行:

1
$HOME/fuzzing_tcpdump/install/sbin/tcpdump -vvvvXX -ee -nn -r '/home/gyx/fuzzing_tcpdump/out/default/crashes/id:000000,sig:06,src:001143,time:2462367,execs:1002839,op:havoc,rep:2'

image-20220418174231894

可以看到它已经给出了漏洞点,也给出了执行跟踪

1
==850830==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6080000000fb at pc 0x0000004f5bc5 bp 0x7ffeee5d97c0 sp 0x7ffeee5d97b8

是一个堆的缓冲区溢出。