U-Fuzz: Stateful Fuzzing of IoT Protocols on COTS Devices

July 4, 2025 ยท View on GitHub

U-Fuzz is a framework to systematically discover and replicate security vulnerabilities on arbitrary wired and wireless IoT protocol (e.g., CoAP, Zigbee, 5G NR) implementations. U-Fuzz offers possibility to automatically construct the protocol state machine with only a few packet traces of normal (i.e., benign) communication.

U-Fuzz Overview and Design


Table of Contents

  1. ๐Ÿ“‹ Software Environment

  2. โฉ Initial Compilation

  3. ๐Ÿ”€ Running Multi-protocol Statemapper

  4. ๐Ÿง‘โ€๐Ÿ’ป Running the fuzzer

  5. ๐Ÿ“„ Exploits

  6. ๐Ÿง‘โ€๐Ÿ’ป U-fuzz Docker

  7. ๐Ÿ“ Citing U-Fuzz


1. ๐Ÿ“‹ Software Environment

  • OS: Ubuntu 18.04 - We recommend using Ubuntu 18.04 to build and run U-Fuzz, otherwise, U-Fuzz and the Multiprotocol Statemapper might fail to execute properly. Alternativelly, you can use an Ubuntu 18.04 docker dev. container to ensure the correct OS environment.
  • Wireshark Version: V4.1 (patched) - This is provided by U-Fuzz.
  • Bindings: Python3, Golang - This is provided by U-Fuzz.

2. โฉ Initial Compilation

Several requirements need to be installed before compiling the project. An automated script for Ubuntu 18.04 is provided on requirements.sh. To compile from source, simply run the following commands:

$ Download the content from this github link:
https://anonymous.4open.science/r/cots-iot-fuzzer/

$ cd wdissector

$ ./requirements.sh dev # Install all requirements to compile wdissector from source

$./requirements.sh doc  # Optional: Install nodejs requirements to generate documentation

$./build.sh all # Compile all binaries. It may take around 15min. Go get a coffe!

3. ๐Ÿ”€ Running Multi-protocol Statemapper

Before running the fuzzer, the multi-protocol-Statemapper needs to be run to generate both the configuration file and the state machine model.

The multi-protocol-statemapper needs two inputs as follows:

1: Capture_trace_for target_protocol.pcapng (can be provided via terminal).

2: configuration template to append the mapping rules needs to specify the file name in "multi_protocol_state_mapper.py :line: 423".

After compiling the project with the correct software environment, please run the following command with the two inputs mentioned previously.

$ cd .../cots-iot-fuzzer/multi_protocol_statemapper/wdissector

$ python3 multi_protocol_state_mapper.py

3.1 Manual Mode Running details

Step 1: Input the final capture trace as illustrated in the figure below.

figStep1

The user can choose to combine multiple capture file by themselves
or use U-Fuzz combiner by inputting "y" in the terminal prompt.

Step 2: After the capture analysis, all the potential state and packet list will be printed out. Then, the user can proceed to form a new state by entering "y". Finally, the potential packet list is shown (you can copy and paste from above).

figStep2

fig-2follow

After the initial packet list is inserted, the user can proceed by inputting 'n', or continuously add more packet lists by inputting 'y' in the question as shown in the figure below:

figStep3

Step 3: After the potential packet list was inserted, the capture processor will first output all the common layers which are shared by all packets provided by the user. Then, the capture processor will start analysing from the most relevant layer as shown in the figure below:

figStep4

The user may need to input a name for that state. She can alternatively copy and paste from the above figure.

fig-4follow

Step 4: One by one analysis (1 by 1) will be performed to find state filters.

figStep5

If a state filter was not found by the previous 1 by 1 step, then 2 by 2 analysis will be performed.

fig2by2

Step 5: Once the filter is found, the user can decide to continuously create a new state by inputting 'y', or to stop by inputting 'n'.

figStep7

Step 6: Once 'n' was provided in the previous step, other three inputs will be asked to the user for the state machine generation:

  1. Previous input capture file;
  2. Template config file;
  3. The output file name, (.json is for the statemachine generation, .png is for the state machine image generation).

figStep8

3.2 Model representation figure

figmodel

4. ๐Ÿง‘โ€๐Ÿ’ป Running the fuzzer

4.1 Zigbee Protocol Implementation

Step1: build the project (zigbee_real_time_fuzzer)

Edit the CMakeLists.txt
$ Uncomments line:802, 810-814 
  (`set(ZIGBEE_SRC src/zigbee_real_time_fuzzer.cpp libs/shared_memory.c)`)
  (`add_executable(zigbee_real_time_fuzzer ${ZIGBEE_SRC} libs/profiling.c)`)
  (`target_link_libraries(zigbee_real_time_fuzzer PRIVATE ${MINIMAL_FUZZER_LIBS} viface)`)
  (`target_compile_options(zigbee_real_time_fuzzer PRIVATE -w -O0)`)
  (`target_compile_definitions(zigbee_real_time_fuzzer PRIVATE -DFUZZ_ZNP)`)

$ Comments line: 804, 824-828 which were configured for CoAP fuzzing
  (`set(COAP_SRC src/coap_realtime_fuzzer.cpp libs/shared_memory.c)`)
  (`add_executable(coap_realtime_fuzzer ${COAP_SRC} libs/profiling.c)`)
  (`target_link_libraries(coap_realtime_fuzzer PRIVATE ${MINIMAL_FUZZER_LIBS} viface)`)
  (`target_compile_options(coap_realtime_fuzzer PRIVATE -w -O0)`)
  (`target_compile_definitions(coap_realtime_fuzzer PRIVATE -DFUZZ_WIFI_AP)`)

$ ./build.sh all

Step2: Install Zigbee2Mqtt from link: https://www.zigbee2mqtt.io/

The sample configuration file for Zigbee2Mqtt is located at folder cots-iot-fuzzer/zigbee_dongle_connection/coordinator/data

Step3: Prepare the hardware for fuzzing Zigbee including coordinator dongle (e.g., CC2531 ZNP-Prod) and zigbee smart devices.

figdongle

Step 4: Run the fuzzer

open a new terminal then run 
$ mosquitto

run the fuzzer at directory
$ cd cots-iot-fuzzer/
$ sudo bin/zigbee_real_time_fuzzer --EnableMutation=true

$ cd zigbee_dongle_connection/coordinator
$ docker-compose up

4.2 CoAP Protocol Implementation

Step1: build the project (coap_realtime_fuzzer)

$ ./build.sh all

Step2: Set up target CoAP sever implementation (e.g., Libcoap)

Step3: Run the Fuzzer

$ Run CoAP Server

$ cd cots-iot-fuzzer/
$ sudo bin/coap_realtime_fuzzer --EnableMutation=true
$ cd cots-iot-fuzzer/coap_client_server
$ sudo ip netns exec veth5 node client_complete.js

4.3 5G NR Implementation (Standalone)

4.3.1 Fuzzing 5G NR using Container:

Download the 5G container from the docker hub.

Credential:

docker login -u a80568681433

Access token:
dckr_pat_A7VRSeNGp_tJPhIAuk4Iksk0pxM

4.3.2 Fuzzing 5G NR with 5G Simulator:

$ cd */wireless-deep-fuzzer/5gcontainer

$ chmod +x container.sh

$ ./container.sh run release-5g

Use the following command to just run 5G simulator $ sudo bin/lte_fuzzer --EnableSimulator=true

4.3.3 Fuzzing 5G NR with real COTS:

Hardware Preparation:

OnePlus Nord CE2 or other 5G COTS UE.

USRP B210

Command:

$ chmod +x container.sh

$ ./container.sh run release-5g

$ sudo bin/lte_fuzzer  --EnableSimulator=false

5. ๐Ÿ“„ Exploits

5.1. Summary of CVEs:

As of today, U-Fuzz has discovered 11 new security flaws which have been assigned 11 CVE IDs. The correspondence between the exploit name, U-Fuzz discovered vulnerability and the CVE IDs are shown in the Tables below:

Protocol Under TestU-Fuzz Vulnerability NameAffected Hardware/
Software Implementation
CVE
5GV1 - Invalid CellGroupConfigOnePlus Nord CE 2CVE-2024-20004
5GV2 - Invalid CellGroupIdOnePlus Nord CE 2CVE-2024-20003
5GV3 - Invalid RLC SequenceOnePlus Nord CE 2CVE-2023-20702 (existed)
5GV4 - Invalid Uplink Config ElementOnePlus Nord CE 2CVE-2023-32843 (existed)
5GV5 - Null Uplink Config ElementOnePlus Nord CE 2CVE-2023-32845 (existed)
ZigbeeV6 - Invalid Transaction
and Cluster ID
Texas Instrument CC2531 USB Dongle Z-stack version:
Z-Stack_Home_1.2
SONOFF Zigbee 3.0 USB
Dongle-P Z-stack version:
Z-Stack_3.0.x
CVE-2023-41388
ZigbeeV7 - Invalid Transaction
and Cluster ID
Zigbee2Mqtt Version:3.8CVE-2023-41003
ZigbeeV8 - Malformed AF_Data_RequestZigbee2Mqtt Version:3.8CVE-2023-42386
ZigbeeV9 - Out of Sync State InformationZigbee2Mqtt Version:3.8CVE-2023-41004
ZigbeeA1 - Skip Link StatusTuya Smart PlugNot applicable
ZigbeeA2 - Skip Link StatusPhilips Hue Smart Light BulbNot applicable
CoAPV10 - NullPointerExceptionJcoapCVE-2023-34918
CoAPV11 - Illegal_Argument_Exception
_Invalid_Token_Length
JcoapCVE-2023-34920
CoAPV12 - Slice_Bounds_out_of_RangeCanopusCVE-2023-34919
CoAPV13 - Bad Get RequestCanopusCVE-2023-34921
CoAPV14 - Invalid Size1 Size2 OptionslibcoapCVE-2023-33605
CoAPV15 - Bad POST RequestCoAPthonCVE-2018-12680 (existed)
CoAPV16 - Invalid Unicode DecodingCoAPthonCVE-2018-12680 (existed)

5.2. Available Exploits

U-Fuzz Vulnerability NameExploit
V1 - Invalid CellGroupConfigmac_sch_mtk_rrc_setup_crash_2
V2 - Invalid CellGroupIdmac_sch_mtk_rrc_setup_crash_1
V3 - Invalid RLC Sequencemac_sch_mtk_rlc_crash
V4 - Invalid Uplink Config Elementmac_sch_mtk_rrc_setup_crash_3
V5 - Null Uplink Config Elementmac_sch_mtk_rrc_setup_crash_4
V10 - NullPointerExceptionreplicate_crash_jcoap_1
V11 - Illegal_Argument_Exception_Invalid_Token_LengthCan replace replicate_crash_jcoap_1 to any PUT request
V12 - Slice_Bounds_out_of_Rangereplicate_crash_canpous
V13 - Bad Get Requestreplicate_crash_canpous
V15 - Bad POST Requestreplicate_crash_CoAPthon
V16 - Invalid Unicode Decodingreplicate_crash_CoAPthon

5.2.1 V14 replication

Our group used Esp32 board to fuzz libcoap and to replicate the vulnerability V14 that we found on libcoap. The detailed replication tutorial can be found at Libcoap_crash_replication_tutorial. Additionally, the replication script can be found at replicate_crash_libcoap.

6. ๐Ÿง‘โ€๐Ÿ’ป U-fuzz Docker

U-fuzz

6.2 Running Toturials and Potential Issues

More detials can refer to the file U_Fuzz_build_from_scrach.html

6.2.1 U-Fuzz container running command

$ docker load -i u-fuzz-docker.tar

$ docker run -it --privileged -d --restart=unless-stopped --network=host -v /dev:/dev -v /var/run/netns:/var/run/netns u-fuzz-docker:latest

get the docker-id by using cmd
$ docker ps -a 

then run 
$ docker exec -it <docker-id> bash

6.2.2 Potential Issue:

if encounter a python configuration problem while building the fuzzer by using command ./build.sh all, you can go to ~/U-Fuzz/modules/python/install/bin and run chmod +x python* to give python3 the correct privilege.

7. ๐Ÿ“ Citing U-Fuzz

@inproceedings{
  author={Shang, Zewen and Garbelini, Matheus E and Chattopadhyay, Sudipta},
  booktitle={2024 IEEE Conference on Software Testing, Verification and Validation (ICST)}, 
  title={U-Fuzz: Stateful Fuzzing of IoT Protocols on COTS Devices}, 
  year={2024},
}