Fuzzer for CGI binaries written using LibAFL.
Warning
This fuzzer is not generalized, it was made to test the webproc and webupg executables belonging to the DSL-3788 router from D-Link. You will need to tweak the grammar if you want significant results with other targets. For this reason I tried putting [APPLICATION SPECIFIC] tags wherever the code is not applicable for other targets.
I used epi052 solutions to domenukk fuzzing101 exercises as a base for a lot of the fuzzer and took heavy inspiration from TrackMania fuzzer for the grammar part.
This fuzzer originally used a custom version of LibAFL 0.8.2 which I added support for the MIPS architecture (at the time I used cargo 1.68.0-nightly). I ported it to work with version 0.14.1 of LibAFL with minimal testing (reads, it might break).
Its development and triage of a vulnerability found using it (CVE-2024-57440) is described in this blog post.
cargo make --makefile makefile.toml build
Recreate the relevant directory structure of the firmware (mainly /bin, /lib and /usr), inside the directory /build.
Then inside the /build directory run the following command:
LD_LIBRARY_PATH= ./bin/qemu_mips_cgi --cores 1 --stdout ../fuzzer_logs.txt -o ../solutions -- ./bin/qemu_mips_cgi --strace -L . -D strace_logs.txt ./usr/www/cgi-bin/webproc
This will fuzz the executable found at ./usr/www/cgi-bin/webproc and save the output of the fuzzer in a file called fuzzer_logs.txt, output your crashes in the /solutions directory and output the strace logs (for debugging purposes, for higher performance I suggest to disable it) in strace_logs.txt
The output saved in /solutions is a representation of derivation trees used by Nautilus, it must be concretized to triage the findings.
To concretize, run the binary with the --to-concrete
flag.
./build/bin/qemu_mips_cgi --to-concrete <binary_name> <crash_directory>
This will create a /concrete subdirectory in the crash directory specified, containing all the concretized crashes.
Example using webproc, with the default directory structure:
./build/bin/qemu_mips_cgi --to-concrete webproc solutions
This requires qemu-mips
installed on the system.
usage: repro.py [-h] -c CRASHFILE -b BIN [-r ROOTDIR] [--logfile LOGFILE] [-g]
Reproduce crashes from concretized inputs
options:
-h, --help show this help message and exit
-c CRASHFILE, --crashfile CRASHFILE
concretized crash file to use as input
-b BIN, --bin BIN path to binary to test
-r ROOTDIR, --rootdir ROOTDIR
root directory of the firmware (default: /build)
--logfile LOGFILE output file containing strace information
-g enable GDB on port 999
After concretizing the crashes as described before, run the repro script. An example command could be:
python3 repro.py -c solutions/concrete/id\:3-5 --bin build/usr/www/cgi-bin/webproc --logfile strace_logs.txt
You can use gdb-multiarch
to debug the executable (if -g
is used).
- Set architecture with
set arch mips
- Set endianess with
set endian big
- Set target with
target remote localhost:9999