ThreadFuzzer is a specialized framework designed for fuzzing Thread protocol implementations across virtual and physical nodes.
src/&include/— Core source and header files.common/&third-party/— Shared libraries and external dependencies.scripts/— Utility scripts for automation and visualization.configs/— JSON configurations for fuzzer settings and strategies.crashing_seeds/— Predefined artifacts for crash reproduction.coverage_log/— (Generated) Coverage data from fuzzing sessions.logs/— (Generated) Logs from the fuzzing sessions.bin/ws/— Directory with Wireshark profiles.experiment_logs.tar.gz— Archive with all the experimental results.
Git LFS Requirement: Due to the large size, the
experiment_logs.tar.gzfile uses Git LFS.
Best for testing software-based virtual nodes in an isolated environment.
1. Build the Docker Image
# Adjust BUILD_CORES to match your available CPU resources
sudo docker build -f Dockerfile.virtual --network=host --build-arg BUILD_CORES=4 -t thread_fuzzer_secriot:virtual .Note: The
--build-arg BUILD_CORES=Xparameter allows you to specify the number of CPU cores dedicated to the compilation process during the Docker build.
Note: This build is a marathon, not a sprint—compiling everything can easily take a couple of hours. ☕ Grab a coffee or take a walk, while your CPU does its workout. ThreadFuzzer will be ready when you get back! 🚀🔥
2. Run the Container
sudo docker run --rm -it thread_fuzzer_secriot:virtualRequired for testing commercial Thread devices. This setup requires host Bluetooth and USB access. The credentials for the device can be supplied in phys_main_config.json using the chip_passcode and chip_discriminator flags.
1. Build the Docker Image
sudo docker build -f Dockerfile.full --network=host --build-arg BUILD_CORES=4 -t thread_fuzzer_secriot:full .Note: The
--build-arg BUILD_CORES=Xparameter allows you to specify the number of CPU cores dedicated to the compilation process during the Docker build.
Note: This build is a marathon, not a sprint—compiling everything can easily take a couple of hours. ☕ Grab a coffee or take a walk, while your CPU does its workout. ThreadFuzzer will be ready when you get back! 🚀🔥
2. Host Preparation
- mDNS/Avahi: Disable
mdnsandavahi-daemonon the host to prevent network interface conflicts.sudo systemctl disable mdns sudo systemctl disable avahi-daemon - AppArmor (Ubuntu 24.04+): If
rsyslogderrors appear indmesg, disable the profile on the host:sudo ln -s /etc/apparmor.d/usr.sbin.rsyslogd /etc/apparmor.d/disable/ sudo apparmor_parser -R /etc/apparmor.d/usr.sbin.rsyslogd
3. Run the Container
sudo docker run --rm -it \
--name threadfuzzer \
--network none \
--security-opt apparmor=unconfined \
-v build:/app/ThreadFuzzer/build \
-v /var/run/dbus:/var/run/dbus \
-v otbr-log:/app/ThreadFuzzer/otbr-log \
-v logs:/app/ThreadFuzzer/logs \
--device /dev/net/tun \
--device /dev/ttyACM0 \
--device /dev/ttyACM1 \
--cap-add NET_ADMIN \
--cap-add SYS_PTRACE \
thread_fuzzer_secriot:fullNote: ttyACM0 represents the RCP, while ttyACM1 connects to the microcontroller (e.g., Arduino) managing physical device resets.
The fuzzer requires a main configuration file followed by one or more strategy configurations.
Example: Random fuzzing of a Virtual MTD target.
./build/ThreadFuzzer configs/Fuzzing_Settings/main_config_mtd.json configs/Fuzzing_Strategies/random_fuzzing_config.jsonExample: Random fuzzing of a Physical Device.
./build/ThreadFuzzer configs/Fuzzing_Settings/phys_main_config.json configs/Fuzzing_Strategies/random_fuzzing_config.jsonTo reproduce predefined vulnerabilities (V1–V5) for virtual nodes, set the corresponding seed path in the configs/Fuzzing_Strategies/crash_replication_config.json (by default it is set to V3 for MTD) and use it as a strategy configuration file.
Example: Reproducing a crash in a Virtual MTD target.
./build/ThreadFuzzer configs/Fuzzing_Settings/main_config_mtd.json configs/Fuzzing_Strategies/crash_replication_config.jsonThis section describes how to reproduce the coverage plots and vulnerability analysis presented in the paper.
First, extract the experimental results from the provided archive:
tar -xvzf experiment_logs.tar.gzThe extracted experiment_logs/ directory is organized as follows:
experiment_logs/
├── physical_devices/ # Logs from commercial Thread device experiments
└── virtual_nodes/ # Logs from OpenThread virtual node experiments
Data visualization scripts require Python 3.8 and several data science libraries. Install them on your host machine (visualization is not supported within the Docker container):
pip install pandas numpy matplotlibThe following scripts generate the coverage plots for the virtual targets evaluated in the paper.
OT-FTD Target:
chmod +x scripts/analysis/visualize_coverage_results_ot-ftd.sh
./scripts/analysis/visualize_coverage_results_ot-ftd.shOT-MTD Target:
chmod +x scripts/analysis/visualize_coverage_results_ot-mtd.sh
./scripts/analysis/visualize_coverage_results_ot-mtd.shTo calculate crash metrics and iteration statistics for virtual nodes, use the analyze_virtual_fuzzing_logs.py script.
Example: Analyze OT-FTD Coverage-based Black-box (BB) results:
python3 scripts/analysis/analyze_virtual_fuzzing_logs.py experiment_logs/virtual_nodes/OT-FTD/Coverage-based_BB_fuzzingFor commercial devices, use analyze_physical_fuzzing_logs.py. You must specify the device type using the --device (--d) flag (MTD or FTD).
Example: Analyze all Random fuzzing runs for the Eve sensor:
# Iterates through all logs in the Eve Random fuzzing directory
for f in experiment_logs/physical_devices/Eve/Random_fuzzing/*; do
python3 scripts/analysis/analyze_physical_fuzzing_logs.py -d MTD "$f"
doneDue to known instabilities with AddressSanitizer (ASan) and high-memory fuzzing, ASLR must be disabled on the host machine to ensure stable execution:
echo 0 | sudo tee /proc/sys/kernel/randomize_va_spaceThreadFuzzer automates factory resets via serial communication to an external microcontroller (e.g., Arduino). This controller manages power cycling and physical button presses. Logic for these interactions is defined in src/DUT/generic_sensor.cpp.
WDissector is utilized for protocol dissection but remains experimental. It is highly recommended to keep AddressSanitizer enabled during use to monitor potential memory leaks or segmentation faults inherent to the dissector's current version.