linuxiotqemufuzzing

"Fork server handshake failed" Error when fuzzing an arm binary without source code


anybody here? I have been working on using afl-qemu mode fuzzing IoT binaries. But I got a "Fork server handshake failed" problem when started to run the binary. I have read the previous related session but none of those fix my problem.

The information of the binary is here:

./bin/busybox: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-uClibc.so.0, stripped

Through my tests, only the version of qemu bigger than 4.1.0 can cope with the '-L' parameter successfully. So I upgrade the qemu version through editing the build_qemu_support.sh. What needs to be mention is that I comment out a few lines of code in order to deal with the error that occurred running.

#patch -p1 <../patches/elfload.diff || exit 1
#patch -p1 <../patches/cpu-exec.diff || exit 1
#patch -p1 <../patches/syscall.diff || exit 1

After setting the QEMU_LD_PREFIX and AFL_PATH, I tried the suggestion like 'afl-showmap -m none -o fuzz_out/out.txt -Q ./bin/busybox cat' and it turned out to be fine.

root@ubuntu:squashfs-root# afl-showmap -m none -o fuzz_out/out.txt -Q ./bin/busybox cat
afl-showmap 2.52b by <lcamtuf@google.com>
[*] Executing './bin/busybox'...

-- Program output begins --

But when I tried command 'afl-fuzz -m none -i fuzz_in/ -o fuzz_out/ -Q ./bin/busybox cat @@' , it reported the error shown below.

root@ubuntu:squashfs-root# afl-fuzz -m none -i fuzz_in/ -o fuzz_out/ -Q ./bin/busybox cat @@
afl-fuzz 2.52b by <lcamtuf@google.com>
[+] You have 4 CPU cores and 2 runnable tasks (utilization: 50%).
[+] Try parallel jobs - see /usr/local/share/doc/afl/parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[*] Checking core_pattern...
[*] Setting up output directories...
[+] Output directory exists but deemed OK to reuse.
[*] Deleting old session data...
[+] Output dir cleanup successful.
[*] Scanning 'fuzz_in/'...
[+] No auto-generated dictionary tokens to reuse.
[*] Creating hard links for all input files...
[*] Validating target binary...
[*] Attempting dry run with 'id:000000,orig:testcase'...
[*] Spinning up the fork server...

[-] Hmm, looks like the target binary terminated before we could complete a
    handshake with the injected code. Perhaps there is a horrible bug in the
    fuzzer. Poke <lcamtuf@coredump.cx> for troubleshooting tips.

[-] PROGRAM ABORT : Fork server handshake failed
         Location : init_forkserver(), afl-fuzz.c:2253

Could anybody tell me where is the problem? Is there anything to do with my upgrade of qemu? Thanks so much!!


Solution

  • You've tried to upgrade the version of QEMU that afl-qemu uses. Because afl-qemu makes modifications to QEMU's source, this is not a trivial thing to do. In particular, these commands that you commented out:

    #patch -p1 <../patches/elfload.diff || exit 1
    #patch -p1 <../patches/cpu-exec.diff || exit 1
    #patch -p1 <../patches/syscall.diff || exit 1
    

    are all commands that say "make the precise modifications to the QEMU source code that the .diff files specify". Commenting out the patch commands means that the modifications aren't made. It is then not surprising that the resulting QEMU binary doesn't interact with the afl-qemu framework in the way that it should.

    If you need to make afl-qemu work with a newer QEMU, you will have to look inside all the patch files and identify what the equivalent changes on the newer QEMU version would be. That is going to be tricky unless you're familiar (or willing to take the time to become familiar) with the internals of QEMU and afl-qemu. (You might look around to see if anybody else has already done this.)

    If the only reason you tried this upgrade was to try to avoid the QEMU bug with its '-L' option in earlier QEMU versions, it will probably be easier if you instead use the standard afl-qemu, and change what the directory you are pointing '-L' at to be simpler so that the older QEMU can work with it. In particular, don't point it at an entire chroot, but instead point it only at a directory structure with guest shared libraries, and where there aren't any symbolic links between directories. (It is the symbolic link structure in particular that is what causes the hang in the older QEMU.)