安装
1.下载最新源代码
2.安装
1 | $ make |
有源码测试
1.可执行文件的输入为一个文件时
用AFL对一个开源的加壳软件UPX进行了测试,记录一下具体过程:
1 | $ git clone https://github.com/upx/upx.git |
编译upx还需要下载两个库否则会出错:
1 | $ git submodule update --init --recursive # 下载lzma-sdk |
下载ucl,并编译安装:
1 | $ cd ucl-1.03 |
具体操作可以看官方文档。
编译upx,并对upx进行测试:
1 | $ make all # 会在src目录下产生upx.out可执行文件 |
用AFL对UPX进行测试发现了好多crash,最后经过对crash进行分析,发现了一个UPX的漏洞。
2.可执行文件的输入为标准输入时
编写源码如下
1 | #include <stdio.h> |
编译测试:
1 | $ afl-gcc -o crash crash.c |
无源码测试
对只有二进制文件的情况进行fuzz,有两种方法:
1.对二进制文件进行插桩
这种方法是通过编译一个AFL版的qemu实现的
1 | $ cd qemu_mode |
编译安装完AFL版的qemu后,在进行模糊测试时,指定-Q
选项即可。
可执行文件的输入为一个文件:
1 | $ type readelf |
2.进行传统的模糊测试,指定-n
选项即可。
原理
AFL采用代码插桩的方法,对遗传算法进行指导,提高代码覆盖率。具体说来,插桩代码把当前地址放到一个全局变量中,类似一个hashmap的地图,设置遗传算法,能够产生不同路径的地图优先度高。
下图是对上文中afl-gcc编译的crash可执行文件的反汇编,可以看到有一些__afl_maybe_log
插桩代码。
AFL的官方说明更加详细,本文只是对一些简单应用进行了说明。
reference
http://lcamtuf.coredump.cx/afl/
https://sourceforge.net/p/upx/discussion/6806/thread/0b5c5343/