Fuzzing -- Angora 安装、测试binutils-2.28

0x00 前言

目前模糊测试面临的一大难题就是覆盖率低,目前已经有的解决方案是用符号执行去解约束,但是符号执行解约束效率非常低,并且存在路径爆炸的问题。Angora提出了一种不用符号执行就可以解约束的方法。在paper中,其性能与AFL相比有较大的优势。几个月前就想说把这个工具跑下试试,拖到现在。。。。

0x01 Angora 环境配置、配置

1.1 下载源码、安装rust

首先该工具已经在github上开源,直接下载源码。

1
$ git clone git@github.com:AngoraFuzzer/Angora.git

Angora需要在Linux-amd64环境下。同时需要rust、llvm4.0.0-7.1.0的支持。
安装rust:

1
$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

1.2 安装LLVM

1.2.1 通过Angora中的自动化脚本安装

Angora的源码的build目录下,有安装LLVM-7.0.0的脚本install_llvm.sh

1
2
#/home/parallels/Desktop/Angora
$ PREFIX=/home/parallels/llvm ./build/install_llvm.sh

/home/parallels/llvm路径是LLVM的安装路径,自己设定。一定要在Angora目录下运行build目录的脚本,不然后面的脚本中的路径会不对,导致报错
其实最简单的方法是直接在编译Angora的时候运行./build/build.sh,该脚本会自动的下载安装LLVM。这张方法比较方便,只是要等一会,下载clang+llvm的时候会很慢。

由于要学编写LLVMpass,所以需要搭建LLVM的整个源码环境,尝试了把脚本中的自动下载clang+llvm的代码注释掉,手动安装LLVM

1.2.2 手动源码编译LLVM-7.1.0

具体的编译步骤在之前的一篇里面写了就不写了。

1.2.2.1 配置环境变量

我的LLVM-7.1.0安装目录在/llvm,设置环境变量。
将下面两行代码添加到.bashrc获取.zshrc。

1
2
export PATH=/llvm/bin:$PATH
export LD_LIBRARY_PATH=/llvm/lib:$LD_LIBRARY_PATH

然后在命令行输入下面的命令,使得上面的修改生效。

1
$ source ~/.bashrc

然后将Angora/build目录下的build.sh脚本中的下面几行注释掉。15784033001181

1.3 编译Angora

直接在Angora目录下运行下面的命令。

1
$ ./build/build.sh

如果报错cmake not found,直接sudo apt install cmake就好了。还遇到一个问题是我之前编译内核的时候把gcc版本换成了gcc4,会导致报错,将gcc换回gcc5就可以。
上述运行没有报错,说明Angora编译安装成功。

1.3.1 系统配置

和AFL一样,系统的core dump需要被disable。

1
$ echo core | sudo tee /proc/sys/kernel/core_pattern

1.3.2 运行测试样例

1
2
3
#Angora目录
$ cd tests
$ ./test.sh mini

15784037879010
15784038540461

0x02 Angora测试binutils-2.28

2.1 编译binutils-2.28

binutils-2.28文件目录下有configure文件,采用Angora官方文档中的autoconf方法来编译目标程序。Angora需要有taint tracking支持的目标程序和light instrumentation支持的目标程序。所以需要分别两次编译生成.taint目标程序和.fast目标程序。

设置参数,然后在命令行输入如下命令,生成Makefile。一定不要忘了后面的–disable-shared,不然会编译报错。

1
2
3
4
$ CC=/home/parallels/Desktop/Angora/bin/angora-clang \
CXX=/home/parallels/Desktop/Angora/bin/angora-clang++ \
LD=/home/parallels/Desktop/Angora/bin/angora-clang \
./configure --disable-shared

编译Fast Mode的目标程序
然后直接编译,默认情况下是Fast Mode.

1
$ make # Fast Mode

在binutils-2.28目录外新建一个angora-binutils目录,然后在该目录下,新建taint目录和fast目录。我是拿binutils-2.28中的readelf程序来试验的,将编译好的readelf可执行文件移到angora-binutils/fast目录下,并命名为readelf.fast。

1
2
3
4
5
$ cd ..
$ mkdir angora-binutils
$ cd angora-binutils
$ mkdir fast taint
$ cp ../binutils-2.28/binutils/readelf fast/readelf.fast

编译Taint Mode支持的目标程序
编译有taint tracking支持的程序。首先先清除之前的编译结果,最简单粗暴的做法是将当前文件夹删除,然后重新解压,因为只是make clean不能清理干净,还要删除一些缓存文件,两种方法都可以,还是喜欢简单粗暴的做法。设置USE_TRACK=1标识。(编译taint模式会比较慢)

1
2
3
4
5
6
7
8
9
10
11
12
#方法一
$ make clean
$ rm config.status
$ CC=/home/parallels/Desktop/Angora/bin/angora-clang CXX=/home/parallels/Desktop/Angora/bin/angora-clang++ LD=/home/parallels/Desktop/Angora/bin/angora-clang ./configure --disable-shared
$ USE_TRACK=1 make
# 方法二
$ tar zxvf
$ cd bi
$ CC=/home/parallels/Desktop/Angora/bin/angora-clang CXX=/home/parallels/Desktop/Angora/bin/angora-clang++ LD=/home/parallels/Desktop/Angora/bin/angora-clang ./configure --disable-shared
$ USE_TRACK=1 make
------------------------------------------------------------------------------------------------------------------------------------
$ cp binutils/readelf ../angora-binutils/taint/readelf.taint

2.2 Fuzzing readelf

新建input文件夹,用于存放输入种子文件。种子文件不能太大,否则会被丢弃。

1
$ ./../../../Angora/angora_fuzzer -i input/ -o output/ -t taint/readelf.taint -- fast/readelf.fast -a
  1. -i后面跟的是种子目录,存放的是种子文件。
  2. -o后面跟的fuzzing结果存放的目录,output文件在fuzzing时会自动创建,如果已经存在会报错。
  3. -t后面跟的是支持taint tracking的目标程序,也就是.taint后缀文件的存放路径。
  4. –后面跟的是支持light instrumentation的目标程序,也就是.fast后缀文件的存放路径。

最终运行截图:15784587721545