Docker环境下AFL 2.57b模糊测试C程序仅探索1条路径的问题
问题分析与解决
核心问题
你的程序逻辑是直接比较命令行参数的字符串内容,但AFL通过@@传递给程序的是临时输入文件的路径,而非输入内容本身。程序并没有读取该文件的内容进行判断,因此无论AFL生成什么输入,程序都会把临时文件路径当作argv[1],永远触发else分支,导致仅能探索1条路径。
解决方法
方法1:修改程序读取输入文件内容(推荐)
调整main.c,让程序读取argv[1]指定的文件内容,适配AFL的@@工作模式:
#include <stdio.h> #include <stdlib.h> #include <string.h> #define BUF_SIZE 1024 int main(int argc, char* argv[]) { if (argc < 2) { fprintf(stderr, "Usage: %s <input_file>\n", argv[0]); return 1; } // 读取输入文件内容 FILE* fp = fopen(argv[1], "r"); if (!fp) { perror("Failed to open file"); return 1; } char buf[BUF_SIZE] = {0}; fgets(buf, BUF_SIZE - 1, fp); // 去掉换行符(避免干扰字符串比较) buf[strcspn(buf, "\n")] = '\0'; fclose(fp); // 用读取到的内容做分支判断 if (strcmp(buf, "-s") == 0) printf("girls\n"); else if (strcmp(buf, "-k") == 0) printf("boys!\n"); else printf("OMG!!\n"); return 0; }
重新编译程序:
afl-clang main.c -o afl-main
之后运行原fuzz命令即可,此时AFL生成的输入会被程序正确读取,触发不同分支路径。
方法2:不修改程序,直接传递命令行参数
如果不想修改代码,可通过脚本包装让AFL把生成的输入直接作为命令行参数传递:
- 创建字典文件
dict.txt,指定候选参数:
-s -k
- 运行AFL时用Shell脚本转发输入:
AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 afl-fuzz -i corpus/ -o afl_out -x dict.txt -- sh -c './afl-main "$(cat)"'
该命令会把AFL生成的输入(从标准输入读取)直接作为argv[1]传递给程序,触发不同分支。
额外排查点
- 确保
corpus目录下的初始种子有效:比如放置内容为-s和-k的两个文件,验证初始输入能触发不同分支。 - 检查编译有效性:运行
afl-showmap -o /dev/null -- ./afl-main test_input(test_input为包含-s的文件,对应方法1的程序),确认能生成不同的路径哈希。
内容的提问来源于stack exchange,提问作者amdeilami
相关产品推荐
相关产品推荐

