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.