In this cooperative framework, the fuzzers collaborate using a centralized scheduler.
The project consists of three parts: 1) the cooperative framework, 2) a scheduler, and 3) the drivers for the fuzzers. In this framework, the scheduler selects input seeds to be scheduled on different fuzzers, by communicating this over the fuzzer driver. At the same time the centralized scheduler collects newly generated inputs from the fuzzers, and repeats the loop.
Communication happens over ZeroMQ. The seeds are send with a message consisting of the fuzzer type ID and the seed (which contains the seed input and an optional conditional to be solved).
The scheduler component selects seed inputs from the global queue, evaluates them, and schedules them to the fuzzers.
The fuzzer drivers implement the communcation mechanisms with the centralized scheduler. The communication happens over ZeroMQ.
Th easiest way is to setup the framework using docker.
The setup consists of the following components:
- fuzzer-framework
- fuzzer-{afl,qsy,aflfast,fairfuzz..}-{target}
- fuzzer-generic-driver
- Setup virtualenv
virtualenv --python=python3 venv
source venv/bin/activate
- Build the container docker images (+ install deps):
make all
- Install the
collab_fuzz_xxx
toolscd runners && python setup.py install
- Test run (runs 1 afl instance and collab framework):
mkdir myrun && cd myrun && collab_fuzz_compose -f afl --scheduler=enfuzz -- objdump && docker-compose up
- To run with more fuzzers (2 afl + qsym + fairfuzz + aflfast):
collab_fuzz_runner -f afl afl qsym fairfuzz aflfast --scheduler=enfuzz -- who
Alternatively, to avoid the long building times, you can fetch the docker
images from a remote repo. For example collab_fuzz_build --remote sarek.osterlund.xyz --pull-reqs
to pull all images.
The afl__generic_driver
runs in a container (fuzzer-generic-driver). This container needs to be privileged and mount /var/run/docker.sock
, such that it can control the container of the fuzzer to sync with.
The logs generated by the containers might eat up a lot of space on your
machine. To avoid this, edit your daemon.json
(typically /etc/docker/daemon.json
) to contain something like:
{
"log-level": "error",
"storage-driver": "overlay2",
"log-opts": {
"max-size": "512m"
}
}
At the moment the LAVA-M and GFT builds are broken. Binutils should still work, though.
* ```virtualenv --python=python3 venv```
* ```source venv/bin/activate```
make framework-binutils
Remember the AFL/QSYM prerequisites (needed on every reboot):
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope
cd /sys/devices/system/cpu
echo performance | sudo tee cpu*/cpufreq/scaling_governor
Then build the docker images (we only build AFL for now):
cd docker && make fuzzer-afl
make tools
You might need to install the collab_fuzz_runner tools in the following way:
cd runner && make collab_fuzz_runner
collab_fuzz_build -f afl -t objdump
Or to build all of binutils for all fuzzers:
collab_fuzz_build -s binutils
mkdir tmp_run && cd tmp_run && collab_fuzz_compose -f afl -- objdump
And then try to start the campaign:
docker-compose up --abort-on-container-exit
To clean up the campaign after exiting (i.e., delete the volumes):
docker-compose down -v
CollabFuzz was presented at EuroSec 2021. CollabFuzz: A Framework for Collaborative Fuzzing.
Video: available on YouTube
Bibtex:
@inproceedings{eurosec_collabfuzz_2021,
title = {{CollabFuzz}: {A} {Framework} for {Collaborative} {Fuzzing}},
booktitle = {{EuroSec}},
author = {Österlund, Sebastian and Geretto, Elia and Jemmett, Andrea and Güler, Emre and Görz, Philipp and Holz, Thorsten and Giuffrida, Cristiano and Bos, Herbert},
month = apr,
year = {2021},
}
If you are interested in collaborative fuzzing, also check out our work on how to select the right set of fuzzers to use in a collaborative setting: Cupid: Automatic Fuzzer Selection for Collaborative Fuzzing. Code: https://github.com/RUB-SysSec/cupid