Helen Sherwood-Taylor
PyCon UK
September 2016
TAKING CONTROL OF YOUR
BLUETOOTH DEVICES
BLUETOOTH
LOW ENERGY
BLE
BTLE
"Bluetooth Smart"
aka:
Part of Bluetooth 4.0
BLE FEATURES
Simple protocols
Low bandwidth
Short range
Low power
Widely used
WHY?
Fun
Control
Endless possibilities!
But... where's my API?
ATT
ATTRIBUTE PROTOCOL
Handle (e.g. 0x12)
UUID (e.g. f000ffad-0451-4000-b000-000000000000)
Properties / Permissions (e.g. 0x02)
Value
Attributes
GATT
GENERIC ATTRIBUTE PROFILE
Builds on attributes
Services / characteristics hierarchy
All contribute to device profile
STANDARD UUIDS
Defined by Bluetooth Special Interest Group (SIG)
Based on Bluetooth Base UUID
Refer to with first 32 bits
Can be looked up in spec
e.g. heart rate, wind speed, latitude
xxxxxxxx-0000-1000-8000-00805F9B34FB
VENDOR UUIDS
Refer to with full 128 bits
Chosen by the vendor
What do they mean?
INGREDIENTS
HARDWARE
Bluetooth lightbulb
Controlling device (Android phone)
ANALYSIS
File transfer (adb?)
Wireshark
CONTROL
Linux box
BlueZ
bluepy
THE APP
HCITOOL
$ hcitool lescan
LE Scan ...
88:C2:55:08:CB:77 (unknown)
88:C2:55:08:CB:77 icolorlive
Advertising / scanning
48 bit address
May require sudo
GATTTOOL
[ ][88:C2:55:08:CB:77][LE]> connect
[CON][88:C2:55:08:CB:77][LE]> characteristics
[CON][88:C2:55:08:CB:77][LE]>
handle: 0x0002, char properties: 0x02, char value handle: 0x0003, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0004, char properties: 0x02, char value handle: 0x0005, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0006, char properties: 0x0a, char value handle: 0x0007, uuid: 00002a02-0000-1000-8000-00805f9b34fb
...
handle: 0x0024, char properties: 0x0a, char value handle: 0x0025, uuid: f000ffa3-0451-4000-b000-000000000000
handle: 0x0027, char properties: 0x0a, char value handle: 0x0028, uuid: f000ffa4-0451-4000-b000-000000000000
handle: 0x002a, char properties: 0x0a, char value handle: 0x002b, uuid: f000ffa6-0451-4000-b000-000000000000
...
That's 3 t's!
GATTTOOL
[CON][88:C2:55:08:CB:77][LE]> char-read-hnd 0x3
[CON][88:C2:55:08:CB:77][LE]>
Characteristic value/descriptor: 69 63 6f 6c 6f 72 6c 69 76 65
That's 3 t's!
Read characteristic by UUID
[CON][88:C2:55:08:CB:77][LE]> char-read-uuid 0x2a00
[CON][88:C2:55:08:CB:77][LE]>
handle: 0x0003 value: 69 63 6f 6c 6f 72 6c 69 76 65
[CON][88:C2:55:08:CB:77][LE]> char-read-uuid f000ffa3-0451-4000-b000-000000000000
[CON][88:C2:55:08:CB:77][LE]>
handle: 0x0025 value: 4f 43
Read characteristic by handle
Read by vendor-defined UUID
LOG CAPTURE
Android Developer Options
Toggle
Do stuff in app
Download log
Repeat
WIRESHARK
Filter:
btl2cap.cid == 0x0004
GATTTOOL
[CON][88:C2:55:08:CB:77][LE]> char-write-cmd 0x28 ff0000
[CON][88:C2:55:08:CB:77][LE]> char-write-cmd 0x28 ffff00
[CON][88:C2:55:08:CB:77][LE]> char-write-cmd 0x28 ff00ff
PYTHON
from time import sleep
from bluepy.btle import Peripheral, ADDR_TYPE_PUBLIC
GREEN = '006600'
BLUE = '000066'
PURPLE = '660066'
addr = sys.argv[1]
def disco(sequence):
for code in sequence:
conn.writeCharacteristic(0x28, bytearray.fromhex(code))
sleep(1.0)
conn = Peripheral(addr, ADDR_TYPE_PUBLIC)
disco((GREEN, BLUE, PURPLE) * 3)
conn.disconnect()
FURTHER READING
RESOURCES
icolorlive bulb (or search for bluetooth bulb) -
Wireshark -
pyshark (python lib for processing logs) -
BlueZ -
bluepy -
https://www.amazon.co.uk/dp/B01FR6QNH0/
https://www.wireshark.org/
https://github.com/KimiNewt/pyshark
http://www.bluez.org/
https://github.com/IanHarvey/bluepy
LINKS
GATT specification: lists of UUIDs
Adafruit tutorial on BLE sniffing
Installing BlueZ on Raspberry Pi -
https://www.bluetooth.com/specifications/gatt
https://learn.adafruit.com/reverse-engineering-
a-bluetooth-low-energy-light-bulb
http://www.elinux.org/RPi_Bluetooth_LE
THANK YOU!
twitter: @helenst
github: @helenst
http://helen.st/

Taking Control of your Bluetooth Devices