| Supported Targets | ESP32 | ESP32-C2 | ESP32-C3 | ESP32-C5 | ESP32-C6 | ESP32-C61 | ESP32-H2 | ESP32-S3 |
|---|
This project is a specialized BLE research tool built on the ESP-IDF NimBLE stack. It has been modified from the standard central example to perform targeted device discovery and high-frequency GATT stress testing (Denial of Service research).
- Target-Locked Scanning: Bypasses standard UUID filtering to identify targets by Local Name (e.g., "Sincerely, Stepper").
- Active Scanning: Configured to request Scan Response packets to retrieve full device names that are often hidden in legacy advertising.
- GATT Flood Logic: Includes a research-oriented loop that performs high-frequency synchronous writes (
ble_gattc_write_flat) to stress-test a target's Bluetooth stack and memory management. - NimBLE Stack: Utilizes the open-source NimBLE host for precise control over BLE procedures.
The goal of this project is to observe how modern BLE stacks (specifically on mobile devices) handle:
- Resource Exhaustion: Flooding a connection with more GATT requests than the target can acknowledge in real-time.
- Malformed Data Handling: Writing randomized garbage data to system-protected handles (like Generic Access Service).
- Link-Layer Resilience: Testing the threshold at which a target terminates a connection due to protocol violations or processing lag.
- Software Resilience: Modern mobile OSs (Android/iOS) demonstrate high resilience to malformed writes on system handles, typically ignoring invalid requests without crashing the radio firmware.
- Attacker Bottlenecks: High-speed flooding without flow control (
vTaskDelay) can lead to memory allocation failures (GATTC proc alloc failed) on the ESP32 itself, demonstrating the importance of timing in protocol-level attacks.
- Configure Target: Set the target name in
main.cinside theblecent_should_connectfunction. - Build and Flash:
idf.py set-target esp32 idf.py build idf.py -p COM6 flash monitor
- Monitor: Observe the serial output for "TARGET ACQUIRED" and the subsequent handshake/flood counts.
This tool is for educational and security research purposes only. Ensure you have permission before testing against any device you do not own.
This is the console output on successful connection:
I (202) BTDM_INIT: BT controller compile version [0b60040]
I (202) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
W (212) phy_init: failed to load RF calibration data (0xffffffff), falling back to full calibration
I (422) phy: phy_version: 4007, 9c6b43b, Jan 11 2019, 16:45:07, 0, 2
I (722) NimBLE_BLE_CENT: BLE Host Task Started
GAP procedure initiated: stop advertising.
GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever
GAP procedure initiated: connect; peer_addr_type=1 peer_addr=xx:xx:xx:xx:xx:xx scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=16 max_ce_len=768 own_addr_type=0
Connection established
Connection secured
encryption change event; status=0
GATT procedure initiated: discover all services
GATT procedure initiated: discover all characteristics; start_handle=1 end_handle=3
GATT procedure initiated: discover all characteristics; start_handle=20 end_handle=26
GATT procedure initiated: discover all characteristics; start_handle=40 end_handle=65535
GATT procedure initiated: discover all descriptors; chr_val_handle=42 end_handle=43
GATT procedure initiated: discover all descriptors; chr_val_handle=49 end_handle=65535
Service discovery complete; status=0 conn_handle=0
GATT procedure initiated: read; att_handle=45
GATT procedure initiated: write; att_handle=47 len=2
GATT procedure initiated: write; att_handle=43 len=2
Read complete; status=0 conn_handle=0 attr_handle=45 value=0x02
Write complete; status=0 conn_handle=0 attr_handle=47
Subscribe complete; status=0 conn_handle=0 attr_handle=43
GATT procedure initiated: write; att_handle=26 len=2
GATT procedure initiated: write; att_handle=25 len=1
GATT procedure initiated: read; att_handle=25
Subscribe to the custom subscribable characteristic complete; status=0 conn_handle=1 attr_handle=26 value=
Write to the custom subscribable characteristic complete; status=0 conn_handle=1 attr_handle=25
received notification; conn_handle=1 attr_handle=25 attr_len=4
Read complete for the subscribable characteristic; status=0 conn_handle=1 attr_handle=25 value=0x19
This is the console output on failure (or peripheral does not support New Alert Service category):
I (180) BTDM_INIT: BT controller compile version [8e87ec7]
I (180) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE
I (250) phy: phy_version: 4000, b6198fa, Sep 3 2018, 15:11:06, 0, 0
I (480) NimBLE_BLE_CENT: BLE Host Task Started
GAP procedure initiated: stop advertising.
GAP procedure initiated: discovery; own_addr_type=0 filter_policy=0 passive=1 limited=0 filter_duplicates=1 duration=forever
GAP procedure initiated: connect; peer_addr_type=1 peer_addr=xx:xx:xx:xx:xx:xx scan_itvl=16 scan_window=16 itvl_min=24 itvl_max=40 latency=0 supervision_timeout=256 min_ce_len=16 max_ce_len=768 own_addr_type=0
Connection established
GATT procedure initiated: discover all services
GATT procedure initiated: discover all characteristics; start_handle=1 end_handle=3
GATT procedure initiated: discover all characteristics; start_handle=20 end_handle=26
GATT procedure initiated: discover all characteristics; start_handle=40 end_handle=65535
GATT procedure initiated: discover all descriptors; chr_val_handle=42 end_handle=43
GATT procedure initiated: discover all descriptors; chr_val_handle=47 end_handle=65535
Service discovery complete; status=0 conn_handle=0
Error: Peer doesn't support the Supported New Alert Category characteristic
GAP procedure initiated: terminate connection; conn_handle=0 hci_reason=19
disconnect; reason=534
The following configuration flags can be adjusted to significantly reduce RAM usage in your ESP-IDF project while retaining basic BLE functionality.
| Config Option | Old → New Value | RAM Saved (Bytes) |
|---|---|---|
| CONFIG_BT_NIMBLE_SM_SC | y → n | 2040 |
| CONFIG_BT_NIMBLE_LL_CFG_FEAT_LE_ENCRYPTION | y → n | 32 |
| CONFIG_BT_NIMBLE_GATT_MAX_PROCS | 4 → 2 | 112 |
| CONFIG_BT_NIMBLE_MAX_CONNECTIONS | 3 → 1 | 480 |
| CONFIG_BT_NIMBLE_MAX_BONDS | 3 → 1 | 448 |
| CONFIG_BT_NIMBLE_MAX_CCCDS | 8 → 1 | 112 |
| CONFIG_BT_NIMBLE_ENABLE_CONN_REATTEMPT | y → n | 256 |
| CONFIG_BT_NIMBLE_TRANSPORT_EVT_COUNT | 30 → 15 | 240 |
| CONFIG_BT_NIMBLE_SECURITY_ENABLE | y → n | 2072 |
| CONFIG_SPI_FLASH_ROM_IMPL | n → y | 9804 |
| CONFIG_SPI_FLASH_SUPPORT_ISSI_CHIP | y → n | 0 |
| CONFIG_SPI_FLASH_SUPPORT_MXIC_CHIP | y → n | 140 |
| CONFIG_SPI_FLASH_SUPPORT_GD_CHIP | y → n | 648 |
| CONFIG_SPI_FLASH_SUPPORT_WINBOND_CHIP | y → n | 8 |
| CONFIG_SPI_FLASH_SUPPORT_BOYA_CHIP | y → n | 140 |
| CONFIG_SPI_FLASH_SUPPORT_TH_CHIP | y → n | 136 |
| CONFIG_SPI_FLASH_ENABLE_ENCRYPTED_READ_WRITE | y → n | 704 |
| CONFIG_VFS_SUPPORT_TERMIOS | y → n | 424 |
| CONFIG_VFS_SUPPORT_IO | y → n | 2008 |
| CONFIG_COMPILER_OPTIMIZATION_SIZE | n → y | 8408 |
| CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE | n → y | 5896 |
| CONFIG_ESP_COEX_SW_COEXIST_ENABLE | y → n | 896 |
| ESP_TASK_WDT_EN | y → n | 528 |
| CONFIG_LOG_DEFAULT_LEVEL_NONE | n → y | 2592 |
For any technical queries, please open an issue on GitHub. We will get back to you soon.