AFLPIN相关介绍
一、AFLPIN介绍
1、AFLPIN
AFLPIN使AFL模糊器(http://lcamtuf.coredump.cx/afl/)可以使用Intel的PIN对未插桩的二进制文件进行模糊处理。
通过插入相同类型的分支检测和共享内存映射来实现AFL的二进制插桩。
不幸的是,这样做会很大程度的损害AFL的性能,因此期望执行时间慢。
2、构建
首先从https://software.intel.com/en-us/articles/pin-a-dynamic-binary-instrumentation-tool下载当前版本。
然后建立AFLPIN工具的.so文件以供pin使用:
$ PIN_ROOT=/path/to/pin/root/ make obj-intel64/aflpin.so
$ PIN_ROOT=/path/to/pin/root/ make TARGET=ia32 obj-ia32/aflpin.so
然后一个命令 (将以root身份运行), 以使pin能够从用户态运行: echo 0 > /proc/sys/kernel/yama/ptrace_scope
3、使用
为了使AFLPIN与afl-fuzz结合使用,我们必须注释掉单个完整性检查,因为从AFL调用了pin的方式:
在afl-fuzz.c:5578(afl-1.15b)中,进行了健全性检查:
if (!dumb_mode && !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) {
...
}
注释掉该行并重建afl-fuzz。
然后使用目标和afl-fuzz调用pin工具:
$ AFL_NO_FORKSRV=1 afl-fuzz -m 500 -i .. -o .. -f .. -- /path/to/pin_app -t /path/to/obj-intel64|obj-ia32/aflpin.so -- TARGETAPP @@
4、Notes
- -m 500是因为pin将需要大量的内存,因此您很可能需要针对给定的目标对其进行调整
- 如果目标是32位对64位,则将obj-intel64 /换为obj-ia32 /。
5、测试程序
-
crash_test.c是一个简单的过程,它读取具有简单 memcpy() 漏洞的文件(按和自变量)。我用它来验证信号是否已正确地从目标通过引脚传输到afl-fuzz。
-
sleep_test.c用于验证AFLPIN中的分支检查,您可以不使用afl即可调用pin工具,而无需修改参数。还有一个-debug标志,您可以将其传递给pin二进制文件,该文件将在AFLPIN内部打印更多信息。
-
如果AFL报告测试用例导致崩溃,请检查当前工作目录中的pin.log文件来了解特定错误。
二、dockerized_fuzzing/aflpin
1、AFLPIN
https://hub.docker.com/r/zjuchenyuan/aflpin
Source: https://github.com/mothran/aflpin
Version: 3668e1e
More Versions: PIN 2.13, AFL 1.15b, gcc 4.8
Last Update: 2015/01
Type: Binary Instrumentation
Tag: Intel PIN
2、指导
Step1: System configuration
echo "" | sudo tee /proc/sys/kernel/core_pattern
echo 0 | sudo tee /proc/sys/kernel/core_uses_pid
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
echo 1 | sudo tee /proc/sys/kernel/sched_child_runs_first
echo 0 | sudo tee /proc/sys/kernel/randomize_va_space
出现类似“没有这样的文件或目录”的错误消息,您可以忽略它。
注意:
尽管此Fuzzer并不需要所有配置,但为了统一不同Fuzzer的一致性,我们以统一的方式提供了这些命令。
这些命令可能会损害您的系统安全性(关闭ASLR),但这并不是一个大问题,因为模糊测试通常是在专用计算机上进行的。
它代替了许多模糊器给出的echo core > /proc/sys/kernel/core_pattern
,当崩溃发生时仍会生成一个核心转储文件,这里我们禁用核心转储文件的生成以减少模糊期间的I/O压力。参考:http://man7.org/linux/man-pages/man5/core.5.html
Step2: Compile target programs
下载源代码,使用常规gcc进行编译。
wget https://sourceforge.net/projects/mp3gain/files/mp3gain/1.6.2/mp3gain-1_6_2-src.zip/download -O mp3gain-1_6_2-src.zip
mkdir -p mp3gain1.6.2 && cd mp3gain1.6.2
unzip ../mp3gain-1_6_2-src.zip
# build using gcc
docker run --rm -w /work -it -v `pwd`:/work --privileged zjuchenyuan/aflpin \
sh -c "make clean; CC=gcc CXX=g++ make"
Step3: Prepare Seed Files
UNIFUZZ提供各种类型的种子文件。在这里,我们提供了10个mp3种子文件,这些文件将下载到seed_mp3文件夹中。
# apt install -y subversion
svn export https://github.com/UNIFUZZ/dockerized_fuzzing_examples/trunk/seed/mp3 seed_mp3
Step4: Fuzzing!
docker run --privileged -w /work -it -v `pwd`:/work --env AFL_NO_FORKSRV=1 zjuchenyuan/aflpin /bin/bash
# it seems afl-1.15b cannot get correct terminal size, so run this command in container
afl-fuzz -i seed_mp3 -o output/aflpin -m 100 -- \
/pinplay-1.2-pin-2.13-62732-gcc.4.4.7-linux/intel64/bin/pinbin -ifeellucky -t /aflpin/obj-intel64/aflpin.so -- \
./mp3gain @@
当从容器退出后,容器是关闭的,此时若要再次进入容器,需要先启动容器docker start bold_chaplygin
,然后再进入容器并开启一个伪终端docker exec -it bold_chaplygin /bin/bash
。
不推荐使用的警告
根据https://github.com/mothran/aflpin/issues/1,作者认为AFL的QEMU模式要快得多。
自从我从事此工作以来已经有很长时间了,因为AFL的QEMU模式惊人地快。