American Fuzzy Lop, Address Sanitizer and LibFuzzer

Hanno Böck


Everyone should have Linux environment with afl installed.

(preferrably with clang 4.0 or later)

Provided: Debian 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 glib version 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.

Fuzzing Bignums


OpenSSL BN_sqr bug (CVE-2014-3570)


  • BN_bin2bn - convert binary data to bignum (BIGNUM*)
  • BN_sqr - square bignum
  • BN_mul - multiply bignums
  • BN_cmp - compare bignums

Fuzz BN_sqr()

  • Get OpenSSL 1.0.1j or older
  • Compile OpenSSL with "CC=afl-clang-fast ./config; make"
  • Create wrapper code to compare BN_sqr and BN_mul output and throw an assert error on failure.
  • afl-clang-fast wrappercode.c [openssl_path]/libcrypto.a

Bignum bugs

  • OpenSSL modular exponentiation
  • NSS modular exponentiation, division
  • Nettle elliptic curve scalar multiplication
  • OpenSSL cornercases (a^0 mod 1)
  • matrixssl modular exponentiation (remote crash / memory corruption)


  • Inetd mode.
  • Intercepting network calls (preeny).
  • Manually craft something around the API of a library (see Heartbleed experiment).
  • afl patch from Doug Birdwell.

AFL/ASAN short tips

  • If there's custom memory allocation, disable it (jemalloc, PHP zend allocator, Mozilla NSPR arena, ...)
  • To get better stack traces for allocations (especially use after free bugs), set ASAN_OPTIONS="fast_unwind_on_malloc=0".
  • Checksums are bad for fuzzing, disable if possible.

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.


Run libfuzzer for OPENSSL_uni2asc with provided test stub.



Write libfuzzer stub for c-ares vulnerability CVE-2016-5180.



Minimize testcases with afl-tmin.

We can use small wrapper to use afl-tmin with libfuzzer stubs.

Recompile c-ares with afl / asan, compile stub, aflize-libfuzzer.cpp + c-ares.




Undefined behavior sanitizer (UBSAN)

  • Integer overflows
  • Invalid shifts
  • Unaligned memory

Problem: You will find a lot of low severity bugs.

Memory Sanitizer (MSAN)

Finds use of uninitialized memory.

Only clang, no gcc.

Many pitfalls.

Combine with -O2 and don't use FORTIFY_SOURCE.


Different approach of protocol fuzzing.

Sets up irc server, sends garbage.


Additional exercises

  • Find your own fuzzing goal.
  • Fuzz PHP 7.1.0 unserialize with AFL/ASAN and USE_ZEND_ALLOC=0.
  • Fuzz irssi with perl script.
  • Compile kernel with KASAN.


AFL persistent mode.

Kernel: KASAN, Syzcaller, vUSBf.

Google's OSS-Fuzz project.