My goal is to learn how to use bleah tool to discover the possibilities of a Bluetooth BLE device and then implement my own POC tool in Python. As I currently don't have many such devices at my disposal, I chose the Suunto Heartrate Sensor. The required theoretical knowledge about how the Bluetooth operates can be found on the Bluetooth specifications page.
Enumerating the device - preparation
My first goal was to install and successfully run the bleah tool. I initially used
pip to install the
bluepy library, which turned out to be a wrong move. The tool was throwing an exception and only after I installed the
bluepy from the source it started to work.
One other thing to note was that I didn't get any errors with bleah when my Bluetooth interface was down. If you don't observe the expected behavior, make sure to check if your interface is working. Here is how to check it and how to bring it up if it is down.
sudo hciconfig-a hci0: Type: Primary Bus: USB BD Address: XX:XX:XX:XX:XX:XX ACL MTU: 1021:5 SCO MTU: 96:5 DOWN RX bytes:17681 acl:677 sco:0 events:546 errors:0 TX bytes:28534 acl:61 sco:0 commands:387 errors:0 Features: 0xff 0xfe 0x0f 0xfe 0xdb 0xff 0x7b 0x87 Packet type: DM1 DM3 DM5 DH1 DH3 DH5 HV1 HV2 HV3 Link policy: RSWITCH HOLD SNIFF Link mode: SLAVE ACCEPT > sudo hciconfighci0 up
After the Bluetooth interface was up and running, everything started working as expected and the enumeration values started showing up.
Enumerating the device - bleah
As my goal was to build very specific POC application, I started off with discovering its Bluetooth address. The Bluetooth address is a unique 48-bit identifier assigned to each Bluetooth device. It was easy to find the correct address as the bleah tool also prints out the device names and additional information.
Once I had the address, I enumerated it to get all the device profile's services. To bring some context, the profile is a simple collection of services provided by the physical device. Each service has its characteristics. The characteristics offer data and functionalities, depending on their attributes. Amongst other things, the attributes define if the characteristic can be read, written to, or perhaps be awaited to receive the notifications. Both services and characteristics are identified with unique UUID-s.
Implementing the notification reader
Figure 2: Suunto sensorOnce I had all the address data I was able to start implementing the POC application. I first wanted to implement a scanner which would return only those devices which are actually Suunto heart rate monitors. This way I could receive all available running devices' data instead of having to select which device I wanted.
Each new device would then subscribe to my callback and start writing out the heart rate. According to the bleah enumeration results, there was a NOTIFY characteristic which can give out the notifications about the heart rate. This meant I could assign a callback to this characteristic and initiate notification sending.
Assigning a callback was easy as it is directly supported by the
Once I started getting the data back, I had to do some reverse engineering. I didn't go into details and figured out only how to get the heart rate. I was receiving data with different lengths, but the most prominent one was four bytes long. I cast each byte into int and observed the values:
- The first one was always 0x16
- The second one was the heart rate
- The third one is still unknown
- The fourth one seems to be the signal strength from 0x01 to 0x04
This was a great exercise with using and reversing BLE Bluetooth devices. I intend to continue researching the Bluetooth in more security-related direction.