Bluetooth Low Energy (BLE) is a wireless communication technology designed for short-range, low-power communication between devices. It is a subset of the Bluetooth standard but optimized for minimal power consumption, making it ideal for battery-powered devices. BLE operates in the 2.4 GHz ISM (Industrial, Scientific, and Medical) band.
In this article, we will be going through the Bluetooth Low Energy Capture the Flag, which is available here: https://github.com/hackgnar/ble_ctf.
BLE Terminology
GATT is a protocol that defines how data is exchanged between devices over a BLE connection. A GATT (Generic Attribute Profile) characteristic value is a piece of data that a Bluetooth Low Energy (BLE) device provides through its GATT server.
The GATT protocol organizes data into services, characteristics, and descriptors:
- Services: A collection of related characteristics and descriptors. For example, a Heart Rate Service might include characteristics like heart rate measurement and body sensor location.
- Characteristics: Represent individual pieces of data that are transmitted between devices. A characteristic is defined by:
- A UUID (Universally Unique Identifier) that specifies what kind of data it represents (e.g., a heart rate measurement, temperature, etc.).
- A value that holds the actual data (e.g., a numerical value like heart rate, a string like device name, etc.).
- Descriptors: Provide additional information about a characteristic, like its range, units, or other metadata.
Setting up the CTF
Setting up the CTF environment requires an ESP32 micro-controller. More information about setting this up can be found here. Once your development environment is setup, you can install pre-made ble_ctf images using the following commands.
git clone https://github.com/hackgnar/ble_ctf
~/ble_ctf$ sudo python3 /home/user/esp/esp-idf/components/esptool_py/esptool/esptool.py -p /dev/ttyUSB0 -b 460800 --before default_reset --after hard_reset --chip esp32 write_flash --flash_mode dio --flash_size 2MB --flash_freq 40m 0x1000 build/bootloader/bootloader.bin 0x8000 build/partition_table/partition-table.bin 0x10000 build/ble_ctf.bin
esptool.py v4.7.0
Serial port /dev/ttyUSB0
Connecting....
Chip is ESP32-D0WDQ6 (revision v1.0)
Features: WiFi, BT, Dual Core, 240MHz, VRef calibration in efuse, Coding Scheme None
Crystal is 40MHz
MAC: 0c:b8:15:c5:0c:04
Uploading stub...
Running stub...
Stub running...
Changing baud rate to 460800
Changed.
Configuring flash size...
Flash will be erased from 0x00001000 to 0x00007fff...
Flash will be erased from 0x00008000 to 0x00008fff...
Flash will be erased from 0x00010000 to 0x000cafff...
Compressed 26464 bytes to 16501...
Wrote 26464 bytes (16501 compressed) at 0x00001000 in 0.9 seconds (effective 242.5 kbit/s)...
Hash of data verified.
Compressed 3072 bytes to 103...
Wrote 3072 bytes (103 compressed) at 0x00008000 in 0.1 seconds (effective 323.3 kbit/s)...
Hash of data verified.
Compressed 765904 bytes to 452895...
Wrote 765904 bytes (452895 compressed) at 0x00010000 in 10.7 seconds (effective 574.6 kbit/s)...
Hash of data verified.
Leaving...
Hard resetting via RTS pin...
Getting Started
First, verify you can see the BLE_CTF system.
sudo rfkill list all
0: hci0: Bluetooth
Soft blocked: no
Hard blocked: no
sudo rfkill unblock all
sudo hciconfig hci0 up
sudo hcitool lescan
LE Scan ...
0C:B8:15:C5:0C:06 BLECTF
0C:B8:15:C5:0C:06 (unknown)
0C:B8:15:C5:0C:06 BLECTF
The following command will allow you to check the current score. As we can see, there are 20 flags to collect in total.
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score: 0/20
Flag 1
This flag is provided by the ble_ctf developer to get you familiar with submitting flags. The solution is listed in the readme.
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "12345678901234567890"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:1 /20
I’ll include the hints provided for future flags, since they are not really possible without them.
Flag 2
Hint: “Check out the ascii value of handle 0x002e and submit it to the flag submission handle 0x002c.”
This is just getting us started with reading and writing handles.
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002e|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
d205303e099ceff44835
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "d205303e099ceff44835"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:2 /20
Flag 3
Hint: “Check out the ascii value of handle 0x0030. Do what it tells you and submit the flag you find to 0x002c.”
This is straightforward, but it’s worth noting that BLE has a limit of 20 bytes, so the MD5 checksum we generate needs to be truncated.
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0030|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
MD5 of Device Name
echo -n "BLECTF" | md5sum
5cd56d74049ae40f442ece036c6f4f06 -
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "5cd56d74049ae40f442e"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:3 /20
Flag 4
Hint: “Bluetooth GATT services provide some extra device attributes. Try finding the value of the Generic Access -> Device Name.”
Based on the BLE standards the UUID we’re looking for should be 0x2A00 for device name.
The primary command in gattool lists primary services, and their associated handles. We can then use the char-desc command to list the service descriptors, and their UUID values.
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> primary
attr handle: 0x0001, end grp handle: 0x0005 uuid: 00001801-0000-1000-8000-00805f9b34fb
attr handle: 0x0014, end grp handle: 0x001c uuid: 00001800-0000-1000-8000-00805f9b34fb
attr handle: 0x0028, end grp handle: 0xffff uuid: 000000ff-0000-1000-8000-00805f9b34fb
[0C:B8:15:C5:0C:06][LE]> char-desc 0x0001 0x0005
handle: 0x0001, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0002, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0003, uuid: 00002a05-0000-1000-8000-00805f9b34fb
handle: 0x0004, uuid: 00002902-0000-1000-8000-00805f9b34fb
[0C:B8:15:C5:0C:06][LE]> char-desc 0x0014 0x001c
handle: 0x0014, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0015, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0016, uuid: 00002a00-0000-1000-8000-00805f9b34fb
handle: 0x0017, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x0018, uuid: 00002a01-0000-1000-8000-00805f9b34fb
handle: 0x0019, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x001a, uuid: 00002aa6-0000-1000-8000-00805f9b34fb
[0C:B8:15:C5:0C:06][LE]> char-desc 0x0028 0xffff
handle: 0x0028, uuid: 00002800-0000-1000-8000-00805f9b34fb
handle: 0x0029, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x002a, uuid: 0000ff01-0000-1000-8000-00805f9b34fb
handle: 0x002b, uuid: 00002803-0000-1000-8000-00805f9b34fb
handle: 0x002c, uuid: 0000ff02-0000-1000-8000-00805f9b34fb
[0C:B8:15:C5:0C:06][LE]> char-read-hnd 0x16
Characteristic value/descriptor: 32 62 30 30 30 34 32 66 37 34 38 31 63 37 62 30 35 36 63 34 62 34 31 30 64 32 38 66 33 33 63 66
We can then convert the value to the flag format and submit it.
echo -n "32 62 30 30 30 34 32 66 37 34 38 31 63 37 62 30 35 36 63 34 62 34 31 30 64 32 38 66 33 33 63 66" | xxd -r -p;printf '\n'
2b00042f7481c7b056c4b410d28f33cf
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "2b00042f7481c7b056c4"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:4 /20
Flag 5
Hint: “Read handle 0032 and do what it says. Notice that its not telling you to write to the flag handle as you have been. When you find the flag, go ahead and write it to the flag handle you have used in the past flags.”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0032|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Write anything here
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x0032 -n $(echo -n "bordergate"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0032|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
3873c0270763568cf7aa
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "3873c0270763568cf7aa"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:5 /20
Flag 6
Hint: “Follow the instructions found from reading handle 0x0034. Keep in mind that some tools only write hex values while other provide methods for writing either hex or ascii”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0034|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Write the ascii value "yo" here
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x0034 -n $(echo -n "yo"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0034|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
c55c6314b3db0a6128af
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "c55c6314b3db0a6128af"|xxd -ps)
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:6 /20
Flag 7
Hint: “Follow the instructions found from reading handle 0x0036. Keep in mind that some tools only write hex values while other provide methods for writing either hex or ascii”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0036|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Write the hex value 0x07 here
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x0036 -n 07
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0036|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
1179080b29f8da16ad66
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "1179080b29f8da16ad66"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:7 /20
Flag 8
Hint: “Follow the instructions found from reading handle 0x0038. Pay attention to handles here. Keep in mind handles can be referenced by integer or hex. Most tools such as gatttool and bleah allow you to specify handles both ways.”
The only trick here is we need to convert decimal 58 to it’s hex equivalent of 0x3a.
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0038|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Write 0xC9 to handle 58
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x003a -n c9
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0038|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
f8b136d937fad6a2be9f
─$ gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "f8b136d937fad6a2be9f"|xxd -ps)
Characteristic value was written successfully
┌──(kali㉿arm64)-[~]
└─$ gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:8 /20
Flag 9
Hint: “Take a look at handle 0x003c and do what it says. You should script up a solution for this one. Also keep in mind that some tools write faster than others.”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x003c|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Brute force my value 00 to ff
We can use bash to automate sending the required commands.
#!/bin/bash
DEVICE="0C:B8:15:C5:0C:06"
HANDLE="0x003c"
# Loop over values from 00 to FF
for i in {0..255}; do
value=$(printf "%02x" $i)
echo "Sending value $value"
gatttool -b $DEVICE --char-write-req -a $HANDLE -n $value
sleep 0.1
done
After running this, we can see the value has been set.
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x003c|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
933c1fcfa8ed52d2ec05
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "933c1fcfa8ed52d2ec05"|xxd -ps)
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:9 /20
Flag 10
Hint: “Take a look at handle 0x003e and do what it says. Keep in mind that some tools have better connection speeds than other for doing reads and writes. This has to do with the functionality the tool provides or how it uses cached BT connections on the host OS. Try testing different tools for this flag. Once you find the fastest one, whip up a script or bash 1 liner to complete the task. FYI, once running, this task takes roughly 90 seconds to complete if done right.”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x003e|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Read me 1000 times
Another bash loop should do the job.
#!/bin/bash
DEVICE="0C:B8:15:C5:0C:06"
HANDLE="0x003e"
for i in {0..1000}; do
gatttool -b $DEVICE --char-read -a $HANDLE|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
done
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "6ffcd214ffebdc0d069e"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:10/20
Flag 11
Hint: “Check out handle 0x0040 and google search gatt notify. Some tools like gatttool have the ability to subscribe to gatt notifications”.
Enabling gatt notifications just requires writing the value of 0x01 to a handle.
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> char-write-req 0x40 01
Characteristic value was written successfully
Notification handle = 0x0040 value: 35 65 63 33 37 37 32 62 63 64 30 30 63 66 30 36 64 38 65 62
echo -n "35 65 63 33 37 37 32 62 63 64 30 30 63 66 30 36 64 38 65 62 " | xxd -r -p;printf '\n'
5ec3772bcd00cf06d8eb
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "5ec3772bcd00cf06d8eb"|xxd -ps)
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:11/20
Flag 12
Hint: “Check out handle 0x0042 and google search gatt indicate. For single response indicate messages, like this challenge, tools such as gatttool will work just fine.”
A BLE Single Response Indicate Message is a one-time indication (with acknowledgment required) sent from a BLE peripheral to a central device. Again writing 0x01 to a handle should work here.
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> char-write-req 0x44 01
Characteristic value was written successfully
Indication handle = 0x0044 value: 63 37 62 38 36 64 64 31 32 31 38 34 38 63 37 37 63 31 31 33
echo -n "63 37 62 38 36 64 64 31 32 31 38 34 38 63 37 37 63 31 31 33" | xxd -r -p;printf '\n'
c7b86dd121848c77c113
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "c7b86dd121848c77c113"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:12/20
Flag 13
Hint: “Check out handle 0x0046 and do what it says. Keep in mind that this notification challenge requires you to receive multiple responses in order to complete.“
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0046|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Listen to me for multi notifications
Similar to before, enable notifications by writing 0x01 to the handle.
┌──(kali㉿arm64)-[~]
└─$ gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> char-write-req 0x0046 01
Characteristic value was written successfully
Notification handle = 0x0046 value: 55 20 6e 6f 20 77 61 6e 74 20 74 68 69 73 20 6d 73 67 00 00
Notification handle = 0x0046 value: 63 39 34 35 37 64 65 35 66 64 38 63 61 66 65 33 34 39 66 64
Notification handle = 0x0046 value: 63 39 34 35 37 64 65 35 66 64 38 63 61 66 65 33 34 39 66 64
Notification handle = 0x0046 value: 63 39 34 35 37 64 65 35 66 64 38 63 61 66 65 33 34 39 66 64
echo -n "63 39 34 35 37 64 65 35 66 64 38 63 61 66 65 33 34 39 66 64" | xxd -r -p;printf '\n'
c9457de5fd8cafe349fd
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "c9457de5fd8cafe349fd"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:13/20
Flag 14
Hint: “Check out handle 0x0042 and google search gatt indicate. Keep in mind that this challenge will require you to parse multiple indicate responses in order to complete the challenge.”
I think this hint is incorrect, and should be instructing you to get handle 0x0048.
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0048|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Listen to handle 0x004a for multi indications
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> char-write-req 0x004a 01
Characteristic value was written successfully
Indication handle = 0x004a value: 55 20 6e 6f 20 77 61 6e 74 20 74 68 69 73 20 6d 73 67 00 00
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
Indication handle = 0x004a value: 62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61
echo -n "62 36 66 33 61 34 37 66 32 30 37 64 33 38 65 31 36 66 66 61 " | xxd -r -p;printf '\n'
b6f3a47f207d38e16ffa
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "b6f3a47f207d38e16ffa"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:14/20
Flag 15
Hint: “Check out handle 0x004c and do what it says. Much like ethernet or wifi devices, you can also change your bluetooth devices mac address.”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x004c|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Connect with BT MAC address 11:22:33:44:55:66
It turns out the Bluetooth adapter I was using does not support changing it’s MAC address.
sudo spooftooph -i hci0 -a 11:22:33:44:55:66
Manufacturer: Cypress Semiconductor (305)
Device address: E4:5F:01:AE:1D:92
Unsupported manufacturer
I added a different adapter to the system, which then worked.
sudo spooftooph -i hci1 -a 11:22:33:44:55:66
Manufacturer: Cambridge Silicon Radio (10)
Device address: 00:1A:7D:DA:71:13
New BD address: 11:22:33:44:55:66
Address changed
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x004c|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
aca16920583e42bdcf5f
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "aca16920583e42bdcf5f"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:15/20
Flag 16
Hint: “Read handle 0x0048 and do what it says. Setting MTU can be a tricky thing. Some tools may provide mtu flags, but they dont seem to really trigger MTU negotiations on servers.”
gatttool -b 0C:B8:15:C5:0C:06 --mtu 444 --char-read -a 0x004e|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n' #
Set your connection MTU to 444
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> mtu 444
MTU was exchanged successfully: 444
[0C:B8:15:C5:0C:06][LE]> char-read-hnd 0x004e
Characteristic value/descriptor: 62 31 65 34 30 39 65 35 61 34 65 61 66 39 66 65 35 31 35 38
echo -n "62 31 65 34 30 39 65 35 61 34 65 61 66 39 66 65 35 31 35 38" | xxd -r -p;printf '\n'
b1e409e5a4eaf9fe5158
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "b1e409e5a4eaf9fe5158"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:16/20
Flag 17
Hint: “Check out handle 0x0050 and do what it says. This challenge differs from other write challenges as your tool that does the write needs to have write response ack messages implemented correctly. This flag is also tricky as the flag will come back as notification response data even though there is no “NOTIFY” property.”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0050|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Write+resp 'hello'
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x0050 --value=$(echo -n "hello"|xxd -p)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0050|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
d41d8cd98f00b204e980
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "d41d8cd98f00b204e980"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:17/20
Flag 18
Hint: “Take a look at handle 0x0052. Notice it does not have a notify property. Do a write here and listen for notifications anyways! Things are not always what they seem!”
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x0052|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
No notifications here! really?
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> char-write-req 0x52 01
Characteristic value was written successfully
Notification handle = 0x0052 value: 66 63 39 32 30 63 36 38 62 36 30 30 36 31 36 39 34 37 37 62
echo -n "66 63 39 32 30 63 36 38 62 36 30 30 36 31 36 39 34 37 37 62" | xxd -r -p;printf '\n'
fc920c68b6006169477b
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "fc920c68b6006169477b"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:18/20
Flag 19
Hint: “Check out all of the handle properties on 0x0054! Poke around with all of them and find pieces to your flag.”
For this, we just need to make a read and write request of 0x0054 and combine the output.
gatttool -b 0C:B8:15:C5:0C:06 -I
[0C:B8:15:C5:0C:06][LE]> connect
Attempting to connect to 0C:B8:15:C5:0C:06
Connection successful
[0C:B8:15:C5:0C:06][LE]> char-write-req 0x54 01
Characteristic value was written successfully
Notification handle = 0x0054 value: 30 37 65 34 61 30 63 63 34 38
[0C:B8:15:C5:0C:06][LE]> char-read-hnd 0x54
Characteristic value/descriptor: 66 62 62 39 36 36 39 35 38 66
echo -n "66 62 62 39 36 36 39 35 38 66 30 37 65 34 61 30 63 63 34 38" | xxd -r -p;printf '\n'
fbb966958f07e4a0cc48
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "fbb966958f07e4a0cc48"|xxd -ps)
Characteristic value was written successfully
gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:19/20
Flag 20
Hint: “Figure out the authors twitter handle and do what 0x0056 tells you to do!”
echo -n "@hackgnar" | md5sum | head -c 20
d953bfb9846acc2e15ee
gatttool -b 0C:B8:15:C5:0C:06 --char-write-req -a 0x002c -n $(echo -n "d953bfb9846acc2e15ee"|xxd -ps)
Characteristic value was written successfully gatttool -b 0C:B8:15:C5:0C:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n'
Score:20/20
In Conclusion
That was quite a lot of steps, primarily focusing on interacting with GATT services. The author of BLE_CTF has made a follow up, BLE CTF Infinity.