You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:AFL-fuzz无法检测到崩溃——首次使用AFL测试简易漏洞C代码遇阻

解决AFL-fuzz未检测到缓冲区溢出崩溃的问题

我来帮你排查这个入门时很容易踩的坑——你遇到的核心问题其实是AFL的输入传递方式和你的程序不匹配,咱们一步步来解决:

1. 关键问题:AFL默认输入是标准输入(stdin),你的程序却从命令行参数读取

你的程序通过argv[1]获取输入,但AFL-fuzz默认会把测试用例发送到程序的标准输入(stdin),而非命令行参数。这就导致AFL生成的所有测试用例根本没传到能触发缓冲区溢出的strcpy那里,自然不会发现崩溃。

两种解决方式:

方式一:修改程序,让它从stdin读取输入

把代码改成从标准输入获取内容,这样AFL的测试用例就能直接被程序接收:

#include <stdio.h>
#include <string.h>
int main(void){ 
    char name[10];
    // 从stdin读取输入
    if (fgets(name, sizeof(name), stdin) != NULL) {
        // 去掉fgets自带的换行符
        name[strcspn(name, "\n")] = '\0';
        printf("HELLO %s\n", name);
    }
    return 0;
}

重新用afl-gcc test.c -o test编译后,再运行afl-fuzz -i afl_in -o afl_out -- ./test,应该很快就能看到AFL检测到崩溃。

方式二:用AFL的@@占位符传递命令行参数

如果你不想修改代码,可以在启动AFL时用@@占位符,它会让AFL把测试用例保存成临时文件,然后把文件名作为命令行参数传给你的程序。你需要先修改程序读取这个文件的内容:

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

int main(int argc, char * argv[]){ 
    char name[10];
    if (argc > 1) {
        FILE *f = fopen(argv[1], "r");
        if (f == NULL) {
            perror("fopen");
            return 1;
        }
        // 从文件读取内容到name
        fgets(name, sizeof(name), f);
        fclose(f);
        name[strcspn(name, "\n")] = '\0';
        strcpy(name, name); // 保留原有的溢出触发点
        printf("HELLO %s\n", name);
    }
    return 0;
}

然后用这个命令启动fuzz:

afl-fuzz -i afl_in -o afl_out -- ./test @@

2. 辅助检查:确保系统允许生成核心转储

AFL需要通过检测核心转储来识别崩溃,所以要先确认系统开启了core dump:

ulimit -c unlimited

执行这个命令后再启动afl-fuzz,避免因为系统限制导致AFL无法捕获崩溃。

3. 验证测试用例的正确性

你之前创建的崩溃测试用例带了换行符,可能会影响测试结果。可以用以下命令生成不带换行的测试用例:

python3 -c "print('A'*26, end='')" > afl_in/testcase_crash

这样测试用例就是纯26个A,和你手动触发崩溃时的输入一致。

按照上面的步骤调整后,重新运行AFL,不出意外的话几分钟内就能检测到缓冲区溢出导致的崩溃了。

内容的提问来源于stack exchange,提问作者Snox

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 14:07:29