Fuzzing

American Fuzzy Lop, Address Sanitizer and LibFuzzer

Hanno Böck
https://hboeck.de/
https://fuzzing-project.org/

Preparation

Everyone should have Linux environment with afl installed.

(preferrably with clang 3.8 or later)

Provided: Ubuntu VM image.

Part 1: Introduction

Fuzzing

Use random / malformed inputs to search for bugs.

Usually: Start with valid file, add errors.

Past

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.

Howto

./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.

-fsanitize=address

int main() {
	char *a = malloc(10);
	a[0]=1;
	free(a);
	printf("%i\n",a[0]);	
}
int main() {
	int i[2] = {1, 0};
	printf("%i\n",i[2]);
}

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

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.

Example

#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.