固件动态链接二进制用afl-fuzz++测试时遇Fork server握手失败的解决方法
目标二进制信息
测试对象是来自IoT设备Linux x86根文件系统固件的dos2unix二进制,属于BusyBox v1.24.2的多调用程序,用法如下:
BusyBox v1.24.2 (2019-06-25 00:47:00 UTC) multi-call binary. Usage: dos2unix [-ud] [FILE] Convert FILE in-place from DOS to Unix format. When no file is given, use stdin/stdout. -u dos2unix -d unix2dos
初始问题
QEMU运行错误
最初使用以下命令在QEMU用户模式运行时出现重定位错误:
qemu-x86_64 -L /pathto/extracted_fs /pathto/extracted_fs/usr/bin/dos2unix -h
错误信息:
relocation error: /lib/x86_64-linux-gnu/libc.so.6: symbol _dl_signal_error, version GLIBC_PRIVATE not defined in file ld-linux-x86-64.so.2 with link time reference.
AFL模糊测试启动失败
尝试使用以下命令启动afl-fuzz:
QEMU_LD_PREFIX=/pathto/extracted_fs afl-fuzz -Q \ -i /pathto/testing-dos2unix/test_input \ -o /pathto/testing-dos2unix/test_output \ /pathto/extracted_fs/usr/bin/dos2unix -d @@
得到错误提示:
[-] Hmm, looks like the target binary terminated before we could complete a handshake with the injected code. You can try the following:
- The target binary crashes because necessary runtime conditions it needs are not met. Try to: 1. Run again with AFL_DEBUG=1 set and check the output of the target binary for clues. 2. Run again with AFL_DEBUG=1 and 'ulimit -c unlimited' and analyze the generated core dump. - Possibly the target requires a huge coverage map and has CTORS. Retry with setting AFL_MAP_SIZE=10000000.Otherwise there is a horrible bug in the fuzzer.
Poke the Awesome Fuzzing Discord for troubleshooting tips.[-] PROGRAM ABORT : Fork server handshake failed
Location : afl_fsrv_start(), src/afl-forkserver.c:1687
环境信息
- qemu-x86_64 version 8.2.2 (Debian 1:8.2.2+ds-0ubuntu1.5)
- afl-fuzz++4.32a based on afl by Michal Zalewski and a large online community
已验证的正常运行命令
已找到可在QEMU用户模式正常运行该二进制的命令:
qemu-x86_64 /pathto/extracted_fs/lib64/ld-linux-x86-64.so.2 --library-path /pathto/extracted_fs/lib64:/pathto/extracted_fs/usr/lib /pathto/extracted_fs/usr/bin/dos2unix
解决方法
由于直接使用QEMU_LD_PREFIX或-L参数会触发GLIBC重定位问题,需将手动指定loader和库路径的逻辑整合到AFL命令中,具体调整后的命令如下:
基础调整命令
AFL_DEBUG=1 ulimit -c unlimited && \ afl-fuzz -Q \ -i /pathto/testing-dos2unix/test_input \ -o /pathto/testing-dos2unix/test_output \ -- qemu-x86_64 /pathto/extracted_fs/lib64/ld-linux-x86-64.so.2 \ --library-path /pathto/extracted_fs/lib64:/pathto/extracted_fs/usr/lib \ /pathto/extracted_fs/usr/bin/dos2unix -d @@
命令说明
- 使用
--分隔AFL参数与目标程序启动命令,让AFL将整个qemu+loader+二进制的组合视为待模糊对象 - 保留手动指定loader和库路径的逻辑,规避之前的GLIBC重定位错误
- 加入
AFL_DEBUG=1和ulimit -c unlimited,方便后续排查运行问题 @@会被AFL自动替换为测试用例文件路径,适配dos2unix的文件输入模式
额外排查步骤
- 先验证单独运行逻辑:在启动AFL前,先单独运行QEMU部分命令,确认能正常处理测试输入:
qemu-x86_64 /pathto/extracted_fs/lib64/ld-linux-x86-64.so.2 \ --library-path /pathto/extracted_fs/lib64:/pathto/extracted_fs/usr/lib \ /pathto/extracted_fs/usr/bin/dos2unix -d /pathto/testing-dos2unix/test_input/sample.txt
确保无运行错误后,再启动AFL模糊测试。
- 增大覆盖率映射大小:如果仍出现fork server握手失败,尝试设置更大的
AFL_MAP_SIZE:
AFL_MAP_SIZE=10000000 AFL_DEBUG=1 ulimit -c unlimited && \ afl-fuzz -Q \ -i /pathto/testing-dos2unix/test_input \ -o /pathto/testing-dos2unix/test_output \ -- qemu-x86_64 /pathto/extracted_fs/lib64/ld-linux-x86-64.so.2 \ --library-path /pathto/extracted_fs/lib64:/pathto/extracted_fs/usr/lib \ /pathto/extracted_fs/usr/bin/dos2unix -d @@
内容的提问来源于stack exchange,提问作者Someijam

