File: fuzzing.rst

package info (click to toggle)
botan3 3.7.1%2Bdfsg-2
  • links: PTS
  • area: main
  • in suites: trixie
  • size: 49,212 kB
  • sloc: cpp: 178,262; python: 12,847; sh: 506; xml: 181; makefile: 165; lisp: 35
file content (98 lines) | stat: -rw-r--r-- 3,544 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
Fuzzing The Library
============================

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

.. highlight:: shell

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

* https://github.com/randombit/crypto-corpus
* https://github.com/mozilla/nss-fuzzing-corpus
* https://github.com/google/boringssl/tree/master/fuzz
* https://github.com/openssl/openssl/tree/master/fuzz/corpora

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.