mirror of
https://github.com/ntop/ntopng.git
synced 2026-04-28 23:19:33 +00:00
203 lines
No EOL
6.2 KiB
Markdown
203 lines
No EOL
6.2 KiB
Markdown
# Fuzzing targets
|
|
|
|
The targets are meant to be run by google oss-fuzz however you can test it locally by
|
|
configuring all the required flags.
|
|
|
|
## How to build
|
|
|
|
In order to build all the targets you need to do the following:
|
|
- Enable the fuzzing targets either with `--enable-fuzztargets` or `--enable--fuzztargets-local`
|
|
- Pass to the C++ preprocessor the flag `FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION`
|
|
- Use the makefile target `fuzz_all`
|
|
|
|
### Steps
|
|
|
|
1. Run autoconf with
|
|
|
|
```shell
|
|
./autogen.sh
|
|
```
|
|
|
|
2. Run the configure scripts enabling the fuzzing targets (look at [Flags](#flags) for more details)
|
|
|
|
```shell
|
|
CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" ./configure --enable-fuzztargets-local
|
|
```
|
|
|
|
3. Build the `fuzz_all` target
|
|
|
|
```shell
|
|
make -j$(nproc) fuzz_all
|
|
```
|
|
|
|
### Flags
|
|
|
|
These are all the flags that can be passed to the C/C++ compiler:
|
|
- [REQUIRED] **FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION**
|
|
- **IS_AFL**: Used only for local testing when using AFL++. It adds the `main` function that calls
|
|
`LLVMFuzzerTestOneInput`. Note that it is not needed when fuzzing on ClusterFuzz.
|
|
|
|
These are all the env variables that can be passed to the configuration script:
|
|
- **LIB_FUZZING_ENGINE**: the flag used by the fuzzing engine (afl, libfuzzer, ...)
|
|
|
|
Additionally there are some options that can be passed to `./configure`
|
|
- **--enable-fuzztargets**: Enable all the fuzzing targets. It is used in the ClusterFuzz environment
|
|
- **--enable-fuzztargets-local**: Enable all the fuzzing targets, used for local testing.
|
|
This will define a function `main(int, char **)` making it incompatible with libfuzzer.
|
|
This is useful in conjuction with `-DIS_AFL` for fuzzing with AFL++ or to build in
|
|
debug mode with no fuzzzing engine.
|
|
- **--with-fuzz-protobuf**: Use libprotobuf-mutator. Right now it is compatible only with libfuzzer
|
|
|
|
Additional sanitizers can be enabled by passing the specific flags in `CFLAGS` and `CXXFLAGS`
|
|
|
|
## Runtime configuration
|
|
|
|
Some of the fuzzing targets require a particular directory structure to run correctly.
|
|
In order to satisfy all the targets it is strongly suggested to create the following
|
|
directories in the same path where the targets are launched:
|
|
|
|
- `install`
|
|
- `data-dir`
|
|
- `docs`
|
|
- `scripts`
|
|
- `scripts/callbacks`
|
|
|
|
# Examples
|
|
|
|
## Building examples
|
|
|
|
You can build the fuzzing targets with different combinations of fuzzing engines (libfuzzer,
|
|
AFL++, honggfuzz, ...) and sanitizers (address, undefined, memory).
|
|
Here you can find some examples on how to build and run some of them.
|
|
|
|
**Remember** to run all the commands from the project root directory
|
|
|
|
**IMPORTANT:** If the project has been compiled before, it might be useful to first execute `make clean`
|
|
|
|
### Building with Libfuzzer
|
|
|
|
```shell
|
|
./autogen.sh
|
|
|
|
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
|
|
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=fuzzer-no-link" \
|
|
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=fuzzer-no-link" \
|
|
LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
|
|
NDPI_HOME=/path/to/nDPI \
|
|
./configure --enable-fuzztargets
|
|
|
|
make -j$(nproc) fuzz_all
|
|
```
|
|
|
|
### Building with Libfuzzer + address sanitizer
|
|
|
|
```shell
|
|
./autogen.sh
|
|
|
|
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
|
|
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
|
|
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
|
|
LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
|
|
NDPI_HOME=/path/to/nDPI \
|
|
./configure --enable-fuzztargets
|
|
|
|
make -j$(nproc) fuzz_all
|
|
```
|
|
|
|
### Building with Libfuzzer + libprotobuf-mutator + address sanitizer
|
|
|
|
```shell
|
|
./autogen.sh
|
|
|
|
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
|
|
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
|
|
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link" \
|
|
LIB_FUZZING_ENGINE="-fsanitize=fuzzer" \
|
|
NDPI_HOME=/path/to/nDPI \
|
|
./configure --enable-fuzztargets --with-fuzz-protobuf
|
|
|
|
make -j$(nproc) fuzz_all
|
|
```
|
|
|
|
### Building with AFL++
|
|
```shell
|
|
./autogen.sh
|
|
|
|
CC=afl-clang-fast CXX=afl-clang-fast++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -DIS_AFL" \
|
|
CFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only" \
|
|
CXXFLAGS="-O1 -fno-omit-frame-pointer -gline-tables-only -stdlib=libc++" \
|
|
NDPI_HOME=/path/to/nDPI \
|
|
./configure --enable-fuzztargets-local
|
|
|
|
make -j$(nproc) fuzz_all
|
|
```
|
|
|
|
### Debug build with no fuzzer
|
|
|
|
This is useful to debug a single test case.
|
|
**Note** that the code is not instrumented for fuzzing.
|
|
|
|
```shell
|
|
./autogen.sh
|
|
|
|
CC=clang CXX=clang++ CPPFLAGS="-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" \
|
|
CFLAGS="-O0 -fno-omit-frame-pointer -g" \
|
|
CXXFLAGS="-O0 -fno-omit-frame-pointer -g -stdlib=libc++" \
|
|
NDPI_HOME=/path/to/nDPI \
|
|
./configure --enable-fuzztargets-local
|
|
|
|
make -j$(nproc) fuzz_all
|
|
```
|
|
|
|
|
|
## Setting up a fuzzing instance
|
|
|
|
Once you have built the fuzzing targets you have to properly set up an environment.
|
|
Some specific commands might vary depending on the fuzzing engine used in the building process.
|
|
|
|
First we create a directory in which we place the fuzzing targets, the dictionaries and
|
|
the corpus. Then we set up the required directory structure
|
|
|
|
```shell
|
|
mkdir fuzzcampaign
|
|
|
|
# Copy fuzzers
|
|
find fuzz/ -regex 'fuzz/fuzz_[a-z_]*' -exec cp {} fuzzcampaign/ \;
|
|
|
|
# Copy dictionaries
|
|
cp fuzz/*.dict fuzzcampaign/
|
|
|
|
# Copy corpus
|
|
cp fuzz/*.zip fuzzcampaign/
|
|
|
|
# Create the directory structure needed for fuzzing
|
|
mkdir -p fuzzcampaign/install fuzzcampaign/data-dir fuzzcampaign/docs fuzzcampaign/scripts/callbacks
|
|
```
|
|
|
|
Then we can start to fuzz
|
|
|
|
### For libfuzzer
|
|
|
|
```shell
|
|
cd fuzzcampaign
|
|
|
|
# Extract the corpus specific for the fuzzing target
|
|
mkdir input
|
|
unzip fuzz_dissect_packet_seed_corpus.zip -d input/
|
|
|
|
# Run the fuzzer
|
|
./fuzz_dissect_packet -timeout=25 input/ -dict=fuzz_dissect_packet.dict
|
|
```
|
|
|
|
### For AFL++
|
|
|
|
```shell
|
|
cd fuzzcampaign
|
|
|
|
# Extract the corpus specific for the fuzzing target
|
|
mkdir input
|
|
unzip fuzz_dissect_packet_seed_corpus.zip -d input/
|
|
|
|
# Run the fuzzer
|
|
afl-fuzz -t 2000 -i input -o afl-out -- ./fuzz_dissect_packet
|
|
``` |