从AFL开始fuzzing

01 关于Fuzzing

fuzzing,模糊测试。其与包括静态分析、动态分析、代码审计等传统漏洞检测方式的最大区别,就在于它可以大规模随机或半随机地生成测试数据,并以使程序crash为目标进行测试。这种方法被证明相当高效,可以敏锐地发掘代码中潜在地各种堆栈溢出等常见漏洞,也能用assert去调试非内存越界的问题(比如CVE-2014-3570 in OpenSSL)。

同样,fuzzing也有一定的局限性

  • 难以确定何时停止
  • 对目标的设置和输入源都由你自己控制
  • 可能卡在某一个对数据的检测中不能自拔
  • 只有部分类型的问题可以被fuzzer发现

不过fuzzing不失为一种强大的测试方法,就先从声名远扬的AFL(American fuzzy lop)的使用开始吧。

02 quickstart

本次测试源码也都来自afl-training

只需要两行代码就能感受到afl的快乐了

//在对源码调试时,使用afl提供的gcc作为gcc/g++的wrapper编译目标程序才能让afl进行插桩
CC=afl-clang-fast AFL_HARDEN=1 make  
afl-fuzz -i inputs -o out ./vulnerable

如果出现这个提示只需要照做就行

建议在非root的情况下运行,这样产生的结果不会有权限问题。运行一段时间后,在out的crashes中查看结果,可以用cat打开,如果你觉得乱码看其来不舒服,也可以用vim打开。复现结果时,直接把这些crash输入就可以了

./vulnerable < out/default/crashes/[file]

afl基本功能的实现我们可以从图中的总览来理解

03 harness

上面是对afl基本操作的体验,实际情况下的程序会有不同功能,在有程序源码的情况下,我们需要用harness进行具体的调试

harness基本要求:

  • 可运行
  • 有效对输入内容进行处理数据输入有两种方法,一种使直接用STDIN_FILENO输入,另一种是使用文件输入
  • 运行结束自动退出
  • 对非目标的crash,使用error代替crash
  • 跳过程序中可能存在的对数据的检测(否则afl会花费大量时间来生成可以通过检测的数据)

STDIN_FILENO输入

buffer型
ssize_t length;
char input[SIZE] = {0};
length = read(STDIN_FILENO, input, SIZE); //STDIN_FILENO为source,input为dest,SIZE为自定义常量

int型
int a = 0;
read(STDIN_FILENO, &a, 4); //直接从输入流中转换一个整数

文件输入

  1. 从命令行读取文件地址
  2. 代码打开文件,读取到缓冲区
  3. 传输内容到测试区块

harness代码


#include <unistd.h>
#include <string.h>
#include <stdio.h>

#include "library.h"

// 确定一个能覆盖你要调试部分所需输入的最大size
#define SIZE 100

int main(int argc, char* argv[]) {
	if((argc == 2) && strcmp(argv[1], "echo") == 0) {
		// 确定要调试的功能,当然也可直接一起调试,输入内容不重要,长度设置好就行了
		char input[SIZE] = {0};

		ssize_t length;
		length = read(STDIN_FILENO, input, SIZE);

		lib_echo(input, length);
	} else if ((argc == 2) && strcmp(argv[1], "mul") == 0) {
		int a,b = 0;
		read(STDIN_FILENO, &a, 4);
		read(STDIN_FILENO, &b, 4);
		printf("%d\n", lib_mul(a,b));
	} else {
		printf("Usage: %s mul|echo\n", argv[0]);
	}
}

编译后开始调试

#using one of afl-clang-fast, afl-clang, or afl-gcc
AFL_HARDEN=1 afl-clang-fast harness.c 原代码.c -o 测试程序名称
afl-fuzz -i 输入文件夹名 -o 输出文件夹 ./测试程序

跑一会就出结果了,很简单的程序,输入pop!就自动abort。

image-20220116164828196