Fuzzing The Library#

Botan comes with a set of fuzzing endpoints which can be used to test the library.

Fuzzing with libFuzzer#

As of Clang Version 6.0 libFuzzer is automatically included in the compiler. Therefore you don’t need to install any new software. You can build the fuzzers by running

$ ./configure.py --cc=clang --build-fuzzer=libfuzzer --enable-sanitizers=fuzzer
$ make fuzzers

The option –enable-sanitizers=fuzzer compiles the library for coverage-guided fuzzing. You can add additional sanitizers like address, undefined and memory or with/without additional information during building by either adding –unsafe-fuzzer-mode or –with-debug-info. The coverage sanitizer is not compatible with this configuration.

If you want to link additional libraries you can use the –with-fuzzer-lib option while configuring the build with configure.py. The fuzzer binaries will be in build/fuzzer. Simply pick one and run it, optionally also passing a directory containing corpus inputs. Running

$ make fuzzer_corpus

downloads a specific corpus from https://github.com/randombit/crypto-corpus.git. Together with

$ ./src/scripts/test_fuzzers.py fuzzer_corpus build/fuzzer

you can test the Fuzzers.

Fuzzing with AFL++#

Please make sure that you have installed AFL++ according to https://aflplus.plus/building/. The version of Clang should match the version of afl-clang-fast++/ afl-clang-fast. You can fuzz with AFL++ in LLVM mode (https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.llvm.md) by running

$ ./configure.py --cc=clang --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-clang-fast++
$ make fuzzers

For AFL++ in GCC mode make sure that you have afl-g++-fast installed. Otherwise follow https://github.com/AFLplusplus/AFLplusplus/blob/stable/instrumentation/README.gcc_plugin.md to build and install it. You can configure the build by running

$ ./configure.py --cc=gcc --with-sanitizers --build-fuzzer=afl --unsafe-fuzzer-mode --cc-bin=afl-g++-fast
$ make fuzzers

The fuzzer binaries will be in build/fuzzer. To run them you need to run under afl-fuzz:

$ afl-fuzz -i corpus_path -o output_path ./build/fuzzer/binary

Fuzzing with TLS-Attacker#

TLS-Attacker (https://github.com/RUB-NDS/TLS-Attacker) includes a mode for fuzzing TLS servers. A prebuilt copy of TLS-Attacker is available in a git repository:

$ git clone --depth 1 https://github.com/randombit/botan-ci-tools.git

To run it against Botan’s server:

$ ./configure.py --with-sanitizers
$ make botan
$ ./src/scripts/run_tls_attacker.py ./botan ./botan-ci-tools

Output and logs from the fuzzer are placed into /tmp. See the TLS-Attacker documentation for more information about how to use this tool.

Input Corpus#

AFL requires an input corpus, and libFuzzer can certainly make good use of it.

Some other crypto corpus repositories include

Adding new fuzzers#

New fuzzers are created by adding a source file to src/fuzzers which have the signature:

void fuzz(std::span<const uint8_t> in)

After adding your fuzzer, rerun ./configure.py and build.