Fuzz-AFL入门

Fuzz-AFL入门

工具

AFL 则是fuzzing的一个很好用的工具,全称是American Fuzzy Lop,由Google安全工程师Michał Zalewski开发的一款开源fuzzing测试工具,可以高效地对二进制程序进行fuzzing,挖掘可能存在的内存安全漏洞,如栈溢出、堆溢出、UAF、double free等。原理是通过对源码进行重新编译时进行插桩(简称编译时插桩)的方式自动产生测试用例来探索二进制程序内部新的执行路径。AFL也支持直接对没有源码的二进制程序进行测试,但需要QEMU的支持。

安装使用

从 http://lcamtuf.coredump.cx/afl/ 下载源码,然后解压之后安装

make
sudo make install

安装成功
在这里插入图片描述

安装目录

afl-gcc 和afl-g++ 分别对应的是gcc 和g++ 的封装
afl-clang 和afl-clang++ 分别对应clang 的c 和c++ 编译器封装À。
afl-fuzz 是AFL 的主体,用于对目标程序进行fuzz。
afl-analyze 可以对用例进行分析,通过分析给定的用例,看能否发现用例中有意义的字段。
afl-qemu-trace 用于qemu-mode,默认不安装,需要手工执行qemu-mode 的编译脚本进行编译,后面会介绍。
afl-plot 生成测试任务的状态图
afl-tmin 和afl-cmin 对用例进行简化
afl-whatsup 用于查看fuzz 任务的状态
afl-gotcpu 用于查看当前CPU 状态
afl-showmap 用于对单个用例进行执行路径跟踪

图片为我们使用AFL进行测试时的运行截图
在这里插入图片描述

整体来说,运行状态主要包括8个部分

  • process timing

这里展示了fuzz的运行时间、最近一次发现新执行路径的时间、最近一次崩溃的时间、最近一次超时的时间。
值得注意的是第2项,最近一次发现新路径的时间。如果由于目标二进制文件或者命令行参数出错,那么其执行路径应该是一直不变的,所以如果从fuzzing开始一直没有发现新的执行路径,那么就要考虑是否有二进制或者命令行参数错误的问题了。

  • cycle progress

主要记录了当前正在处理的fuzz进程和由于超时放弃的路径数

  • stage progress

这里记录了包括正在测试的fuzzing策略、进度、目标的执行总次数、目标的执行速度

执行速度可以直观地反映当前跑的快不快,如果速度过慢,比如低于500次每秒,那么测试时间就会变得非常漫长。如果发生了这种情况,那么我们需要进一步调整优化我们的fuzzing

  • fuzzing strategy yields
  • overrall results

这里包括运行的总周期数、总路径数、崩溃次数、超时次数。

其中,总周期数可以用来作为何时停止fuzzing的参考。随着不断地fuzzing,周期数会不断增大,其颜色也会由紫色,逐步变为黄色、蓝色、绿色。一般来说,当其变为绿色时,代表可执行的内容已经很少了,继续fuzzing下去也不会有什么新的发现了。此时,我们便可以通过Ctrl-C,中止当前的fuzzing

  • map coverage

  • findings in depth

  • path geometry

levels表示测试等级,pending表示还没有经过fuzzing的输入数量,pend fav表明fuzzer感兴趣的输入数量,own finds表示在fuzzing过程中新找到的,或者是并行测试从另一个实例导入的,imported中的n/a表明不可用,即没有导入。最后说明一下stability,表明相同输入是否产生了相同的行为,一般结果都是100%,如果低于100%并且变红,则需要查阅官方文档寻找解决步骤。

使用方法分为有源码无源码有二进制应用程序

有源码-Fuzz

对于有源码的fuzz,使用AFL自带的编译器对源码进行插桩编译,然后利用Afl-fuzz对编译好的二进制应用进行fuzz
编译c程序使用afl-gcc,编译c++程序使用afl-g++

$ afl-gcc test.c -o test
$ afl-g++ test.cpp -o test

然后使用afl-fuzz进行测试,命令行如下,-i指明测试用例的目录,-o指明测试结果的存放目录。对于直接从终端获取输入的程序来说,我们需要在testcase_dir目录下新建一个文件,文件的内容就是程序的输入,文件命名不唯一,后面会给一个示例

$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program [...params...]

对于从文件中获取输入的程序,请使用“@@”标记,AFL将会自动将其替换为测试用例中的文件名

$ ./afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@

在这里插入图片描述

无源码二进制应用Fuzz

AFL对于缺少源码的二进制程序fuzz,利用qemu_mode

安装

cd  qemu_mode
./ build_qemu_support.sh

中途会遇到报错,记录一下解决方案
报错1:
在这里插入图片描述

sudo apt-get install libtool
sudo apt-get install libtool-bin

报错2:
在这里插入图片描述

编译qemu的时候报错,这是因为memfd_create和glibc中的同名函数冲突了,所以需要给安装包打patche

cd ./qemu_mode/patches
vim memfd_create.diff
//添加以下patche 并保存
diff -ru qemu-2.10.0-clean/util/memfd.c qemu-2.10.0/util/memfd.c
--- qemu-2.10.0-clean/util/memfd.c      2018-11-20 18:11:00.170271506 +0100
+++ qemu-2.10.0/util/memfd.c    2018-11-20 18:11:13.398423613 +0100
@@ -37,7 +37,7 @@
 #include <sys/syscall.h>
 #include <asm/unistd.h>
 
-static int memfd_create(const char *name, unsigned int flags)
+int memfd_create(const char *name, unsigned int flags)
 {
 #ifdef __NR_memfd_create
     return syscall(__NR_memfd_create, name, flags);

//修改 build_qemu_support.sh安装添加的patch
 patch -p1 <../patches/elfload.diff || exit 1
 patch -p1 <../patches/cpu-exec.diff || exit 1
 patch -p1 <../patches/syscall.diff || exit 1
 patch -p1 <../patches/memfd_create.diff || exit 1

报错3:
在这里插入图片描述
解决方案:
加上一个syscall1.diff文件,将其放在patches文件夹下,然后再改build_qemu_support.sh的patch就可以了

--- 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:

完成安装后:
在这里插入图片描述
使用Qemu模式来fuzz缺少源代码的二进制程序,使用-Q参数

如果提示出现Failed to locate afl-qemu-trace的问题
在qemu-2.10.0目录下执行

sudo make install

在这里插入图片描述
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gAXowIjs-1672297678087)(images/0ddd64b9f4395aa5a88365027715927c4c0269a69eaa26794f2159de99f6693e.png)]

执行速度比起源码fuzz有显著下降

关于ARM这部分,看到Qemu的Readme里描述说在调用之前设置CPU_TARGET/build_qemu_support.sh,可以得到一个能够运行非本机二进制文件的构建(例如可以尝试CPU_TARGET=arm)

关于ARM架构的二进制FUZZ后面有待尝试,UU们有什么推荐的好工具嘛?

参考:
https://xz.aliyun.com/t/4314
https://blog.csdn.net/A951860555/article/details/119666269
https://blog.csdn.net/qq_42931917/article/details/112801073
https://blog.csdn.net/qysh123/article/details/114792891

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值