This article covers the topic Fuzzing with American Fuzzy Lop (AFL), a powerful fuzzer to find unknown/known vulnerabilities in a software. This should be a good start for any security researchers or a passionate developer who love hunting bugs for fame and profit. There are many other great fuzzers which serves the same purpose and will be introduced in other posts.

In order to discover the vulnerabilities in any software, there are three primary factors to be considered

  • Source Code Audit
  • Reverse Engineering
  • Fuzzing

First two approaches will be covered in next few articles in great detail.

Fuzzing

Fuzzing is a technique that feeds a running program with some random inputs to elicit crashes, errors or the applicate state. The primary goal of fuzzing is to discover bugs in the inspected program, more likely memory related vulnerabilities which are exploitable. Also, other goal is the code coverage, which is an important metric in fuzzing which tells a researcher the amount of code was executed.

Fuzzing a binary with different sets of input helps security researchers discovering in exploitable vulnerabilities which were missed in a manual audit. However, fuzzers also may miss the bugs as it totally depends on the type of fuzzer being used.

Mutation-based fuzzers

fuzzers are quite simple to use as it just mutates existing input randomly. It is not intelligent enough to understand the structure of the data. But still, dumb fuzzing helps to test the robustness of a program by supplying large amount of data.

Generation-based fuzzers

These fuzzers are intelligent enough to generate the inputs on its own by understanding the format, this fuzzer gives better code coverage and code path. However, these fuzzers takes more time when compared to dumb fuzzers as it requires a dedicated compiler, which detects possible code path and generates samples covering subsets of all code paths.

Intro to American Fuzzy Lop (AFL)

AFL is a powerful and open source fuzzer written in C which works on x86 Linux, OpenBSD, FreeBSD, and NetBSD. Also, it supports programs written in C, C++, Objective C, compiled with either gcc or clang. AFL is a little different than other fuzzers, with the power of instrumenting the programs while compilation and analyzing the control flow, it generates malformed data to be supplied. AFL also allows fuzzing the target without source code, which is using ‘qemu_mode’.

So with the help of this fuzzer anyone start hunting bugs in a software. For the illustration, we will be fuzzing latest version of tcpdump i.e 4.9.2 which is an open-source package and takes ‘.pcap’ file as an input. The commands issued here works on Ubuntu or Debian based distros which we assume that you are running.

In few simple steps, one can start fuzzing with AFL against any open-source software and hunt for bugs

  • Install AFL
  • Install target software by compiling AFL compiler
  • Provide a few test cases to train AFL in generating malformed data
  • Create two directories ‘test cases’ and ‘results’ to store the test cases that resulted in unique crashes
  • Fuzz with AFL

AFL Installation

If you are running Ubuntu or Debian, AFL can be installed directly using the command

sudo apt-get install afl

Else, you can install compiling the source code using following commands

wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
tar -xf afl-latest.tgz
cd afl-
make
sudo make install

Compiling Target using AFL compiler

Let’s download the target which is the latest version of tcpdump by following commands, prior to that, we need to install gcc and gdb

sudo apt-get install gcc gdb
sudo apt-get install sqlite3 libsqlite3-dev libpcap-dev
sudo apt-get update
wget http://www.tcpdump.org/release/tcpdump-4.9.2.tar.gz

Extract the downloaded the source code and create two directories ‘testcases’ and ‘result’. The directory ‘testcase’ would have the test cases to be supplied to the fuzzer and the directory ‘result’ will be storing test cases which cause the crashes or hangs.

tar xzf tcpdump-4.9.2.tar.gz
mkdir testcases result

To fuzz the program we need a set of test cases, however we will consider ‘.pcap’ file as a testcase which was shipped with AFL package. Copy the file to the folder testcase which we have created initially.

cp /usr/share/afl/testcases/others/pcap/small_capture.pcap ~/tcpdump-4.9.2/testcases/

Now we need to compile the source code with AFL compiler which is ‘afl-gcc’

CC=afl-gcc ./configure
make

Before fuzzing the program, we may require switching to root user to arrange the core_pattern. Login as root and type the following command

sudo su
echo core >/proc/sys/kernel/core_pattern
exit

Fuzzing the Target

Now we can start fuzzing our target to find out vulnerabilities by the following command

afl-fuzz -i ~/tcpdump-4.9.2/testcases/ -o ~/tcpdump-4.9.2/result/ ~/tcpdump-4.9.2/tcpdump -nr @@

The above command afl-fuzz is used to run AFL, the actual syntax is as follows

afl-fuzz -i [TESTCASE DIR] -o [RESULT_DIR] [TARGET_BINARY] [BINARY_PARAMS] @@

TESTCASE DIR ~/tcpdump-4.9.2/testcases/
RESULT_DIR ~/tcpdump-4.9.2/result/
TARGET_BINARY ~/tcpdump-4.9.2/tcpdump
BINARY_PARAMS -nr

On running the command, a nice screen with various statistics would be displayed as shown below, which is a really cool feature of AFL

Let the fuzzer run for few hours/days as it generates maximum code execution paths based on the test cases provided (at the time of writing this article, we are fuzzing the target with a specific test case).

We stop fuzzing issuing ‘ctrl+ c’ observing ‘total paths‘ and ‘uniq crashes‘ in the section ‘overall results‘ of AFL statistics screen. We can say whether the fuzzer is discovering new code paths by looking at the value of ‘total paths’. If the total number of paths fuzzed matches our expected number of paths, then we can stop fuzzing the target. We can find the test cases which cause the crash, in the ‘results’ folder which we have created. On navigating to the folder ‘results‘, we observe few folders gets generated

queue – contains test cases for every execution path

crashes – contains test cases which cause the inspected program to crash

hangs – testcases which cause the program to timeout

We strongly recommend

  • Do not run the fuzzer with root access
  • Get a solid environment for the fuzzer, never run the fuzzer on low configured hypervisors
  • Do not run the fuzzer against the any commercial software

Conclusion

Though we have covered how to fuzz with AFL to hunt bugs, we have not covered few other cool features of AFL yet. Hopefully, we will cover rest of those features and concepts in Part 2 of it. Happy Bug Hunting..!

References: http://lcamtuf.coredump.cx/afl/

Must watch: 106 Fuzzing with AFL Adam DC949

Credit: ACE Team – Loginsoft