___ ___ ___
/\__\ /\ \ /\ \
/:/ _/_ /::\ \ ___ |::\ \
/:/ /\__\ /:/\:\ \ /\__\ |:|:\ \
/:/ /:/ / /:/ /::\ \ /:/ / __|:|\:\ \
/:/_/:/ / /:/_/:/\:\__\ /:/__/ /::::|_\:\__\
\:\/:/ / \:\/:/ \/__/ /::\ \ \:\~~\ \/__/
\::/__/ \::/__/ /:/\:\ \ \:\ \
\:\ \ \:\ \ \/__\:\ \ \:\ \
\:\__\ \:\__\ \:\__\ \:\__\
\/__/ \/__/ \/__/ \/__/
Fuzz Against The Machine
Fuzz-Against-The-Machine is a simple fuzzer for the MQTT protocol. It is written in Python3 and relies on Scapy to build MQTT control packets.
This fuzzer utilizes a generation based approach for creating the fuzz. The following MQTT control packets are supported:
CONNECT
CONNACK
SUBSCRIBE
PUBLISH
PUBACK
PUBREC
PUBREL
PUBCOMP
The fuzzing functionality starts by typing 1
in the main menu or by using the flag --sequence
.
The project contains a file with inputs which are known to cause issues or anomalies in programs. The inputs are ready to use, but can also be altered to fit your needs.
The fuzzer takes the input line by line and inserts it into the specific MQTT control packet fields. For covering all combinations of control packet fields a superset is created. This results in 2^n sent packets per control packet for every input, where n is the number of fields in the MQTT control packet. Additionaly every superset element is sent with one byte cut off at the end until the remaining length is one. Finally for every superset element some bytes are flipped randomly before sending the packet.
For CONNECT
, PUBLISH
and SUBSCRIBE
packets it is possible to predefine fields with custom values by entering them in the specific template file. This enables the user to specify field values that are neccessary to reach inner program logic. One poosible example is the protoname field in the CONNECT
packet which must be "MQTT" to generate a valid packet.
The supported MQTT version is 5. The template mode is an additional feature to send single, predefinded packets. The packets are generated by reading the template file for the specific packet type. Templates can be changed at runtime. The Packet Configurer starts by entering 2 in the main menu.
It is recommended to use an addional monitoring tool for detecting problems like memory leaks or buffer overflows, which do not immediately result in crashes. For C and C++ based brokers the use of ASAN or Valgrind would be a possible choice.
The following make command can be used to build the sources with ASAN support:
make CFLAGS=-fsanitize=address LDFLAGS=-fsanitize=address WITH_DOCS=no
The public interface of LeakSanitizer (sanitizer/lsan_interface.h) offers various functions for real time leak detection:
__lsan_do_leak_check()
__lsan_do_recoverable_leak_check()
Fuzz-Against-The-Machine requires the installation of some python modules i n specific versions. To avoid conflicts with existing installations, create a virtual environment to install them:
virtualenv venv
source venv/bin/activate
pip3 install -r requirements.txt
You may need to install virtualenv first by running
pip3 install virtualenv
You need to at least specify the target using the -t
or --target
switch. By default, the fuzzer is in guided mode, guiding you through the setup. Additional options are listed below:
usage: fatm.py [-h] [--guided | --sequence | --template | --resend] [-i INPUT] -t TARGET [-p PACKETTYPES] [-l LOGFILE]
optional arguments:
-h, --help show this help message and exit
mode selection:
--guided Guided fuzzing mode (default)
--sequence Sequential fuzzing mode
--template Template fuzzing mode
--resend Resend logfile mode
options:
-i INPUT, --input INPUT
File with list of fuzzing inputs, separated by newlines
-t TARGET, --target TARGET
Target IP and Port of the broker to fuzz, separated by a colon (e.g. 192.168.2.1:1800)
-p PACKETTYPES, --packettypes PACKETTYPES
Packet types, e.g. for types 1,2,3 and 6, enter 1236. Available types are:
(1) CONNECT, (2) CONNACK, (3) PUBLISH, (4) PUBACK,
(5) PUBREC, (6) PUBREL, (7) PUBCOMP, (8) SUBSCRIBE
-l LOGFILE, --logfile LOGFILE
Logfile to be resent, default file is connect.log
Example usage:
# fuzz in guided mode for target 127.0.0.1 port 1883
sudo python3 fatm.py -t 127.0.0.1:1883
# fuzz in sequences with default wordlist for CONNECT and CONNACK packets
sudo python3 fatm.py -t 127.0.0.1:1883 --sequence -p 12
# fuzz template for SUBSCRIBE packet
sudo python3 fatm.py -t 127.0.0.1:1883 --template -p 8
# resend publish logfile
sudo python3 fatm.py -t 127.0.0.1:1883 --resend -l ./logs/publish.log