它通過對源碼進行重新編譯時進行插桩的方式自動產生測試用例來探索二進制程序內部新的執行路徑。
與其他基於插桩技術的 fuzzers 相比,afl-fuzz 具有較低的性能消耗,有各種高效的 fuzzing 策略和技巧最小化技巧,不需要先行複雜的配置,能無縫處理複雜的現實中的程序。
當然 AFL 也支持直接對沒有源碼的二進制程序進行測試,但需要 QEMU 的支持。
安裝 afl-fuzz#
從官網下載源碼壓縮包,解壓。然後編譯安裝:
make
sudo make install
安裝完成後一般需要配置一下,將 coredumps 輸出為文件,而不是把崩潰信息發送到特定的處理程序:
sudo su
echo core > /proc/sys/kernel/core_pattern
官方文檔:http://lcamtuf.coredump.cx/afl/README.txt
測試示例#
對於有源碼的測試程序,可以使用 afl 來代替 gcc 或 clang 來編譯。用 afl 的插桩可以優化 afl-fuzz 的性能,加速 fuzz。
測試程序#
下面是一個崩潰示例程序:
#include <stdio.h>
#include <signal.h>
int main(int argc, char *argv[])
{
char buf[233] = {0};
FILE *input = NULL;
input = fopen(argv[1], "r");
if(input != 0)
{
fscanf(input ,"%s", &buf);
printf("buf is %s\n", buf);
func(buf);
fclose(input);
}
else
printf("error!");
return 0;
}
int func(char *data)
{
if(data[0] == 'A')
raise(SIGSEGV);
else
printf("ok\n");
return 0;
}
當輸入文件的首字母為 A 時程序崩潰。
用 afl-gcc 編譯程序,插桩:
afl-gcc test.c -o test
準備#
新建輸入、輸出文件夾:
mkdir fuzz_in fuzz_out
準備初始化 測試用例,將 case 內容寫成 aaa, fuzzer 會根據測試用例進行突變:
echo aaa > fuzz_in/case
開始 fuzzing#
fuzz_in
是自帶的輸入目錄,fuzz_out
是指定的輸出目錄
afl-fuzz -i fuzz_in -o fuzz_out ./test @@
這裡使用@@
標誌,從文件中讀取輸入。在實際執行的時候會把@@
替換成fuzz_in
下的測試樣本
fuzzing 結果#
fuzz_out/crashes$ cat id\:000000\,sig\:11\,src\:000000\,op\:flip1\,pos\:0
Aaa
參考資料: