DPIFuzz is a differential fuzzing framework which has been designed with the intent of uncovering DPI Elusion strategies for QUIC. The differential fuzzing framework can be extended to compare various aspects of QUIC server implementations in addition to the demonstrated purpose of uncovering DPI elusion strategies. The fuzzer that powers DPIFuzz can also be run in a non-differential mode to independently test server-side implementations of QUIC as well.
The framework uses the high level QUIC API provided by QUIC-Tracker(a test suite which comprises a minimal Go implementation of QUIC). It is currently draft-27 and TLS-1.3 compatible; however, the highly modular architecture allows it to be readily extended to support all the corresponding versions of QUIC drafts as well.
The corresponding research paper will be published in the 36th Annual Computer Security Applications Conference (ACSAC 2020). If you use DPIFuzz in your paper/project, please do remember to cite this work:
@inproceedings{dpifuzz, author = {Gaganjeet Singh Reen and Christian Rossow}, title = {DPIFuzz: A Differential Fuzzing Framework to Detect DPI Elusion Strategies for QUIC}, year = {2020}, isbn = {978-1-4503-8858-0/20/12}, publisher = {Association for Computing Machinery}, url = {https://doi.org/10.1145/3427228.3427662}, doi = {10.1145/3359789.3359848}, booktitle = {36th Annual Computer Security Applications Conference (ACSAC), 2020}, }
The repository is structured in the following way:
bin/fuzzer/
-- Contains 2 binary files and a text file:fuzzer_runner.go
- This file runs a single instance of a fuzzer against a single host. It initialises the necessary structures required to keep track of one iteration of a fuzzer against a single host.modular_differential_fuzzer.go
- This file is used to execute multiple instances of the fuzzer against multiple hosts and performs a comparative analysis of the results of the fuzzer iterations against different hosts; thereby facilitating differential analysis. It uses a.txt
file to provide the list of hosts against which to run the fuzzer. It can also run multiple instances of the fuzzer against a single host and not perform differntial analysis.hosts.txt
- This file lists the hosts whose behaviour we want to compare with each other. The format of specifying a host is -<host_ip_address:port number>[tab space]<path to request when performing tests that needs data to be sent)>[tab space]<port serving http3 traffic>[tab space]<alpn prefix>
generators/
-- Contains four different generators used to generate sequences of QUIC packets:- Basic Stream Reassembly (
stream_reassembly.go
) - Flow-Control-Aware Stream Reassembly (
flow_control_stream_reassembly.go
) - Overlapping Offset (
overlapping_offset.go
) - Randomised (
randomised.go
)
- Basic Stream Reassembly (
mutators/
-- Contains two types of mutators used to perform mutation on the sequences of packets produced by the generators:- Sequence Level Mutations (
sequence_level.go
) - Mutations for the sequence as a whole - Packet Level Mutations (
packet_level.go
) - Mutations for individual packets in a sequence
- Sequence Level Mutations (
fuzzer/
-- Contains two files:fuzzer.go
- This is the actual fuzzer code which calls the generators and mutators, send the packets to the Implementation Under Test(IUT) and monitors the IUT response. This file is executed byfuzzer_runner.go
inbin/fuzzer/
.structure.go
- This contains the structures required for execution of a fuzzer instance against a host.
When the modular_differential_fuzzer.go script in bin/fuzzer/
is run without specifying any value for the generator flag, it will execute the fuzzer using all the generators against all the hosts specified in a hosts.txt file (for details about command line flags, refer to the section on Execution Commands). In case more than one host is specified, the results of the execution will be a comparison_results.txt
file in bin/fuzzer
. The contents of this file contain entries each of which comprises of:
- Generator Name with which the fuzzer was executed,
- Seed Value used in the execution
- Map containing the name of the IUTs as keys and the list of IUTs their behaviour differs from as values.
The user can extract the entries from this file and use them as input for fuzzer_runner.go
, thereby recreating specific sequences of packets and correspondingly observe the effect on the IUTs in detail.
The trace files generated for each execution of the fuzzer with each client are available in the directory specified with the -trace-directory
command line flag.
Running DPIFuzz as a docker container
Install docker and then do the following:
git clone https://github.com/piano-man/DPIFuzz.git cd DPIFuzz docker build -f Dockerfile -t dpifuzz:lastest . docker container run --network host -it dpifuzz & docker container ls #to get the id of the container docker exec -it <container-id> /bin/sh
NOTE: The docker container is run in the host network mode. As a consequence, the container network is not isolated from the host network thereby allowing communication with servers that might be running on different ports of the host machine using the 127.0.0.1 address in the container. The networking options should be altered depending on the use case.
For a local build
First run these commands
sudo apt-get install -y tcpdump sudo apt-get install -y libpcap-dev sudo apt-get install faketime libscope-guard-perl libtest-tcp-perl sudo apt-get install make sudo apt-get install cmake sudo apt-get install build-essential sudo apt-get install pkg-config sudo apt-get install libssl-dev
Additionally, you should have Go >1.9 and openssl 1.1.1 installed before starting.
Follow this with:
go get -u github.com/QUIC-Tracker/quic-tracker # This will fail because of the missing dependencies that should be build using the 4 lines below cd $GOPATH/src/github.com/mpiraux/pigotls make cd $GOPATH/src/github.com/mpiraux/ls-qpack-go make cd $GOPATH/src/github.com/QUIC-Tracker rm -rf quic-tracker git clone https://github.com/piano-man/DPIFuzz.git mv ./DPIFuzz ./quic-tracker cd $GOPATH/src/github.com/QUIC-Tracker/quic-tracker
Run these commands to list the command line flags that are supported
go run bin/fuzzer/modular_differential_fuzzer.go -h go run bin/fuzzer/fuzzer_runner.go -h
Sample Commands for reference:
- modular_differential_fuzzer.go -
cd bin/fuzzer go run modular_differential_fuzzer.go -hosts hosts.txt -max-instances <integer value> -iterations <integer value> -parallel=<true/false> -generator <stream_reassembly/flow_control_stream_reassembly/overlapping_offset> -debug=<true/false> -trace-directory <directory name where you want to store the trace files> -fuzz 1
NOTE: Please make sure that the trace file directory exists before running the command. When run in the container mode, the trace files will be created under the /tmp directory, irrespective of the value of the trace-directory
command line flag.
- fuzzer_runner.go -
cd bin/fuzzer go run fuzzer_runner.go -host <host IP:port> -generator <stream_reassembly/flow_control_stream_reassembly/overlapping_offset> -debug=<true/false> -alpn <hq/h3> -fuzz 1 -source <seed value>