Hello, I am Sayli Ambure. I am new to infosec and have been working on web and other generic application security and IoT / Hardware has been something I always wanted to explore and I did finally try.. YaaaaY to me!!
So my first blog is going to be about Bluetooth LE (aka BLE) reversing. It’s not something too advanced or something. I am just sharing how and what I found while learning and pentesting an IoT device.
I am not going to give you a brief of how exactly BLE works because it’s already been written by so many people (Do check reference links in the bottom of blog) and i want to keep this blog short and not some TL;DR content.
So here we go….
I am going to use a very cheap and easily available smartwatch to make you understand how i reversed it and pwned it successfully.
The smartwatch i am using is fairly simple and cheap. It is branded under different names. The most common name is the M4 watch and it costs under 5$ — Chinese manufacturer.
The process I am going to show is going to be the same for different BLE devices.
1. Getting Communication data:
Now the first step is to reverse the communication from the mobile app and the device.
If you don’t have any expensive sniffer, that’s fine. Luckily android lets you sniff the Bluetooth communication.
It can be found in the developer option →BT Snoop. Way to get the PCAP depends on the mobile vendor.
Once you get your PCAP, open it in Wireshark and you will see all the Bluetooth communication. We are going to focus on only BLE part of the communication which is GATT or ATT.
Apply the filter btatt to see only the ATT protocol because we don’t need any other communication happening over Bluetooth right now.
Now you will see only the GATT based communication.
Now look for packet which says Sent Write Request, because the app sends a write request to set the time or send some notification to the device.
Once you identified the “Sent Write Request”, Select the write request opcode and apply it as a filter. Now you can easily see all the data that is being sent.
Here the important thing is to note the Handle and the Value. We’ll talk a bit on why we need it in next section.
Once that is done, You can either use scapy-radio to remove the data packet or just manually copy paste all the data and send the data to try.
I have created a python dissector to extract the required data so you can use it to perform replay attack or analyze it better.
You can get it from here:
2. Connecting to the device:
You first need to set up the Bluetooth of your host machine and see if it is working by using hciconfig command.
If you have any issues. You can use this to reset the interface
‣ hciconfig hci0 reset or hciconfig hci0 up ( hcix is the hardware interface name)
To connect to the device, I am going to use an amazing framework called as ExplIoT Framework. (You can download it from here)
Start the tool by running the command “expliot” and scan the BLE device with run ble.generic.scan
Now the MAC address of the device will be visible and can be connected.
To give a short course on BLE and how it communicates,
Three important things are Service, Characteristics and data.
- Service is like a block of memory that has a collective meaning.
- Characteristics is the memory address for each data point.
- Data is the value to control the device.
Now let’s see how we can see these things using expliot
‣ List of Services: run ble.generic.scan -a <mac address> -s
‣ List of characteristics: run ble.generic.scan -a <mac address> -c
Now if you go back to the packets, you can see “0x0e” is the handle all the data is being written to.
To write to a device command is
‣ run ble.generic.writechar -a <mac addr> -n <handle> -w <value>
3. Reversing Communication Data:
Now that we have learned about using Expliot framework to write to a device and get the packet capture, it’s time to reverse the communication. Till now the procedure is the same for any BLE device. The data format is vendor-specific and it needs to be reversed for each vendor exclusively unlike what we did till now.
One way to go about it is to send all data one by one and see if it is causing any changes in the device. In my case, it is a smart band. so typically I should be able to change the time, date or show notification or something specific to the watch.
I tried replaying all the packets and noticed one packet which changed the date and time.
Handle: 0x0e Value: ab0b0401130c030d313beb
When I tried to change the time, it wasn’t working and realized they have CRC-8 check on the packet and I need to regenerate the packet with CRC-8 for it to work.
To reverse data, I segregated it as byte and converted it into decimal and observed if it has some similarities with the changed time/date in the smartwatch.
- The first byte denotes the packet header because it is same for all.
- The second byte denotes the length of the packet.
- The third byte is still a puzzle.(Let me know if you have any idea :))
- The fourth byte means type of message, time packet or notification or something.
- The fifth byte is year.
- The sixth byte is month.
- The seventh byte is date.
- The eighth byte is Time in 24hr format.
- The ninth byte is minutes.
- The tenth byte is seconds.
- The eleventh byte is CRC Maxim.
Then, I crafted packet to change the time, date, hour, minute and seconds to 11 😛 and it worked flawlessly!
This got me excited and then I started writing script to randomly show time and dates in smartwatch.
You can see the script in this github repo.
Now the interesting part is the notification!
To successfully send the Notification we need to send two or more packets and here also we need the same CRC check to craft and send our own notification.
ab 11 17 10 02 02 04 753a5368646e646e64 2d
- The first byte is the header.
- The second byte is the size of the notification payload.
- The third byte is the size of the data.
- The Fourth byte is the type of packet.
- The fifth byte is the number of notification payloads needed.
- The sixth byte is the payload number as per fifth byte.
- The seventh byte tells what type of notification; message or whatsapp or call.
- The eighth byte is the ascii message itself.
- The last byte is the CRC MAXIM.
The watch has few more options like setting alarm and enabling lost mode. Which is going to be the same.
These are few references from where I have understood BLE internals and reversing. Adding them here in case needed.
See you next time!! 👻 Until then,