Just found out #LibAFL launcher can print output of child processes if you set the LIBAFL_DEBUG_OUTPUT=1 env variable.

I knew this some time in the past, but forgot..

#fuzzing #fuzzingTips

To debug a fuzzer (or anything really), I use this magical strace command:

strace -tt -yy -y -f -e trace=open,read,write,pipe,socket,dup2,clone,close -s 10000 -o /tmp/strace.log ./tool

  • -tt enables microseconds
  • -yy prints additional information about each file descriptor (like, files, sockets, etc.)
  • -f follows forks (get all info about subprocesses, threads, etc.)
  • -e trace= traces only specific syscalls we are interested in
  • -s increases the max size of logged strings
  • -o writes everything to /tmp/strace.log

Then, I can look at the log in vim or vscode, both with syntax hightlighting ( in vim, you may need to :set filetype=strace )

As additional weapon, I add -k which can dump a stacktrace at every syscall. Super slow, but super useful.

#fuzzing #fuzzingTips #debugging

The deprecation of #libfuzzer is a great time to recompile your fuzzing testcases with AFL++'s afl-cc (supports the same testcases!)
and switch your future fuzzer developments to #LibAFL

https://llvm.org/docs/LibFuzzer.html#status

#fuzzing #fuzzingTips

libFuzzer – a library for coverage-guided fuzz testing. — LLVM 19.0.0git documentation

If you are #fuzzing on macOS then stay on BigSur and do not update, especially if you are on M1/M2. Things are breaking left and right ... sigh ... #fuzzingTips #macos

For binary-only emulation in #LibAFL qemu, you can now dump DrCov traces to see in #idapro (lighthouse), #binaryninja (bncov), or #ghidra (dragondance) which paths the executions took.

This helps you understand where your fuzzer gets stuck, develop the harness further, and reach greater depth in the binary, eventually.

Binary-only modes of #AFLplusplus ( #qemu / #frida ) and libafl_frida also support DrCov output, already.

#fuzzing #fuzzingTips
https://github.com/AFLplusplus/LibAFL/pull/878

Adding DrCov for qemu by TeumessianFox · Pull Request #878 · AFLplusplus/LibAFL

Advanced Fuzzing Library - Slot your Fuzzer together in Rust! Scales across cores and machines. For Windows, Android, MacOS, Linux, no_std, ... - Adding DrCov for qemu by TeumessianFox · Pull Request #878 · AFLplusplus/LibAFL

GitHub

Trying to fuzz argv for whatever reason?

You should have a look at argvfuzz in AFL++.
#include "/path/to/argv-fuzz-inl.h" and place AFL_INIT_SET0("prog_name") just as first line of main.

The fuzz target will read command line arguments from stdin (no @@ is needed). And seeds will contain null-terminated strings like AAAA\0BBBB\0CCCC\0.

https://github.com/AFLplusplus/AFLplusplus/blob/stable/utils/argv_fuzzing/argv-fuzz-inl.h

@aflplusplus #fuzzing #fuzzingTips

AFLplusplus/argv-fuzz-inl.h at stable · AFLplusplus/AFLplusplus

The fuzzer afl++ is afl with community patches, qemu 5.1 upgrade, collision-free coverage, enhanced laf-intel & redqueen, AFLfast++ power schedules, MOpt mutators, unicorn_mode, and a lot more!...

GitHub

Fuzzing a file format that is complex and has no ready-made dictionary?

AFL++ has nice compile-time flag that generates a dictionary:
AFL_LLVM_DICT2FILE=/absolute/path/file.txt

It will write all constant string comparisons to dictionary.

Just use this dictionary with afl-fuzz -x option.

@aflplusplus #fuzzing #fuzzingTips

@dmnk @aflplusplus that #fuzzingtips hashtag is a good idea, we should use that more thoroughly in the future. and a good feature in mastodon that you can follow hashtags. #fuzzing

Fuzzing in persistent mode and got hard-to-replay crashes a few hundred executions in?

There's a handy flag in afl++: AFL_PERSISTENT_RECORD

With this compile-time and run-time flag, afl-fuzz will store every single input it delivered to the target that leads up to a crash.

So, say the target forked, ran 300 executions, then crashed, you will have the complete trace of 300 inputs leading up to the corpus program state.

This way you can replay traces for more stateful crashes.

@aflplusplus #fuzzing #fuzzingTips