ZAFL (Zipr-based AFL)
Welcome to ZAFL, a project to fuzz binary programs directly. Salient features of ZAFL are:
- no source code required. ZAFL lets you fuzz a binary even if you don't have the source code. Even when you have the source code, the build system can be so convoluted that it is easier to work with binaries directly.
AFL compatibility. ZAFL inlines the instrumentation that AFL expects directly into the target binary. Thus, ZAFL leverages the AFL ecosystem and lets you use standard AFL tools such as
- speed. ZAFL is fast as it uses efficient static binary rewriting techniques.
- X86 64-bit on Linux is robust, support for other architectures/platforms coming soon.
ZAFL demonstration video
A picture is worth a 1000 words. A video is worth a 1000 pictures? Here's a short video of ZAFL demonstrating its ease-of-use and application in a DevOps pipeline.
Please see our current licensing terms. Our plan is to open-source ZAFL and its underlying infrastructure. If the current license does not fit your need, please contact us (contact: email@example.com). Our goal is to get ZAFL in use by the community and we will be glad to work with you.
Prepping your system
The following set of instructions will step you through using ZAFL on a to prep a binary for fuzzing, as well as running the prepped binary under the control of the standard AFL fuzzer.
We regularly test ZAFL on the following platforms:
Ubuntu 16.04 and
Setting up Docker on your system is likely the trickiest part of the installation procedure. We suggest you install Docker first before proceeding.
Once you've installed Docker, make sure you can run basic
hello-world without any errors:
docker run hello-world
Installing AFL on your system
First, install the AFL fuzzer on your system.
# for Ubuntu sudo apt-get install afl
If there is no package available, or if you want to get the latest AFL release, you can download AFL and follow installation procedure to build from source.
After you have installed AFL, type the following cmd:
and make sure to see AFL's help screen.
Installing ZAFL support libraries
For CentOS or Red Hat, you can install the support libraries from source. For Debian-based systems, e.g. Ubuntu, you can download our latest Debian package:
Then install it (you will need to have sudo privilege on your system):
sudo dpkg -i libzafl_latest_amd64.deb
If all goes well, you should have
/usr/lib. To verify:
ls /usr/lib/*zafl* The output should be: /usr/lib/libautozafl.so /usr/lib/libzafl.so
Transforming a binary with ZAFL
After installing dependencies, we are ready to transform a binary for fuzzing. For convenience, we have setup a public Docker image that takes as input a binary and produces as output the same binary augmented with the required AFL-compatible instrumentation.
As an illustrative example, we will prep the Unix calculator utility
bc for fuzzing.
# copy bc into /tmp cp $(which bc) /tmp cd /tmp # map the host's /tmp directory into the docker image's /io directory, # thus /tmp/bc corresponds to /io/bc inside of the Docker container # The output binary produced inside the container, /io/bc.zafl, maps to /tmp/bc.zafl on your local system docker run -v /tmp:/io -t git.zephyr-software.com:4567/opensrc/libzafl/zafl:latest /io/bc /io/bc.zafl
You should see output of the form:
This docker container is made available to the public by Zephyr Software (contact: firstname.lastname@example.org) under the Creative Commons Attribution- NonCommercial 4.0 International license (CC BY-NC 4.0). https://creativecommons.org/licenses/by-nc/4.0/legalcode Linux, Gcc, and other relevant open source projects are licensed under their own license and are exempt from this license statement. Zafl: main exec is PIE... use entry point address (0x27a0) for fork server Zafl: Transforming input binary /io/bc into /io/bc.zafl Zafl: Issuing command: /opt/ps_zipr/tools/ps_zipr.sh /io/bc /io/bc.zafl -c rida -s move_globals -c zax -o move_globals:--elftables-only -o move_globals:--no-use-stars -o zax:--stars -o zax:--enable-floating-instrumentation -o zax:'-e 0x27a0' Using Zipr backend. Detected ELF shared object. Performing step rida [dependencies=mandatory] ...Done. Successful. Performing step pdb_register [dependencies=mandatory] ...Done. Successful. Performing step fill_in_cfg [dependencies=unknown] ...Done. Successful. Performing step fill_in_indtargs [dependencies=unknown] ...Done. Successful. Performing step fix_calls [dependencies=unknown] ...Done. Successful. Performing step move_globals [dependencies=unknown] ...Done. Successful. Performing step zax [dependencies=none] ...Done. Successful. Performing step zipr [dependencies=none] ...Done. Successful. Zafl: success. Output file is: /io/bc.zafl BY USING THIS DOCKER IMAGE, YOU AGREE TO BE BOUND BY THE CREATIVE COMMONS ATTRIBUTION-NONCOMMERCIAL 4.0 INTERNATIONAL LICENSE
The output binary,
bc.zafl, should now have been created in
Let's verify that it works.
bc.zafl has been instrumented and ready to be used with the AFL fuzzer, it can still be used normally. To test:
echo "2 + 2" | ./bc.zafl
and you should see
4 as the answer.
Fuzzing ZAFL-processed binaries with AFL
We are now ready to fuzz the calculator utility program using AFL. Note that we assume that you are already familiar with AFL. If not, please refer to the AFL documentation.
We must first setup the following environment variables:
Let's create a seed directory with an input seed file:
mkdir seed_inputs echo "2 * 3" > seed_inputs/simple.seed
We are now ready to run afl:
afl-fuzz -i seed_inputs -o output_dir -- ./bc.zafl
If all goes well, you should see the AFL dashboard on your screen.
If you do not see the AFL dashboard, please see Troubleshooting.
A special thank you to Michal Zalewski for unleashing AFL to the world, thereby making fuzzing easily available to all. Thanks to Google for supporting Michal and continuing to make AFL widely available.
Special thanks to our government sponsors for supporting our work over the years.