Inspect Bluetooth packets¶
This should give some ideas and hints how to decode the Bluetooth protocol used by a gadget.
Tools¶
- BLE Explorer
- BLE Monitor
- nRF Toolbox (on Play Store)
- nRF Connect
- Wireshark - Network protocol analyzer
- Frida - Dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Do note, that in order to know what functions to hook into, you need to list them first. See this proof of concept code which is doing exactly that. Other way would be de-compiling the original app APK which might not be legal and thus is not adviceable.
Articles¶
- Reading Values From a BLE Device Using CSR1010 and Dragonboard 410c
- My journey towards Reverse Engineering a Smart Band - Bluetooth-LE RE - (archived)
- How I Reverse Engineered and Exploited a Smart Massager - (archived)
- Reverse Engineering BLE Devices - (archived, in PDF)
- Android reverse engineering for beginners - Frida - (archived)
- Let's Reverse Engineer an Android App! - (archived)
- Reverse Engineering Nike Run Club Android App Using Frida - (archived)
Android's Bluetooth logging¶
The most simple approach to "decode" the protocol would be sniffing packets sent by the original app. Android comes with a function to log all incoming and outgoing BT packets.
In order to capture the Bluetooth traffic, open Android's "Settings → Developer options" and check "Enable Bluetooth HCI snoop log". Then perform the action that you want to capture. After doing that, uncheck the option again.
The logging process (on Android 10) requires the following steps: 1. Enable developer options on your device. 2. Enable ADB on your device. 3. Enable Bluetooth HCI snoop log. 4. Toggle Bluetooth for logging to take effect. 5. Use original vendor app to connect to you your device, fire some commands.
Note
On some devices/Android versions the Bluetooth snoop log might be stored in a different location (e.g. /sdcard/Android/data/btsnoop_hci.log
for a Samsung Galaxy S5). If you cannot find the log file, you can find out the correct path with (ADB must be installed):
See here for further details.
Alternatively, you can dump BT log by adb shell dumpsys bluetooth_manager
:
- Copy bugreport including BT log to PC
adb bugreport
or byadb pull data/misc/bluetooth/logs/btsnoop_hci.log
- Paths can vary depending on device / android version. adb needs to run as root (
adb root
) to access /data - Find the log in the .zip package if you choose the bugreport way.
- You will find the logfile at
/sdcard/btsnoop_hci.log
.
Getting on LineageOS¶
While the above explanations are correct, getting the bt_snoop easily is a critical skill and should be as fast as possible. Pulling data with adb bugreport
, extracting the bt_snoop or even generating it with pybtsnooz.py
takes a very long time and can often result in files which actually do not contain required data. Getting the bt_snoop is super easy on a rooted phone or an open ROM, like LineageOS, which actually provides rooted adb access directly (no installation of super su needed) in the Developer options in settings:
- Enable Developer options.
- Enable Bluetooth HCI snoop log.
- Enable Rooted debugging.
- Enable root adb with
adb root
on the computer. - Get the log with
adb pull /data/misc/bluetooth/logs/btsnoop_hci.log btsnoop.log
.
To reset the log, simple erase it on the phone:
- Run
adb shell rm /data/misc/bluetooth/logs/btsnoop_hci.log
. - Disable/enable Bluetooth and then pull a new log.
Getting live bt_snoop data with Wireshark¶
Wireshark has support for live bt_snoop capture. This seems to work even on phones without root or adb root. Make first sure that bt_snoop logging is enabled:
- Enable Developer options.
- Enable Bluetooth HCI snoop log.
- Connect the phone with your computer over USB cable.
- Start Wireshark and in the menu → Capture, select "Refresh interfaces".
- Select the newly visible Android Bluetooth Btsnoop.
- Profit :).
On newer versions of Android the btsnoop port (8872) is not opened regardless of the option in Developer Options, so Wireshark won't detect it automatically. To check that this is the case use adb shell nc localhost 8871
. As a workaround you can manually redirect the BtSnoop log into the port using the following command (copied from here):
adb shell su -c "'nc -s 127.0.0.1 -p 8872 -L system/bin/tail -f -c +0 data/misc/bluetooth/logs/btsnoop_hci.log'"
If you only have adb root and no su:
adb root
adb shell "nc -s 127.0.0.1 -p 8872 -L /system/bin/tail -f -c +0 /data/misc/bluetooth/logs/btsnoop_hci.log"
Wireshark dissectors¶
Wireshark offers the possibility to define dissectors which can highlight some data, filter them, calculate them, for further analysis. See some examples of dissectors here.
Working with data¶
By using a BLE scanner (listed above), basic information like BT MAC address, supported GATT services and ATT layer communication can already be collected. Also, collect the bt_snoop data as per above.
Analyze the logs¶
Now that we have the log we can use Wireshark to read and analyze the data.
- Open the btsnoop_hci.log you just pulled with Wireshark
- It is a good idea to see timestamp of the packets, you can do this by right clicking on the columns and enabling Time. Then, in the menu: "Edit → Preferences → Appearance → Columns → Time → double click on the Type" and choose the required time format, typically one of the UTC (UTC date, as YYYY....).
- Things can be made more clear by making use of Wireshark's great filtering capabilities. For example it may be good to only check packets from smartphone to gadget at first. This can be easily achieved by adding a filter
bluetooth.dst == 78:02:xx:xx:xx:xx
with the MAC address of your gadget (which you've found earlier by using nRF). - Now you need a starting point. If you can link one easy command with it's packet you're nearly done. You could probably use the "find-my-device" command of the original vendor that lets your gadget vibrate. By firing this command often enough you may see an abnormality in the packet log with many similar packets.
- Once found a simple command and its associated packet you can use it as "marker". Make use of the packet colorization function and set up a rule for this marker packet. (e.g.
btatt contains ab:00:00:00:01:02:07:01
). - Fire a couple marker commands, then a command you want to know the packet for and afterwards some marker commands again. By varying the amount of markers you can easily differentiate between the different unknown commands.
Once you found the first functions and its associated command bytes it makes to check the existing Gadgetbridge sources. It's really likely someone already uses this protocol (Or at least a similar version). That can make things a lot easier.
Following the data¶
- In Wireshark, set a filter to
btatt
, to only see the data flow and not all other stuff - Find the place, where the phone did some action, to set something on the device (or the other way)
- Look at the
handle
andvalue
in the Bluetooth Attribute Protocol tree: - This gives you the characteristics and the data value.
Isolate parts of the captured data¶
In order to analyze data capture it is useful to isolate specific portion of the snoop. Here is one of the ways to do this. Basic capturing and exporting knowledge as describe above is presumed.
- Start the app in question, connect it to your band, go to the screen where you will want to perform the action of interest, wait for all syncing to happen.
- Capture the bt_snoop, open it in Wireshark, go to last line and note the line number.
- In the app, now perform the action of your interest, do only minimal actions, no screen switching etc.
- Capture the bt_snoop, open it in Wireshark. Go to line number as noted in step #2. Select all lines from here down (Shift + ↓). You might like to first apply the
btatt
filter, to only list relevant lines. - Export only these lines via Wireshark menu: "Export specific packets → Export as Symbian OS btsnoop → Selected packets only".
This now gives you only the performed action captured as bt_snoop. It seems, that MAC addresses are now reset to 00:00
. This is not a bad thing in order to be able to share it.