最近打 ctf 的時候感覺有點遇到瓶頸,就來 fuzz 這塊看看。
AFL 全稱為 American huzzy loop,是 Fuzzing 最高階的測試工具之一。這個工具對有原始碼和無原始碼的二進位制程式均可以進行 fuzz 測試。
alf 各位自行安裝即可,值得注意的是,在我本機 glibc2.31 的環境下,編譯 alf 前要對 AFL/llvm_mode/afl-clang-fast.c修改一下,否則會出現報錯,只需把部分內容註釋掉即可
輸入 afl-fuzz 出現下圖即安裝成功
我們先看對有原始碼的二進位制程式是怎樣進行測試:
在 AFL 資料夾裡會有很多目錄,我們進入 test。首先先把自己要測試的原始碼放進去,再建兩個資料夾分別放測試輸入的內容和測試輸出的內容,我這裡就建了 fuzz_in , fuzz_out。在fuzz_in 裡面還要建一個檔案,裡面隨便放一些字母就行(這裡筆者也不是很清楚為什麼)。在有原始碼的情況下我們用 afl 自帶的編譯器,對其進行編譯這會使測試更加高效。原因是 afl 自帶的編譯器在編譯時會對目標程式插樁,故此過程叫插樁編譯。我從其他師傅的部落格裡找了一個簡單的二進位制程式來進行測試。
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> #include <signal.h> int vuln(char *str) { int len = strlen(str); if(str[0] == 'A' && len == 66) { raise(SIGSEGV); //如果輸入的字串的首字元為A並且長度為66,則異常退出 } else if(str[0] == 'F' && len == 6) { raise(SIGSEGV); //如果輸入的字串的首字元為F並且長度為6,則異常退出 } else { printf("it is good!\n"); } return 0; } int main(int argc, char *argv[]) { char buf[100]={0}; gets(buf);//存在棧溢位漏洞 printf(buf);//存在格式化字串漏洞 vuln(buf); return 0; }
對其插樁編譯
afl-gcc -g -o afl_test afl_test.c
我們接下來就可以對其進行測試了,此外在 fuzz 前要關閉系統的核心轉儲,確保在 fuzz 的過程中即使出現 crash 也不會停止,不然就會出現如下報錯
我們關閉系統核心轉儲開始測試
sudo su echo core >/proc/sys/kernel/core_pattern
exit
afl-fuzz -i fuzz_in -o fuzz_out ./afl_test
這上面的數字是彩色的,注意 overall results 裡的 cycles results 的顏色會隨著 fuzz 次數的增加從紅色到黃色到藍色到綠色,當他到綠色的時候也就說明基本上該有的 crash 都出來了,繼續跑下去,發現的東西也很少了,此時我們就可以 crtl+c 結束測試。
此時我們就可以從我們剛剛建立的 fuzz_out 資料夾裡看到測試的結果了。
我們再進行檢視
之前一次測試的時候格式化字串也測試出來了,不知道為什麼這次沒出來。好吧,那插樁測試就寫到這裡。
下面我們來看無原始碼的測試過程。
進行無原始碼測試之前我們要進入到 AFL/qemu_mode 在終端中執行一下 ./build_qemu_support.sh
遇見如下報錯:
make[1]: *** [/xxxxxxxx/AFL/qemu_mode/qemu-2.10.0/rules.mak:66: linux-user/syscall.o] Error 1
make: *** [Makefile:326: subdir-x86_64-linux-user] Error 2
查閱資料後得知:給 /AFL/qemu_mode/patches/syscall.diff 打個補丁即可
--- qemu-2.10.0-clean/linux-user/syscall.c 2020-03-12 18:47:47.898592169 +0100 +++ qemu-2.10.0/linux-user/syscall.c 2020-03-12 19:16:41.563074307 +0100 @@ -34,6 +34,7 @@ #include <sys/resource.h> #include <sys/swap.h> #include <linux/capability.h> +#include <linux/sockios.h> // https://lkml.org/lkml/2019/6/3/988 #include <sched.h> #include <sys/timex.h> #ifdef __ia64__ @@ -116,6 +117,8 @@ int __clone2(int (*fn)(void *), void *ch #include "qemu.h" +extern unsigned int afl_forksrv_pid; + #ifndef CLONE_IO #define CLONE_IO 0x80000000 /* Clone io context */ #endif @@ -256,7 +259,9 @@ static type name (type1 arg1,type2 arg2, #endif #ifdef __NR_gettid -_syscall0(int, gettid) +// taken from https://patchwork.kernel.org/patch/10862231/ +#define __NR_sys_gettid __NR_gettid +_syscall0(int, sys_gettid) #else /* This is a replacement for the host gettid() and must return a host errno. */ @@ -6219,7 +6224,8 @@ static void *clone_func(void *arg) cpu = ENV_GET_CPU(env); thread_cpu = cpu; ts = (TaskState *)cpu->opaque; - info->tid = gettid(); + // taken from https://patchwork.kernel.org/patch/10862231/ + info->tid = sys_gettid(); task_settid(ts); if (info->child_tidptr) put_user_u32(info->tid, info->child_tidptr); @@ -6363,9 +6369,11 @@ static int do_fork(CPUArchState *env, un mapping. We can't repeat the spinlock hack used above because the child process gets its own copy of the lock. */ if (flags & CLONE_CHILD_SETTID) - put_user_u32(gettid(), child_tidptr); + // taken from https://patchwork.kernel.org/patch/10862231/ + put_user_u32(sys_gettid(), child_tidptr); if (flags & CLONE_PARENT_SETTID) - put_user_u32(gettid(), parent_tidptr); + // taken from https://patchwork.kernel.org/patch/10862231/ + put_user_u32(sys_gettid(), parent_tidptr); ts = (TaskState *)cpu->opaque; if (flags & CLONE_SETTLS) cpu_set_tls (env, newtls); @@ -11402,7 +11410,8 @@ abi_long do_syscall(void *cpu_env, int n break; #endif case TARGET_NR_gettid: - ret = get_errno(gettid()); + // taken from https://patchwork.kernel.org/patch/10862231/ + ret = get_errno(sys_gettid()); break; #ifdef TARGET_NR_readahead case TARGET_NR_readahead:
成功!
又出現如下報錯:
這時我們返回 AFL 目錄重新 make install 即可
此後和插樁測試的過程就大體一致了,只是在 test 裡直接放進二進位制程式即可,並且加上引數 -Q
afl-fuzz -i fuzz_in -o fuzz_out -Q ./afl_test2
好了 afl 的一些基礎用法掌握了,以後就在 ctf 打不動的時候,跟著其他師傅的部落格去復現CVE漏洞看看。
參考文章:
https://blog.csdn.net/weixin_50919879/article/details/108916954
https://blog.csdn.net/geniusle201/article/details/111028697
https://www.codeleading.com/article/61745363753/
https://blog.csdn.net/qq_38239282/article/details/120975670