
EF/CF - Extremely Fast smart Contract Fuzzing
EF/CF is a new approach to smart contract fuzzing: instead of using a new custom built fuzzer, it repurposes existing fuzzing infrastructure of C/C++ code to smart contracts. Currently, AFL++ is the primarily supported fuzzer, although there is some very rudimentary support for libfuzzer and honggfuzz as well.
Why use existing fuzzing infrastructure?
What are some problems that we encounter along the way?
./src/ethmutator/./src/evm2cpp/This repository the primary entry point for the EF/CF project. It contains all
the relevant code as sub-projects in ./src/ and several convenience scripts for
installation, scripts for launching a fuzzing campaigns and various datasets to
test the fuzzer (and compare against other tools).
./src/ - contains all source necessary to build and run EF/CF; for
reproducibility all direct dependencies are added as git submodules../data/ - contains the datasets used during evaluation./scripts - contains scripts to run experiments, installation, etc../docker - Dockerfile for container-based workflow
./docker/tools/ contains dockerfiles for tools that we evaluated EF/CF
against. We tried our best to use fix the versions we evaluated in our
paper in the dockerfiles../EXPERIMENTS.md - contains a guide to
reproduce the experiments from our paper../examples - contains example outputs produced by EF/CFWe describe EF/CF's architecture, implementation, and summarize our evaluation results in our paper: arxiv.org preprint
When referring to EF/CF in academic work please use the following bibtex entry for citation:
@InProceedings{efcf2023,
author = "Michael Rodler and David Paaßen and Wenting Li and Lukas Bernhard and Thorsten Holz and Ghassan Karame and Lucas Davi",
title = "EF/CF: High Performance Smart Contract Fuzzing for Exploit Generation",
booktitle = "{IEEE} European Symposium on Security and Privacy ({EuroS\&P})",
publisher = "{IEEE}",
year = "2023",
}
The recommended way is to run EF/CF as an interactive docker container.
docker run --rm -it ghcr.io/uni-due-syssec/efcf-framework
or build the container from the cloned repository
make gitmodules # to fetch the git submodules
make container-enter
efcfuzz --until-crash --out ./baby_bank_results/ --source ./data/examples/baby_bank.sol
cd /tmp/baby_bank_results/
./r.sh crashes_min/default_id:000000*
No git? if you use a tarball/docker release, ignore this.
Run git submodule update --init to fetch the latest submodule commits on already cloned repositories.
Make sure to run this also in ./src/eEVM.
git submodule update --init; cd src/eEVM/; git submodule update --init; cd ../../
Warning: Running git clone --recursive $repo or passing the --recursive argument to git sumbodule (update|init) will make git recursive into submodules of the AFL++ repository, which are not needed for this project. So to save some space it is better to avoid the recusive submodule checkouts.
We provide the following convenience make targets for container-based workflows:
make container-build # build default efcf container
make container-enter # enter default efcf container in current working dir
If you want to ensure a clean build, you can use the following command
make container-build CLEAN_CHECKOUT=1
Alternatively the container can be built with the following docker command:
docker build \
-f docker/ubuntu.Dockerfile \
-t efcf:latest \
.
Note that there is also an Archlinux and Fedora based Dockerfile. They should work as well, but are not as well tested.
For manually distributing a docker image (e.g., if including some local changes), use:
make container-release
docker load -i ./efcf*.tar
We recommend the following docker options for launching:
--security-opt seccomp=unconfined - better fuzzing perf--net=host - for easy access to a local ethereum node--tmpfs "/tmp/efcf/":exec,size=6g - put EF/CF's temporary files onto a ramdisk if possible (less disk wear)--privileged - to run afl-system-config or efcfuzz --configure-system-v - to persist the output data of EF/CFFor VM or bare-metal-based workflows:
make system-install # install efcf to current system (requires root or sudo rights)
Note that a lot of the scripts work on the relative directory layout anyway, so
this mostly installs dependencies and some tools that are handy to have in your
PATH. We have tested running EF/CF on the following Linux distributions:
(Distro does not matter that much, we tested LLVM 13 and 14 with 14 being the
preferred choice. LLVM 11 or 12 might also still work, but as always - the newer the
better. The important part is that there is a LLVM that is compatible with our fork of AFL++.)
We have not tested EF/CF on Mac OS natively. Likely things won't work (e.g., afl-clang-lto on Mac OS seems to not work). The best option is to utilize docker.
# make sure that the submodules are initialized
make gitmodules
# pull the linux/amd64 base image
docker pull ubuntu:jammy --platform linux/amd64
# build the ef/cf image
docker build -t efcf:latest -f docker/ubuntu.Dockerfile --platform linux/amd64 .
# launch the EF/CF container
docker run --tmpfs "/tmp/efcf/":exec,size=8g --platform linux/amd64 --rm -it -v $(pwd):$(pwd) -w $(pwd) efcf:latest
We tested using docker desktop v4.21.1 and basic EF/CF usage works. However, consider the following:
The tools generally do not need to be installed. Install the required
dependencies as in the system-install.sh script or as in the Dockerfiles.
For convenience we have some scripts to update your PATH:
# POSIX-like shells (i.e., bash, ...)
source ./scripts/env.sh
# for the fish shell
source ./scripts/env.fish