"BLE is everywhere. Your running shoes may be more vulnerable than your laptop." — The Definitive Guide to ARM Cortex-M0 and Cortex-M0+, Chapter 14 (Bluetooth LE overview)
Lecture (50 min)
7.1 BLE Protocol Architecture
Bluetooth Low Energy (BLE), introduced in Bluetooth 4.0 (2010), is a distinct protocol from Classic Bluetooth, optimized for low-power IoT devices. It operates in the 2.4 GHz ISM band across 40 channels:
- 3 advertising channels (37, 38, 39): 2402, 2426, 2480 MHz -- chosen to minimize 802.11 overlap
- 37 data channels: used for paired connections
GAP (Generic Access Profile): controls advertising, scanning, and connection establishment. A device in "advertising" mode broadcasts packets every 20ms to 10s on advertising channels. A "scanner" listens and responds.
GATT (Generic Attribute Profile): defines how data is structured and exchanged over a BLE connection. GATT uses a client-server model:
- Server (peripheral): exposes Services and Characteristics
- Client (central): connects, discovers, reads, writes Characteristics
A Service is a collection of related Characteristics (e.g., Heart Rate Service). A Characteristic is a typed data field with a UUID, permissions (read/write/notify), and a value.
7.2 BLE Advertising and Passive Reconnaissance
A BLE device in advertising mode broadcasts its presence without requiring any pairing. The advertising PDU contains:
- Device address (may be randomized since BLE 4.2)
- Advertising flags (connectable, scannable, non-connectable)
- AD structures: local name, manufacturer data, service UUIDs, TX power
Passive scanning with a BLE sniffer reveals:
- Every advertising device within range (including health wearables, beacons, smart locks, IoT sensors)
- Manufacturer data (often encodes device state, firmware version, or user data in cleartext)
- Service UUIDs (identifies device type without connecting)
This is the first stage of BLE reconnaissance: discover what is advertising, infer device type and vendor, look up known vulnerabilities for that device/firmware combination.
7.3 BLE Pairing and Key Exchange
BLE pairing establishes shared keys for encrypted communication. The security level depends on the pairing method:
Just Works: no user confirmation. Susceptible to MITM because neither side verifies the exchange. Provides encryption but not authentication. Used by many IoT devices for convenience.
Passkey Entry: one side displays a 6-digit PIN; the other enters it. Provides MITM protection if the PIN is observed only by the legitimate user. Vulnerable if attacker can observe the PIN display or brute-force (1,000,000 possibilities).
Numeric Comparison (BLE 4.2+): both sides display a 6-digit number; user confirms match on both. Provides strong MITM protection; requires display + input on both devices. Used by smartphones pairing with keyboards/mice.
OOB (Out-of-Band): key exchange material is delivered over a separate channel (NFC tap, QR code). Provides strong MITM protection proportional to the security of the OOB channel.
Secure Connections (BLE 4.2): uses ECDH (P-256) for key agreement. Older "Legacy Pairing" used a weaker mechanism. Secure Connections is mandatory for BLE 5.0 devices claiming Bluetooth SIG certification.
7.4 GATT Enumeration: Finding Sensitive Characteristics
Once paired (or if the device allows unauthenticated reads), GATT enumeration reveals the full service/characteristic tree. Tools:
# bluetoothctl
bluetoothctl
power on
scan on
# (wait for device to appear)
connect AA:BB:CC:DD:EE:FF
menu gatt
list-attributes
# bleak (Python, cross-platform)
import asyncio
from bleak import BleakClient
async def enumerate(addr):
async with BleakClient(addr) as client:
for service in client.services:
print(f"[Service] {service.uuid}: {service.description}")
for char in service.characteristics:
print(f" [Char] {char.uuid}: {char.properties}")
asyncio.run(enumerate("AA:BB:CC:DD:EE:FF"))
Sensitive findings from GATT enumeration:
- Write-without-response characteristics that control actuators (locks, blinds, outlets)
- Notify characteristics streaming sensor data (location, health metrics)
- Custom UUIDs (vendor-specific) that accept unauthenticated writes to configuration registers
7.5 BLE Attacks in Practice
Passive eavesdropping: BLE advertising is unauthenticated and unencrypted by design. Pre-paired data traffic is encrypted only if pairing used an appropriate security level. Legacy Pairing with Just Works is crackable from a passive capture.
MITM against Legacy Pairing: an attacker with a sniffer present during pairing can recover the Long Term Key (LTK) from a Legacy Pairing exchange using the TK brute-force attack (1 million possibilities for 6-digit PIN legacy; 1 possibility for Just Works TK=0).
Replay attacks against unencrypted commands: some BLE-controlled devices (smart outlets, simple locks) accept commands on unauthenticated writable characteristics. Capturing and replaying the GATT write unlocks or toggles the device.
KNOB Attack (CVE-2019-9506): forces Bluetooth (Classic and BLE Secure Connections) to negotiate a 1-byte entropy key during pairing, making the encryption brute-forceable in real time. Patched by requiring minimum 7-byte entropy in firmware updates.
Bluetooth Impersonation Attack (BIAS, CVE-2020-10135): Classic Bluetooth; impersonates a previously paired device by exploiting the legacy authentication procedure. Not directly applicable to BLE Secure Connections.
7.6 BLE in Penetration Tests
BLE testing is increasingly standard in IoT/OT pentest engagements. Workflow:
- Passive scan and advertiser enumeration
- Connect and enumerate GATT tree
- Test unauthenticated write characteristics for unintended state changes
- Test read characteristics for sensitive data leakage
- Attempt pairing downgrade (request Legacy Pairing instead of Secure Connections)
- Capture pairing exchange (if timed with device re-pairing); attempt LTK recovery
- Report: unauthenticated writable actuators = Critical; cleartext sensor data in advertising = Medium/High
Lab Preview
Lab 7 uses an nRF52840 dongle with Sniffle firmware (or the provided BLE PCAP) to capture BLE advertising packets, enumerate a lab device's GATT tree with bleak, and identify one unauthenticated writable characteristic.
Homework
Reading (45 min): PySDR Chapter on Bluetooth (linked from course portal) -- covers BLE advertising packet format, channel hopping, and GFSK modulation. This bridges from the RF work in Week 1 to the protocol layer.
Hands-on (60 min): Using bluetoothctl and bleak (or the provided capture), enumerate all GATT services on the provided lab BLE device. Produce a service/characteristic tree table (UUID, description, properties, value if readable). Identify any read-protected characteristics and note what security level is required.
Toolchain Diary Entry
First-introduce this week: bluetoothctl, btmon, bleak (Python), nRF Sniffer / Sniffle
btmon: HCI-level Bluetooth packet monitor. Logs all HCI commands, events, and ACL data. Useful for observing pairing exchanges from the host side.
bluetoothctl: interactive Bluetooth controller. scan on for discovery; connect <addr> to pair/connect; menu gatt to enumerate services.
bleak: Python async BLE client library. Cross-platform. Better than gatttool (deprecated). Install: pip install bleak.
nRF Sniffer (Nordic nRF52840 DK + Wireshark plugin): channel-hopping BLE sniffer that follows a specific device's connection. Requires nRF52840 hardware.
Sniffle (firmware for nRF52840 dongle): open-source BLE 5 sniffer supporting Coded PHY, Extended Advertising, and connection following. pip install sniffle.
Key Terms
- GATT: Generic Attribute Profile; defines the client-server data model for BLE; services contain characteristics
- Advertising channel: one of 3 BLE channels used for device discovery (37, 38, 39); all others are data channels
- Just Works pairing: BLE pairing method with no MITM protection; TK = 0; legacy pairing only
- LTK: Long Term Key; BLE equivalent of a session key; derived during pairing; stored for reconnection
- KNOB Attack: CVE-2019-9506; forces low-entropy key negotiation; allows real-time brute-force of Bluetooth session keys; patched via minimum entropy enforcement
- Sniffle: open-source BLE 5 sniffer firmware for nRF52840; supports connection following and extended advertisements
- bleak: async Python BLE client library; cross-platform; preferred over deprecated
gatttool