Skip to content
Snippets Groups Projects
README.md 7.22 KiB
Newer Older
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
# Zafl (Zipr-based AFL)

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Welcome to *Zafl*, a project to fuzz X86 64-bit binary programs. 

Key features of Zafl:
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
* Uses Zipr, a fast, space-efficient binary rewriter to inline AFL-style instrumentations. Preliminary overhead: 
    * 20% slower than afl/source code
    * 15% faster than afl/dyninst
    * a **lot** faster than afl/QEMU
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
* Platform for experimenting with other instrumentation to guide afl, e.g., add calling context to the edge-profile function (a la Angora)
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed

## Installation
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Note that you will need **sudo** privileges to get and install all the required packages.
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed

### Getting packages and compiling Zafl
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
git clone --recurse-submodules git@git.zephyr-software.com:allnp/zafl_umbrella.git
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
cd zafl_umbrella
. set_env_vars
./get-packages.sh
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
./build-all.sh
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
### Setting up local postgres tables
Next we need to setup the proper tables in a local copy of the postgres database (email admin for instructions if you want to use a remote Postgres database). 
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
cd $ZAFL_HOME/zipr_umbrella
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
./postgres_setup.sh
```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
If all goes well with the postgres setup, you should be able to login into the database by typing: ```psql``` 
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
The output of psql should look something like this:
```
psql (9.3.22)
SSL connection (cipher: DHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
peasoup_XXX=> 
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
## Testing Zafl

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Before running Zafl, always make sure to have your environment variable set
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
cd <zafl_top_level_directory>   # in this example, the top level dir is: zafl_umbrella
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
. set_env_vars
```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
### Testing Zipr
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Test that the binary rewriting infrastructure by rewriting /bin/ls
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
cd /tmp
$PSZ /bin/ls ls.zipr
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Your terminal's output should look like this:
```
Using Zipr backend.
Detected ELF file.
Performing step gather_libraries [dependencies=mandatory] ...Done. Successful.
Performing step meds_static [dependencies=mandatory] ...Done. Successful.
Performing step pdb_register [dependencies=mandatory] ...Done. Successful.
Performing step fill_in_cfg [dependencies=mandatory] ...Done. Successful.
Performing step fill_in_indtargs [dependencies=mandatory] ...Done. Successful.
Performing step clone [dependencies=mandatory] ...Done. Successful.
Performing step fix_calls [dependencies=mandatory] ...Done. Successful.
Program not detected in signature database.
Performing step zipr [dependencies=clone,fill_in_indtargs,fill_in_cfg,pdb_register] ...Done. Successful.
```

Invoke the rewritten version of /bin/ls and make sure it runs normally: 
```
./ls.zipr
``` 
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
### Testing Zafl
#### Download afl and install it locally
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
wget http://lcamtuf.coredump.cx/afl/releases/afl-latest.tgz
tar -xzvf afl-latest.tgz
cd <afl_dir>
make
# (optional) build qemu support
cd qemu_mode
./build_qemu_support.sh
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
cd /tmp
mkdir in
echo "1" > in/1
afl-fuzz -i in -o out -Q -- /bin/ls @@
```

Alternatively, you may opt to build afl without QEMU support.
In that case, you will need to make sure that afl works for you.

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
You may see afl error messages such as this one that will need to be fixed:
```
afl-fuzz 2.52b by <lcamtuf@google.com>
[+] You have 24 CPU cores and 1 runnable tasks (utilization: 4%).
[+] Try parallel jobs - see docs/parallel_fuzzing.txt.
[*] Checking CPU core loadout...
[+] Found a free CPU core, binding to #0.
[*] Checking core_pattern...

[-] Hmm, your system is configured to send core dump notifications to an
    external utility. This will cause issues: there will be an extended delay
    between stumbling upon a crash and having this information relayed to the
    fuzzer via the standard waitpid() API.

    To avoid having crashes misinterpreted as timeouts, please log in as root
    and temporarily modify /proc/sys/kernel/core_pattern, like so:

    echo core >/proc/sys/kernel/core_pattern

[-] PROGRAM ABORT : Pipe at the beginning of 'core_pattern'
         Location : check_crash_handling(), afl-fuzz.c:7275
```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
or:
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```
[-] Whoops, your system uses on-demand CPU frequency scaling, adjusted
    between 1558 and 2338 MHz. Unfortunately, the scaling algorithm in the
    kernel is imperfect and can miss the short-lived processes spawned by
    afl-fuzz. To keep things moving, run these commands as root:
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
    cd /sys/devices/system/cpu
    echo performance | tee cpu*/cpufreq/scaling_governor

    You can later go back to the original state by replacing 'performance' with
    'ondemand'. If you don't want to change the settings, set AFL_SKIP_CPUFREQ
    to make afl-fuzz skip this check - but expect some performance drop.
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Fix any afl-related errors until you can run:
```afl-fuzz -i in -o out -Q -- /bin/ls @@```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
#### Running Zafl smoke tests
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
cd $ZAFL_HOME/zfuzz/test/bc
./test_bc.sh
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
The test will run afl on bc, instrumented with the proper instrumentation inlined. 
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
The output should end with:
```
execs_since_crash : 77855
exec_timeout      : 20
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
afl_banner        : bc.stars.zafl
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
afl_version       : 2.52b
target_mode       : default
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
command_line      : afl-fuzz -i zafl_in -o zafl_out -- ./bc.stars.zafl -f
TEST PASS: ./bc.stars.zafl: ran zafl binary: execs_per_sec     : 2000.00
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
TEST PASS: all tests passed: zafl instrumentation operational on bc
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
There are also other smoke tests you can run in ```$ZAFL_HOME/zfuzz/test```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
#### Final sanity check
```bash
cd /tmp
zafl.sh /bin/ls ls.zafl
```

**zafl.sh** is the primary script for adding afl instrumentation to binaries. 
You should see:
```
zafl.sh /bin/ls ls.zafl
Zafl: Transforming input binary /bin/ls into ls.zafl
Zafl: Issuing command: /home/zafl_guest/zafl_umbrella/install/zipr_umbrella/peasoup_examples/tools/ps_zipr.sh /bin/ls ls.zafl -c move_globals=on -c zafl=on -o move_globals:--elftables -o zipr:--traceplacement:on -o zipr:true -o zafl:--stars 
Using Zipr backend.
Detected ELF file.
Performing step gather_libraries [dependencies=mandatory] ...Done. Successful.
Performing step meds_static [dependencies=mandatory] ...Done. Successful.
Performing step pdb_register [dependencies=mandatory] ...Done. Successful.
Performing step fill_in_cfg [dependencies=mandatory] ...Done. Successful.
Performing step fill_in_indtargs [dependencies=mandatory] ...Done. Successful.
Performing step clone [dependencies=mandatory] ...Done. Successful.
Performing step fix_calls [dependencies=mandatory] ...Done. Successful.
Program not detected in signature database.
Performing step move_globals [dependencies=none] ...Done. Successful.
Performing step zafl [dependencies=none] ...Done. Successful.
Performing step zipr [dependencies=clone,fill_in_indtargs,fill_in_cfg,pdb_register] ...Done. Successful.
```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
You can run **ls.zafl** as you would **ls**: ```./ls.zafl```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Zafl'd binaries can be run normally. There is no extra output.
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed

To make sure the binary has been instrumented properly: ```ZAFL_DEBUG=1 ./ls.zafl```

The output should start with:
```
Error getting shm environment variable - fake allocate AFL trace map
Error getting shm environment variable - fake allocate AFL trace map
zafl_initAflForkServer(): Bad file descriptor
```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Let's now run the Zafl'd binary with afl:
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
afl-fuzz -i in -o out -- ./ls.zafl @@
```

Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
You can also run the usual afl utilities, e.g:
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```bash
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
afl-showmap -o map.out -- ./ls.zafl
afl-cmin -i out/queue/ -o out.cmin -- ./ls.zafl @@
```
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Et voila!
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
# TL;DR
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
Once everything is installed properly:
Anh Nguyen-Tuong's avatar
Anh Nguyen-Tuong committed
```zafl.sh <target_binary> <zafl_output_binary>```