Berkner Tech

BLE Security Testing for Connected Products

BLE security testing pipeline for connected products, from scanning to writing a GATT characteristic

Bluetooth Low Energy is the radio behind a huge share of consumer IoT: locks, wearables, medical sensors, trackers. Its security is entirely optional, and a striking number of products leave it off. Here is how I test a BLE device, from the first advertisement to writing the characteristic that unlocks it, and how to make sure yours is not the easy one.

Why BLE Is Worth a Hard Look

BLE devices expose their functionality through GATT, a table of services and characteristics that any nearby client can list. Encryption and authentication exist in the spec, but they have to be turned on and enforced by the product. When they are not, the radio is an open API broadcasting to everyone in range, and the attacker never has to touch the device.

Step 1: Scan for the Device

Start by listening for advertisements. A scan shows the address and name of everything broadcasting nearby:

sudo bluetoothctl
[bluetooth]# scan on
Example output
Discovery started
[NEW] Device A4:C1:38:9F:11:22 SmartLock-3F
[NEW] Device 5C:F8:21:0A:3B:7E Fitness-Band

Step 2: Enumerate the GATT Table

With the address in hand, list the characteristics. This is the device’s whole interface, laid out for you:

gatttool -b A4:C1:38:9F:11:22 --characteristics
Example output
handle: 0x0024, char value handle: 0x0025, uuid: 0000ff01-0000-1000-8000-00805f9b34fb
handle: 0x0026, char value handle: 0x0027, uuid: 0000ff02-0000-1000-8000-00805f9b34fb

Two custom characteristics. Vendor-specific UUIDs like ff01 and ff02 are exactly where the interesting control and status values tend to live.

Step 3: Read and Write Characteristics

Now probe them. Reading a value sometimes hands you a secret outright; writing one sometimes triggers an action:

Anatomy of a gatttool BLE characteristic write command for unauthenticated device access
# read the status characteristic
gatttool -b A4:C1:38:9F:11:22 --char-read -a 0x0027
Example output
Characteristic value/descriptor: 31 32 33 34
# write 01 to the control characteristic
gatttool -b A4:C1:38:9F:11:22 --char-write-req -a 0x0025 -n 01
Example output
Characteristic value was written successfully

The read returned 31 32 33 34, which is the ASCII for 1234, a PIN sitting in the clear. The write actuated the lock. Neither operation required pairing, bonding, or any authentication. That is a critical finding, and it is depressingly common.

Common BLE Findings

Across BLE assessments, the same three issues come up again and again:

Three common BLE security findings: Just Works pairing, a static passkey, and an open GATT table

Defending a BLE Product

Require LE Secure Connections pairing with a real out-of-band or numeric-comparison method, and bond so the link is encrypted. More importantly, do not treat the BLE link as your only access control: authenticate sensitive actions at the application layer, so that writing a characteristic is not the same as being authorized. A lock should verify the requester, not just the radio.

Where This Fits

BLE testing, from enumerating the GATT table to proving an action can be triggered without authentication, is a standard part of a connected-product penetration test. That hands-on radio work is the kind of work we do at Berkner Tech.


References and Further Reading