Expand description
§⚡ Getting Started
§Installation
§Prerequisites
Install Rust using rustup.
§Clone
Clone the navigator repo.
§Initialise and update the winafl-netspoof submodule
git submodule update --init
§Build navigator and libinject packages
In the Windows machine - run cargo build from the root of the naviator workspace
§Build the inject CMake project
(note at the cmake step the lininject is also built again via cargo build)
For 64-bit builds:
cd inject
mkdir build64
cd build64
cmake -G"Visual Studio 17 2022" -A x64 .. -DDynamoRIO_DIR=C:\Users\shared\dynamorio_prebuilt\cmake
cmake --build . --config ReleaseFor 32-bit builds:
rustup target add i686-pc-windows-msvc
cd inject
mkdir build32
cd build32
cmake -G"Visual Studio 17 2022" -A Win32 .. -DDynamoRIO_DIR=C:\Users\shared\dynamorio_prebuilt\cmake
cmake --build . --config ReleaseNote that default arguments in the CLI depend on the build directories being named as above.
§Build the winafl-netspoof CMake project
For 64-bit builds:
cd winafl-netspoof
mkdir build64
cd build64
cmake -G"Visual Studio 17 2022" -A x64 .. -DDynamoRIO_DIR=C:\Users\shared\dynamorio_prebuilt\cmake
cmake --build . --config ReleaseFor 32-bit builds:
rustup target add i686-pc-windows-msvc
cd winafl-netspoof
mkdir build32
cd build32
cmake -G"Visual Studio 17 2022" -A Win32 .. -DDynamoRIO_DIR=C:\Users\shared\dynamorio_prebuilt\cmake
cmake --build . --config Release§Run navigator
- Go back to root of the navigator repo (workspace)
- Consult –help to compose a cli command to run:
cargo run -- --help- Note that the
--mutator-libpath must be an absolute path!
Example command for MINI/MEGA VMs:
- Only the
--mutator-liboption needs to be edited with a valid path.
cargo run -- --mutator-lib C:\path\to\navigator\winafl-netspoof\build64\bin\Release\mutator.dll --coverage-module prove_fuzzing_capability.exe --target-module prove_fuzzing_capability.exe --nargs 2 --target-path C:\Users\shared\prove_fuzzing_capability.exe --target-opts 192.2.2.2§Running 32-bit on a 64-bit machine
Follow the build instruction for 32-bit builds, then ensure that a suitable 32-bit target is passed to cargo run.
For example:
cargo run --target i686-pc-windows-msvc --release -- --mutator-lib C:\path\to\navigator\winafl-netspoof\build32\bin\Release\mutator.dll --coverage-module prove_fuzzing_capability_32.exe --target-module prove_fuzzing_capability_32.exe --nargs 2 --target-path C:\Users\shared\prove_fuzzing_capability_32.exe --target-opts 192.2.2.2§Usage
§Useful tips
cargo run -- --help for documentation (on the CLI) for the navigator repo
Running make at the root of the repo will build Navigator natively (for your current OS) and it will build libinject for Windows
§Tests
cargo test -p navigator for the navigator package
§Configuring Fuzzing Sessions
When setting the navigator CLI arguments, there are a few considerations related to fuzzing sessions:
§Parallelisation
SaM supports Single-system parallelization offered by WinAFL, in Buffer-mode only. Multi-system parallelization is not yet supported. However this feature would possibly enable parallel fuzzing with SaM in Network-mode (discussed in more detail here).
The --parallel n flag is used to specify n parallel fuzzer instances. Whenever using Buffer-mode it is advisable to set n to around min(8, (num_cpu_cores - 1)) (i.e. either 8 or (num_cpu_cores - 1), whichever is smaller).
As discussed in the WinAFL parallelisation docs:
“Every copy of afl-fuzz will take up one CPU core. This means that on an n-core system, you can almost always run around n concurrent fuzzing jobs with virtually no performance hit.”
When running SaM we have found that if n > 8, then the OS is flooded with resolving OS synchronisation primatives, and other tasks that are dispatched to the single OS kernel.
§Custom mutators
The role of a mutator is to take:
- a candidate input, and
- an “energy” score (which reflects how interesting the coverage information was when the binary was executed with that input)
and return a mutated version of the input, which will be added to the queue of candidate inputs to be used on subsequent executions.
AFLPlusPlus (upon which WinAFL is built) has a whole suite of mutators and a strategy to use different mutators at different times. However, WinAFL exposes the option of defining a custom mutator to be used in conjuction with, or to replace, the existing AFL mutators.
§Using SaM’s fixed-length mutator
SaM provides an implementation for a fixed-length custom mutator that replaces all AFL mutators. This mutator is built by the Rust crate found at winafl-netspoof/mutator. It is built by default when building the winafl-netspoof project (mutator.dll will be found in the winafl-netspoof build directory).
This mutator can be selected with --mutator-lib /absolute/path/to/winafl-netspoof\build64\bin\Release\mutator.dll (note that this path must be an absolute path).
§When to use this fixed-length mutator
If the response bytes being fuzzed are of a known-length, then it is significantly more efficient to only produce fuzzing candidates that are the correct length. The fixed-length mutator implements this, skipping calls to all other AFL mutators so that fuzz candidates are always the same length as the original seed inputs in the fuzzer seed directory.
§Seed inputs
At the start of a fuzzing session, the fuzzer initialises the fuzzing queue with all of the inputs in the afl_inputs directory. SaM manages the creation and population of this driectory, either with random seeds, or the inputs specified with the --seed-data option.
§Coverage collection
Relevant coverage information must be collected for coverage-guided fuzzing to make good progress. Ideally, coverage information should only be collected on the code modules that contain code relevant to the fuzzing task. Collecting coverage on irrelevant modules will add considerable noise to the signal the fuzzer gets about whether a given input was “interesting”.
§Specifying coverage modules
One or several modules from the loaded-module space can be provided over the CLI by including the --coverage-module flag one or several times. For example:
--coverage-module my_bin.exe --coverage-module important_logic.dllSaM prints out the names of all code modules as they load. So a preliminary run of the target binary with SaM can reveal the full set of code modules for consideration.