American Fuzzy Lop, Address Sanitizer and LibFuzzer

Hanno Böck


Everyone should have Linux environment with afl installed.

(preferrably with clang 3.8 or later)

Provided: Ubuntu VM image.

Part 1: Introduction


Use random / malformed inputs to search for bugs.

Usually: Start with valid file, add errors.


Dump fuzzing: Only random mutations, no knowledge about application.

Template-based fuzzing: Individual fuzzer for each data input format.

Either not very good or a lot of work.

American Fuzzy Lop

New approach: Instrumentation-based fuzzing.

Use code paths as a feedback mechanism.

Smart and easy to use.

How to fuzz with AFL?

Compile application with afl-gcc/afl-clang/afl-clang-fast.

Run afl-fuzz.


./configure CC=afl-clang-fast CXX=afl-clang-fast++ --disable-shared; make

Place sample file(s) in directory "in/".

afl-fuzz -i in -o out ./[path_to_executable] [params] @@

Exercise: Run afl on latest version of lha.

Part 2: Address Sanitizer (ASAN)

Small buffer overflows, out of bounds read, use after free: They often don't crash.

Address Sanitizer

Feature of gcc/clang.

Relatively fast (~1.5x).

Finds many bug classes, some of them can't be found with runtime-only tools like valgrind.


int main() {
	char *a = malloc(10);
int main() {
	int i[2] = {1, 0};

Address Sanitizer

Add -fsanitize=address to CFLAGS/CXXFLAGS/LDFLAGS.

Control with environment variable ASAN_OPTIONS, e. g. ASAN_OPTIONS="log_path=/var/log/asan/asan-error".

Exercise: Run test suite of latest version of glib (2.48.1) with Address Sanitizer.

Part 3: AFL and ASAN together

Fuzzing with superpowers

ASAN finds hidden bugs, so combining Fuzzing and ASAN is smart.

How to afl-fuzz with ASAN.

Environment variable AFL_USE_ASAN=1.

Disable memory limit: -m none

Exercise: Fuzz lha again, with ASAN enabled.

Part 4: Good fuzzing targets


Good targets: Everything that parses complex data.

Tools that support many file formats (ImageMagick, 7-zip, libarchive, ffmpeg, ...)

Exercise: Find something interesting to fuzz.

Part 5: LibFuzzer

AFL or Libfuzzer

AFL works on executables, LibFuzzer on functions.

No forking / startup: Faster.

But: Need to write code, fragile.


#include <openssl/rsa.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
	unsigned char out[512];

	RSA_padding_check_PKCS1_type_1(out, 512, Data, Size, 512);
	return 0;

LibFuzzer Howto

Write function LLVMFuzzerTestOneInput that takes buffer and size argument, call function to be tested.

Be careful: Memory leaks will kill your fuzzing process.

Exercise: Write libfuzzer wrapper for d2i_SSL_SESSION (or other OpenSSL function).

If there's time

Other Sanitizers: UBSAN, MSAN, TSAN.

Kernel: KASAN, Syzcaller, vUSBf.

Large files.

Bignum fuzzing / differential testing.

Custom allocators.