AFLNet: A Greybox Fuzzer for Network Protocols (https://thuanpv.github.io/publications/AFLNet_ICST20.pdf)
AFLNet: A Greybox Fuzzer for Network Protocols (https://thuanpv.github.io/publications/AFLNet_ICST20.pdf)
AFLNet is a greybox fuzzer for protocol implementations. Unlike existing protocol fuzzers, it takes a mutational approach and uses state-feedback, in addition to code-coverage feedback, to guide the fuzzing process. AFLNet is seeded with a corpus of recorded message exchanges between the server and an actual client. No protocol specification or message grammars are required. It acts as a client and replays variations of the original sequence of messages sent to the server and retains those variations that were effective at increasing the coverage of the code or state space. To identify the server states that are exercised by a message sequence, AFLNet uses the server’s response codes. From this feedback, AFLNet identifies progressive regions in the state space, and systematically steers towards such regions.
AFLNet is licensed under Apache License, Version 2.0.
AFLNet is an extension of American Fuzzy Lop written and maintained by Michał Zalewski >. For details on American Fuzzy Lop, we refer to README-AFL.md.
AFLNet has been accepted for publication as a Testing Tool paper at the IEEE International Conference on Software Testing, Verification and Validation (ICST) 2020.
@inproceedings{AFLNet,
author={Van{-}Thuan Pham and Marcel B{\"o}hme and Abhik Roychoudhury},
title={AFLNet: A Greybox Fuzzer for Network Protocols},
booktitle={Proceedings of the 13rd IEEE International Conference on Software Testing, Verification and Validation : Testing Tools Track},
year={2020},}# Install clang (as required by AFL/AFLNet to enable llvm_mode)
sudo apt-get install clang
# Install graphviz development
sudo apt-get install graphviz-dev libcap-devDownload AFLNet and compile it. We have tested AFLNet on Ubuntu 18.04 and Ubuntu 16.04 64-bit and it would also work on all environments that support the vanilla AFL and graphviz.
# First, clone this AFLNet repository to a folder named aflnet
git clone aflnet
# Then move to the source code folder
cd aflnet
make clean all
cd llvm_mode
# The following make command may not work if llvm-config cannot be found
# To fix this issue, just set the LLVM_CONFIG env. variable to the specific llvm-config version on your machine
# On Ubuntu 18.04, it could be llvm-config-6.0 if you have installed clang using apt-get
make
# Move to AFLNet's parent folder
cd ../..
export AFLNET=$(pwd)/aflnet
export WORKDIR=$(pwd)export PATH=$PATH:$AFLNET
export AFL_PATH=$AFLNETAFLNet adds the following options to AFL. Run afl-fuzz --help to see all options. Please also see the FAQs section for common questions about these AFLNet's options.
-N netinfo: server information (e.g., tcp://127.0.0.1/8554)
-P protocol: application protocol to be tested (e.g., RTSP, FTP, DTLS12, DNS, DICOM, SMTP, SSH, TLS, DAAP-HTTP, SIP)
-D usec: (optional) waiting time (in microseconds) for the server to complete its initialization
-e netnsname: (optional) network namespace name to run the server in
-K : (optional) send SIGTERM signal to gracefully terminate the server after consuming all request messages
-E : (optional) enable state aware mode
-R : (optional) enable region-level mutation operators
-F : (optional) enable false negative reduction mode
-c script : (optional) name or full path to a script for server cleanup
-q algo: (optional) state selection algorithm (e.g., 1. RANDOM_SELECTION, 2. ROUND_ROBIN, 3. FAVOR)
-s algo: (optional) seed selection algorithm (e.g., 1. RANDOM_SELECTION, 2. ROUND_ROBIN, 3. FAVOR)
Example command:
afl-fuzz -d -i in -o out -N -x -P -D 10000 -q 3 -s 3 -E -K -R Live555 Streaming Media is a C++ library for multimedia streaming. The library supports open protocols such as RTP/RTCP and RTSP for streaming. It is used internally by widely-used media players such as VLC and MPlayer and some security cameras & network video recorders (e.g., DLink D-View Cameras, Senstar Symphony, WISENET Video Recorder). In this example, we show how AFLNet can be used to fuzz Live555 and discover bugs in its RTSP server reference implementation (testOnDemandRTSPServer). Similar steps would be followed to fuzz servers implementing other protocols (e.g., FTP, SMTP, SSH).
If you want to run some experiments quickly, please take a look at ProFuzzBench. ProFuzzBench includes a suite of representative open-source network servers for popular protocols (e.g., TLS, SSH, SMTP, FTP, SIP), and tools to automate experimentation.
The newest source code of Live555 can be downloaded as a tarball at Live555 public page. There is also a mirror of the library on GitHub. In this example, we choose to fuzz an old version of Live555 which was commited to the repository on August 28th, 2018. While fuzzing this specific version of Live555, AFLNet exposed four vulnerabilites in Live555, two of which were zero-day. To compile and setup Live555, please use the following commands.
cd $WORKDIR
# Clone live555 repository
git clone https://github.com/rgaufman/live555.git
# Move to the folder
cd live555
# Checkout the buggy version of Live555
git checkout ceeb4f4
# Apply a patch. See the detailed explanation for the patch below
patch -p1 TCP Stream.
Wireshark will then display all requests and responses in plain text.
As we are only interested in the requests for our purpose, we choose incoming traffic to the SUT-opened port by selecting an option from the bottom-left drop-down list. We choose ```127.0.0.1:57998->127.0.0.1:8554…
200``` for all successful client requests, no matter what actual server state is. So to make fuzzing more effective, we can apply [this simple patch](tutorials/live555/ceeb4f4_states_decomposed.patch) that decomposes the big state 200 into smaller states. It makes the inferred state machine more fine grained and hence AFLNet has more information to guide the state space exploration.
## Step-3. Fuzzing
```bash
cd $WORKDIR/live555/testProgs
afl-fuzz -d -i $AFLNET/tutorials/live555/in-rtsp -o out-live555 -N tcp://127.0.0.1/8554 -x $AFLNET/tutorials/live555/rtsp.dict -P RTSP -D 10000 -q 3 -s 3 -E -K -R ./testOnDemandRTSPServer 8554Once AFLNet discovers a bug (e.g., a crash or a hang), a test case containing the message sequence that triggers the bug will be stored in replayable-crashes or replayable-hangs folder. In the fuzzing process, AFLNet State Machine Learning component keeps inferring the implmented state machine of the SUT and a .dot file (ipsm.dot) is updated accordingly so that the user can view that file (using a .dot viewer like xdot) to monitor the current progress of AFLNet in terms of protocol inferencing. Please read the AFLNet paper for more information.
AFLNet has an utility (aflnet-replay) which can replay message sequences stored in crash and hang-triggering files (in replayable-crashes and replayable-hangs folders). Each file is structured in such a way that aflnet-replay can extract messages based on their size. aflnet-replay takes three parameters which are 1) the path to the test case generated by AFLNet, 2) the network protocol under test, and 3) the server port number. The following commands reproduce a PoC for CVE-2019-7314.
cd $WORKDIR/live555/testProgs
# Start the server
./testOnDemandRTSPServer 8554
# Run aflnet-replay
aflnet-replay $AFLNET/tutorials/live555/CVE_2019_7314.poc RTSP 8554
…
extract_requests_*``` and ```extract_response_codes_*``` functions as references. These functions should be declared and implemented in [aflnet.h](aflnet.h) and [aflnet.c](aflnet.c), respectively. Note that, please use the same function parameters.
#### Step-2. Update main function to support a new protocol
Please update the code that handles the ```-P``` option in the main function to support a new protocol.
### 1.2. How do I implement another search strategy?
It is quite straightforward. You just need to update the two functions ```choose_target_state``` and ```choose_seed```. The function ```update_scores_and_select_next_state``` may need an extension too.
## 2. What happens if I don't enable the state-aware mode by adding -E option?
If ```-E``` is not enabled, even though AFLNet still manages the requests' boundaries information so it can still follow the sequence diagram of the protocol -- sending a request, waiting for a response and so on, which is not supported by normal networked-enabled AFL. However, in this setup AFLNet will ignore the responses and it does not construct the state machine from the response codes. As a result, AFLNet cannot use the state machine to guide the exploration.
## 3. When I need -c option and what I should write in the cleanup script?
You may need to provide this option to keep network fuzzing more deterministic. For example, when you fuzz a FTP server you need to clear all the files/folders created in the previous fuzzing iteration in the shared folder because if you do not do so, the server will not be able to create a file if it exists. It means that the FTP server will work differently when it receives the same sequence of requests from the client, which is AFLNet in this fuzzing setup. So basically the script should include commands to clean the environment affecting the behaviors of the server and give the server a clean environment to start.
## 4. What is false-negative reduction mode and when I should enable it using -F?
Unlike stateless programs (e.g., image processing libraries like LibPNG), several stateful servers (e.g., the RTSP server in the above tutorial) do not terminate themselves after consuming all requests from the client, which is AFLNet in this fuzzing setup. So AFLNet needs to gracefully terminate the server by sending the SIGTERM signal (when -K is specified). Otherwise, AFLNet will detect normal server executions as hangs. However, the issue is that if AFLNet sends SIGTERM signal too early, say right after all request messages have been sent to the server, the server may be forced to terminate when it is still doing some tasks which may lead to server crashes (i.e., false negatives -- the server crashes are missed). The false-negative reduction mode is designed to handle such situations. However, it could slow down the fuzzing process leading to slower execution speed.No open issues yet, or sync has not completed.