A quick and dirty guide to "Fuzzing with AFL for fun and maybe a little profit"

Step 1: The Setup

Whether you're doing this for fun, as a new hobby or in the course of your job duties, getting started with AFL is easier than you think.

First, you're going to need a Linux machine. For simplicity's sake, we'll use a $5 VPS from DigitalOcean or Vultr. Both are fine choices for what we're about to embark on, but if you've already got a local Linux machine or a VM setup, you're ahead of the curve.

Note: You may see me running as root in some screenshots, don't fuzz as root.

For this guide we'll be using Debian, so first let's ensure the system is up to date:
apt-get update && apt-get upgrade

Next, we'll install a few necessities:
apt-get install build-essential git gdb autotools-dev automake libtool texinfo

And we'll need the latest version of AFL:
wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz

Extract that with a quick tar zxf afl-latest.tgz and then cd afl-2.41b.

From there we'll run make clean all to build the afl-gcc and afl-g++ wrappers and optionally sudo make install if you want to install AFL.

Step 2: Pre-fuzzing software compilation

Now comes time to pick a target, and for this quick tutorial I'm going to choose something easy: GNU binutils. I say easy, but binutils can be a pain in the ass to compile, so hopefully by following my instructions I will save you some of that pain. (;

Grab binutils using git:
cd ~ && git clone git://sourceware.org/git/binutils-gdb.git binutils && cd binutils

Build binutils using the wrappers we built in step 1:
CC=afl-gcc CXX=afl-g++ AFL_USE_ASAN=1 LDFLAGS="-ldl" ./configure

Without setting LDFLAGS="-ldl" the compilation may fail with an error like undefined reference to symbol 'dlsym@@GLIBC_2.0' which required some Google-fu to solve. Easy peasy thanks to Stack Overflow! (;

If there are no errors, type AFL_USE_ASAN=1 LDFLAGS="-ldl" make and it will start compiling:

It might take a minute to compile so be patient. Once it is done, we can start fuzzing and hopefully find a bug.

Step 3: Fuzzing your target

Now that we have all of the important stuff out of the way, let's fire up AFL and see how many bugs we can find. binutils probably isn't the best choice because a lot of people fuzz it, but for this tutorial it will do just fine. Since you're already in ~/binutils, go ahead and cd binutils and look for a target using find . -maxdepth 1 -perm -111 -type f and you might get output that looks like this:

readelf is a good target because it reads ELF format files and displays information about them (and AFL comes with a sample ELF file for fuzzing). Here is what normal readelf output looks like with a normal ELF format file:

Lots of information we really don't care about in the long run, but still nice to know what "normal" looks like. To start fuzzing this target, we're going to use the following commands:

cd ~/binutils/binutils && mkdir tmp && cd tmp

afl-fuzz -m none -i ~/afl-2.41b/testcases/others/elf -o output_dir ../readelf -a @@

Note: -m none instructs AFL to not set a memory limit, which is essential when dealing with ASAN.

Once you've done that, you'll be presented with the following AFL status screen and you're now successfully fuzzing an open source application.

Stay tuned for follow-up articles where we look at triaging crashes, llvm mode and more!

Step 4: Profit!!!111

I hope you enjoyed this quick and dirty guide to fuzzing with AFL. As always, you can support me on Patreon, via PayPal, Bitcoin 1HnyFwSJDjWFexD7oRr4HGTFwD8N6NsrfX or Ethereum 0xee9cBCB8DDC4f25832AD7FC02FADB981b1212D04.

========

A million thanks to @lcamtuf for providing such a great tool to the infosec community.

Geeknik Labs

Also on this blog

SHARE:  Email · Facebook · Google · Twitter · Tumblr · Kindle
SUBSCRIBE:  Receive an email on new posts from Geeknik Labs

Comments

hello, exec speed : 2.01/sec (zzzz...) is normal? how do i specify how many cores?
2017-04-18, johnathon

That is pretty slow. AFL uses 1 core per instance, so if you have a dual core machine, you can try and advanced setup like this:
terminal 1: afl-fuzz -m none -M master -i input -o output ./program @@
terminal 2: afl-fuzz -m none -S slave -i input -o output ./program @@
For this tutorial fuzzing binutils, I was seeing between 80 and 100 execs/second on a cheap $5 VPS (1 vCPU).
2017-04-18, Geeknik Labs


  • Notify me upon new comments

☺ Got it