Sni5Gect is a framework for sniffing unencrypted 5G messages and injecting custom packets into the over-the-air communication between a base station and a User Equipment (UE). It can be used for security research to perform attacks like crashing UE modems, network downgrades, fingerprinting, and auth bypass. The tool has been tested with commercial UEs (smartphones, modems) and srsRAN/Effnet base stations.
- 🔎 Sniff: Capture 5G MAC-NR unencrypted messages between the base station and UE.
- 💉 Inject: Send arbitrary MAC-NR messages to a target UE at specific communication states.
- 💥 Crash UE modems.
- 📉 Downgrade attacks (5G to 4G).
- 👆 Device Fingerprinting.
- 👹 Anomaly Detection.
Sni5Gect artifacts paper received badges Available, Functional and Reproduced in the 34th USENIX Security Symposium. Artifacts PDF available here
We recommend running the entire stack within an Ubuntu 22.04 Docker container to ensure consistent dependencies and avoid affecting the local environment.
Build and Start the Docker Container:
docker compose build sni5gect # Build container
docker compose up -d sni5gect # Start Container
docker exec -it sni5gect bash # Access Container
./build/shadower/shadower configs/srsran-n78-20MHz-b210.yaml # Run Sniffer for Band N78 with 20MHz Bandwidth
# See Running Sni5Gect in the README.md- Features Supported
- Requirements
- Running Sni5Gect
- Exploit Modules
- Example Configuration
- Overview of Components
- Project Structure
- Disclaimer
- Citing Sni5Gect
We have tested with the following configurations:
- Frequency Bands: n78, n41 (TDD), n3 (FDD)
- Frequency: 3427.5 MHz, 2550.15 MHz, 1865.0 MHz
- Subcarrier Spacing: 30 kHz, 15 KHz
- Bandwidth: 20–50 MHz
- MIMO Configuration: Single-input single-output (SISO)
- Distance: 0 meter to up to 20 meters (with amplifier)
An example srsRAN base station configuration is available at configs/base_station/srsran-n78-20MHz.yml.
Sni5Gect utilizes a USRP Software Defined Radio (SDR) device to send and receive IQ samples during communication between a legitimate 5G base station and a UE. The following SDRs are supported:
- USRP B210 SDR
- USRP x310 SDR
Host Machine Recommendations:
- Minimum: 12-core CPU
- 16 GB RAM
Our setup consists of an AMD 5950x processor with 32 GB of memory.
- Operating System: Ubuntu 22.04 (containerized environment)
- Note: The host should be dedicated to Sni5Gect without resource-intensive applications (e.g., GUI) to prevent SDR overflows.
- wDissector for analyzing over-the-air traffic.
- Wireshark display filters to identify communication states.
Sni5Gect builds upon srsRAN 4G utilizing features such as SSB search, PBCH decoding, PDCCH decoding, PDSCH encoding/decoding, and PUSCH decoding.
The following COTS devices were evaluated:
| Model | Modem | Patch Version |
|---|---|---|
| OnePlus Nord CE 2 IV2201 | MediaTek MT6877V/ZA | 2023-05-05 |
| Samsung Galaxy S22 SM-S901E/DS | Snapdragon X65 | 2024-06-01 |
| Google Pixel 7 | Exynos 5300 | 2023-05-05 |
| Huawei P40 Pro ELS-NX9 | Balong 5000 | 2024-02-01 |
| Fibocom FM150-AE USB modem | Snapdragon X55 | NA |
The Sni5Gect executable is located in the build/shadower directory, and configuration files are available in the configs folder.
The easiest way to get started with Sni5Gect is to run it using a pre-recorded IQ sample file. We've provided a sample for offline testing.
- Download and Extract the example recording file from Zenodo:
wget https://zenodo.org/records/15601773/files/example-connection-samsung-srsran.zip
unzip example-connection-samsung-srsran.zip- Edit
configs/config-srsran-n78-20MHz.confand modify thesourcesection as follows:
source:
source_type: file
source_params: /root/sni5gect/example_connection/example.fc32
rf:
sample_rate: 23.04e6
num_channels: 1
uplink_cfo: 0 # Uplink Carrier Frequency Offset correction in Hz
downlink_cfo: 0 # Downlink Carrier Frequency Offset (CFO) in Hz- Finally launch the sniffer using:
./build/shadower/shadower configs/srsran-n78-20MHz-b210.yamlYou should see output similar to the screenshot below:
To test Sni5Gect with a live over-the-air signal using a Software Defined Radio (SDR), update the configuration file to use the SDR as the source.
Example source and rf Section for UHD-compatible SDR (e.g., USRP B200)
source:
source_type: uhd
source_params: type=b200,master_clock_rate=23.04e6
rf:
sample_rate: 23.04e6
num_channels: 1
uplink_cfo: -0.00054 # Uplink Carrier Frequency Offset correction in Hz
downlink_cfo: 0 # Downlink Carrier Frequency Offset (CFO) in Hz
padding:
front_padding: 0 # Number of IQ samples to pad in front of each burst
back_padding: 0 # Number of IQ samples to pad at the end of each burst
channels:
- rx_frequency: 3427.5e6
tx_frequency: 3427.5e6
rx_offset: 0
tx_offset: 0
rx_gain: 40
tx_gain: 80
enable: trueThen start the sniffer with:
./build/shadower/shadower configs/srsran-n78-20MHz-b210.yamlUpon startup, Sni5Gect will do the following:
- Search for the base station using the specified center and SSB frequencies.
- Retrieve cell configuration from SIB1.
- Detect RAR messages indicating a new UE connecting to the target base station.
The exploit modules are designed to provide a flexible way to load different attacks or exploits. When receiving a message, it will first be sent to wDissector to analyze the packet and if the packet matches with any Wireshark display filters specified, it will react according to the post_dissection specified, either to inject messages to the communication or to extract certain fields.
This module performs passive sniffing. The wDissector framework dissects packets and provides summaries of received packets.
exploit: modules/lib_dummy.so
To monitor decoded DCI (Downlink Control Information) messages in real time, set the following logging configuration:
worker_log_level = DEBUG
With this setting, the sniffer logs detailed DCI-related information, including:
- DCI UL (Uplink Scheduling)
- PUSCH decoding results
- DCI DL (Downlink Scheduling)
- PDSCH decoding results
Example output:
[D] [ 0] DCI UL slot 6732 17503: c-rnti=0x4601 dci=0_0 ss=common0 L=2 cce=0 f_alloc=0x498 t_alloc=0x0 hop=n mcs=9 ndi=1 rv=0 harq_id=0 tpc=1
[D] [ 0] PUSCH 6734 17507: c-rnti=0x4601 prb=(3,26) symb=(0,13) CW0: mod=QPSK tbs=528 R=0.670 rv=0 CRC=OK iter=1.0 evm=0.04 t_us=249 epre=+16.6 snr=+24.0 cfo=-2657.6 delay=-0.0
[I] 17921 [S:17507] <-- [P:NR RRC/NAS-5GS/NAS-5GS] RRC Setup Complete, Registration request, Registration request [113-bytes] (Padding 405 bytes)
[D] [ 0] DCI DL slot 6741 17520: c-rnti=0x4601 dci=1_1 ss=ue L=1 cce=4 f_alloc=0x14 t_alloc=0x0 mcs=20 ndi=0 rv=0 harq_id=0 dai=0 tpc=1 harq_feedback=3 ports=0 srs_request=0 dmrs_id=0
[D] [ 0] PDSCH 6741 17520: c-rnti=0x4601 prb=(20,20) symb=(2,13) CW0: mod=64QAM tbs=54 R=0.593 rv=0 CRC=OK iter=1.0 evm=0.00 epre=+11.2 snr=+39.5 cfo=-0.7 delay=-0.0
[I] 17921 [S:17520] --> [P:NR RRC/NAS-5GS] DL Information Transfer, Identity request [13-bytes] (Padding 31 bytes) These exploits are taken from paper 5Ghoul: Unleashing Chaos on 5G Edge Devices. These affect the MTK modems of the OnePlus Nord CE2.
| CVE | Module |
|---|---|
| CVE-2023-20702 | lib_mac_sch_rrc_setup_crash_var.so |
| CVE-2023-32843 | lib_mac_sch_mtk_rrc_setup_crash_3.so |
| CVE-2023-32842 | lib_mac_sch_mtk_rrc_setup_crash_4.so |
| CVE-2024-20003 | lib_mac_sch_mtk_rrc_setup_crash_6.so |
| CVE-2023-32845 | lib_mac_sch_mtk_rrc_setup_crash_7.so |
Upon receiving the RRC Setup Request message from the UE, Sni5Gect replies with malformed RRC Setup to the target UE. If the UE accepts such malformed RRC Setup message, it crashes immediately, this can be confirmed from the adb log containing the keyword sModemReason, which indicates the MTK modem crashes. For example:
MDMKernelUeventObserver: sModemEvent: modem_failure
MDMKernelUeventObserver: sModemReason:fid:1567346682;cause:[ASSERT] file:mcu/l1/nl1/internal/md97/src/rfd/nr_rfd_configdatabase.c line:4380 p1:0x00000001
Utilizes the TC11 attack from the paper Never Let Me Down Again: Bidding-Down Attacks and Mitigations in 5G and 4G. Injects a Registration Reject message after receiving a Registration Request from the UE, causing it to disconnect from 5G and downgrade to 4G. Since the base station may not be aware of the disconnection, it may keep sending the messages such as Security Mode Command, Identity Request, Authentication Request, etc.
exploit: modules/lib_dg_registration_reject.so
Demonstrates a fingerprinting attack by injecting an Identity Request message after receiving a Registration Request. If the UE accepts, it responds with an Identity Response containing its SUCI information.
exploit: modules/lib_identity_request.so
This exploit corresponds to CVD-2024-0096. It is the most complex exploit we have, involving two stages: sniffing and replaying. During the replaying stage, it requires sniffing and injecting at multiple different states.
- Sniffing: Capture a legitimate Authentication Request from the base station to the UE.
exploit: modules/lib_dg_authentication_request_sniffer.so
- Replaying: Update
shadower/modules/dg_authentication_replay.ccwith the captured MAC-NR values. Rebuild the module:
ninja -C buildThen load the module:
exploit: modules/lib_dg_authentication_replay.so
Upon receiving Registration Request from the UE, Sni5Gect replays the captured Authentication Request message to the target UE. Upon receiving the replayed Authentication Request message, the UE replies with Authentication Failure message with cause Synch Failure and starts the timer T3520. Then Sni5Gect updates its RLC and PDCP sequence number accordingly and replays the Authentication Request message for a few more times. Eventually, after multiple attempts and timer T3520 expires, the UE deems that the network has failed the authentication check, locally releases the communication, and treats the active cell as barred. If no other 5G base station is available, then the UE will downgrade to 4G and persists in downgrade status up to 300 seconds according to the specification 3GPP TS 24.501 version 16.5.1 Release 16 5.4.1.2.4.5 Abnormal cases in the UE. (Some phones may stay in downgrade status for much longer time).
In the example output, we can identify that the UE replies with the Authentication Failure message two times in the following screenshot.
This exploit utilizes Registration Request from the UE, Sni5Gect injects the plaintext Registration Accept message with security header 4. The UE will ignore the wrong MAC, accept the Registration Accept message, and reply with Registration Complete and PDU Session Establishment Requests. Since the core network receives such unexpected messages, it instructs the gNB to release the connection by sending the RRC Release message to terminate the connection immediately.
exploit: modules/lib_plaintext_registration_accept.so
An example configuration is provided in configs/srsran-n78-20MHz-b210.yaml
cell:
band: 78 # Band number
nof_prb: 51 # Number of Physical Resource Blocks
scs_common: 30 # Subcarrier Spacing for common (kHz)
scs_ssb: 30 # Subcarrier Spacing for SSB (kHz)
ssb_period_ms: 10 # SSB periodicity in milliseconds
dl_arfcn: 628500 # Downlink ARFCN
ssb_arfcn: 628128 # SSB ARFCN
source:
source_type: uhd
source_params: type=b200,master_clock_rate=23.04e6
enable_recorder: false # record the IQ samples to file
pcap_folder: logs/
rf:
sample_rate: 23.04e6
num_channels: 1
uplink_cfo: -0.00054 # Uplink Carrier Frequency Offset correction in Hz
downlink_cfo: 0 # Downlink Carrier Frequency Offset (CFO) in Hz
padding:
front_padding: 0 # Number of IQ samples to pad in front of each burst
back_padding: 0 # Number of IQ samples to pad at the end of each burst
channels:
- rx_frequency: 3427.5e6 # Actual rx frequency for each channel
tx_frequency: 3427.5e6 # Actual tx frequency for each channel
rx_offset: 0 # rx frequency manual calibration
tx_offset: 0 # tx frequency manual calibration
rx_gain: 40 # rx gain to use for each channel
tx_gain: 80 # tx gain to use for each channel
enable: true # Enable this channel or not
workers:
pool_size: 24 # Worker pool size
n_ue_dl_worker: 4 # Number of UE downlink workers
n_ue_ul_worker: 4 # Number of UE uplink workers
n_gnb_dl_worker: 4 # Number of gNB downlink workers
n_gnb_ul_worker: 4 # Number of gNB uplink workers
uetracker:
close_timeout: 5000 # ms: stop tracking if no messages received
parse_messages: true # Parse messages
num_ues: 5 # Number of UETrackers to pre-initialize
enable_gpu: false # GPU acceleration for decoding
downlink_injector:
delay_n_slots: 5 # Number of slots to delay injecting the message
duplications: 2 # Number of duplications to send in each inject
tx_cfo_correction: 0 # Uplink CFO correction (Hz)
tx_advancement: 160 # Number of samples to send in advance
pdsch_mcs: 3 # PDSCH MCS
pdsch_prbs: 24 # PDSCH PRBs
log:
log_level: INFO
syncer: INFO
worker: INFO
bc_worker: INFO
exploit: build/modules/lib_dummy_exploit.so # exploit module to use
# exploit: build/modules/lib_identity_request.so
# exploit: build/modules/lib_dg_authentication_request_sniffer.so
# exploit: build/modules/lib_dg_authentication_replay.so
# exploit: build/modules/lib_dg_registration_reject.so
# exploit: build/modules/lib_mac_sch_mtk_rlc_crash.so
# exploit: build/modules/lib_mac_sch_mtk_rrc_setup_crash_3.so
# exploit: build/modules/lib_mac_sch_mtk_rrc_setup_crash_4.so
# exploit: build/modules/lib_mac_sch_mtk_rrc_setup_crash_6.so
# exploit: build/modules/lib_mac_sch_mtk_rrc_setup_crash_7.so
# exploit: build/modules/lib_plaintext_registration_accept.so
Sni5Gect comprises several components, each responsible for handling different signals:
- Syncer: Synchronizes time and frequency with the target base station.
- Broadcast Worker: Decodes broadcast information such as SIB1 and detects and decodes RAR.
- UETracker: Tracks the connection between the UE and the base station.
- UE DL Worker: Decodes messages sent from the base station to the UE.
- GNB UL Worker: Decodes messages sent from the UE to the base station.
- GNB DL Injector: Encodes and sends messages to the UE.
The project is organized as follows. The core Sni5Gect framework resides in the shadower directory. Key components are implemented in the following files:
.
├── cmake
├── configs
├── credentials
├── debian
├── images
├── lib
|-- shadower
| |-- CMakeLists.txt
| |-- comp
| | |-- CMakeLists.txt
| | |-- fft
| | |-- scheduler.cc # Distributes received subframes to components
| | |-- ssb
| | |-- sync # Syncer implementation
| | |-- trace_samples
| | |-- ue_tracker.cc # UE Tracker implementation
| | |-- ue_tracker.h
| | `-- workers
| | |-- CMakeLists.txt
| | |-- broadcast_worker.cc # Broadcast Worker implementation
| | |-- gnb_dl_worker.cc # GNB DL Injector implementation
| | |-- gnb_ul_worker.cc # GNB UL Worker implementation
| | |-- ue_dl_worker.cc # UE DL Worker implementation
| | |-- wd_worker.cc # wDissector wrapper
| |-- main.cc
| |-- modules # Exploit modules
| |-- source
| |-- test
| |-- tools
| `-- utils
├── srsenb
├── srsepc
├── srsgnb
├── srsue
├── test
└── utils
This framework is for research and educational purposes only. Unauthorized use of Sni5Gect on live public networks or devices without consent may violate local laws and regulations. The authors and contributors are not responsible for any misuse.
@inproceedings{
author={Shijie Luo and Garbelini Matheus E and Chattopadhyay Sudipta and Jianying Zhou},
booktitle={34th USENIX Security Symposium (USENIX Security 25)},
title={Sni5Gect: A Practical Approach to Inject aNRchy into 5G NR},
year={2025},
}