BLECTF低功耗蓝牙CTF change
BLECTF:低功耗蓝牙CTF change
前言
环境配置
需要的设备
- esp32(含有wifi和蓝牙模块的板子)
- CSR4.0(外接蓝牙模块)
这里需要注意的是esp32的设备需要用好一点的连接线才可以连接成功,有时候连接不成功可能是连接线的问题
https://blog.csdn.net/qq_40589912/article/details/108301290
下载ESPtools
可以直接通过apt-get安装,但是可能会存在包不对的情况,之类的
1 | sudo apt-get install esptool |
也可以直接下载github库
1 | git clone https://github.com/espressif/esptool |
烧录BLECTF
根据这个教程去烧录
https://github.com/hackgnar/ble_ctf/blob/master/docs/setup.md
首先下载blectf
1 | git clone https://github.com/hackgnar/ble_ctf.git |
然后进入blectf目录
1 | cd ble_ctf |
最后直接烧录(我前面esptools下载用的是github上的)
1 | ../esptool-master/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 |
就成功烧录了
安装hciconfig工具
我的虚拟机环境是kali
1 | apt-get install bluetooth #安装工具包 |
扫描设备&&gatttool的用法
1 | hcitool lescan -i hci0 |
![image-20240714133810878](/picture/BLECTF低功耗蓝牙CTF change/image-20240714133810878.png)
我们就 能得到对应挑战的mac地址
通过gatttool与设备交互,使用gatttool -b 78:EE:4C:01:D2:FE -I
进入交互模式
![image-20240714133925967](/picture/BLECTF低功耗蓝牙CTF change/image-20240714133925967.png)
这里简单列举gatttool的几个使用方法
1 | GATT commands |
gatttool具体的使用方法参考如下
https://blog.csdn.net/u010764600/article/details/119685484
注意事项
- 如果查看状态返回
Read LE supported states on hci0 returned status 1
表示你的蓝牙适配器不支持 BLE,正常的应该是这样的
![image-20240714133053405](/picture/BLECTF低功耗蓝牙CTF change/image-20240714133053405.png)
- 开启设备失败
1 | hciconfig hci0 up |
出现上面的情况运行 rfkill unblock all
再 hciconfig hci0 up
即可解决
- gatttools报错
1 | root@kali-vm:~# gatttool -b b4:e6:2d:96:14:7F --char-read -a 0x002a |
如果出现上述的错误,默认情况下没有打开LE。你需要运行这个来在Kali中启用它
运行下面的命令
1 | btmgmt le on |
- 扫描设备报错
1 | hcitool lescan |
出现这样的情况可能是设备有问题了,重启即可
1 | hciconfig hci0 down |
前置知识
ATTR服务
在安装好gatttool后,用primary进行探测其服务
![image-20240715100541241](/picture/BLECTF低功耗蓝牙CTF change/image-20240715100541241.png)
大致能看到如下情况,这个设备是我的小米手环设备
1 | attr handle: 0x0001, end grp handle: 0x0007 uuid: 00001800-0000-1000-8000-00805f9b34fb |
制造商名称字符串应该在 设备信息服务,其标准UUID为0x180A。我们在这一行的服务列表中看到它:
1 | attr handle: 0x0030, end grp handle: 0x0040 uuid: 0000180a-0000-1000-8000-00805f9b34fb |
该UUID的其余部分只是128位BLE基本UUID 0000XXXX-0000-1000-8000-00805f9b34fb
。不同的制造商通常会为自己的自定义服务使用自己的自定义128位基本uuid,每个服务的 XXXX
不同。
查看UUID显示的行其余部分,我们可以看到有两个额外的字段: attr handle
和 end grp handle
。BLE句柄与UUID不同:UUID定义我们要访问的属性的属性和元数据,而句柄给出特定属性的地址。在这里,我们使用服务的UUID来发现这个特定的服务是设备信息服务;现在,为了访问与其关联的数据,我们需要使用服务的列出句柄。
让我们尝试访问此服务的特征。为此,在gatttool中使用 characteristics
命令。我们需要为该服务提供两个句柄:“attr句柄”0x0010和“end grp句柄”0x0022。(这些是该服务的开始句柄和结束句柄。)
1 | [D0:62:2C:D1:C4:CB][LE]> characteristics 0x0030 0x0040 |
我们现在有了一个我们试图访问的设备信息服务的特征表:
1 | handle: 0x0031, char properties: 0x02, char value handle: 0x0032, uuid: 00002a29-0000-1000-8000-00805f9b34fb |
制造商名称字符串特征有 标准UUID 0x2A29。从上面的列表中挑选出来:
1 | handle: 0x0031, char properties: 0x02, char value handle: 0x0032, uuid: 00002a29-0000-1000-8000-00805f9b34fb |
我们现在可以通过使用 char-read-hnd
命令从列出的字符值句柄
0x0032中读取制造商名称字符串特征的值:
1 | gatttool -b D0:62:2C:D1:C4:CB --char-read -a 0x32 |
还发现了一个记录更详细的博客,感兴趣的师傅可以更详细研究一下https://epxx.co/artigos/bluetooth_gatt.html
闯关
参考这两个师傅的笔记
https://github.com/camercu/ble-ctf
https://cloud.tencent.com/developer/article/1947203
查看分数和提交flag
提交分数
1 | gatttool -b device_mac --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf '\n' |
提交结果
1 | gatttool -b de:ad:be:ef:be:f1 --char-write-req -a 0x002c -n $(echo -n "some flag value"|xxd -ps) |
第一关
Flag one is a gift! You can only obtain it by reading this document or peaking at the source code. In short, this flag is to get you familiar with doing a simple write to a BLE handle. Do the following to get your first flag. Make sure you replace the MAC address in the examples below with your devices mac address!
First, check out your score:
gatttool -b de:ad:be:ef:be:f1 –char-read -a 0x002a|awk -F’:’ ‘{print $2}’|tr -d ‘ ‘|xxd -r -p;printf ‘\n’
Next, lets sumbmit the following flag. gatttool -b de:ad:be:ef:be:f1 –char-write-req -a 0x002c -n $(echo -n “12345678901234567890”|xxd -ps)
Finaly, check out your score again to see your flag got accepted:
gatttool -b de:ad:be:ef:be:f1 –char-read -a 0x002a|awk -F’:’ ‘{print $2}’|tr -d ‘ ‘|xxd -r -p;printf ‘\n’
送分题,教你怎么提交 flag 的,使用 –char-write-req 向句柄 44 提交 12345678901234567890
即可
1 | gatttool -b 78:EE:4C:01:D2:FE --char-write-req -a 0x002c -n $(echo -n "12345678901234567890"|xxd -ps) |
![image-20240714141151148](/picture/BLECTF低功耗蓝牙CTF change/image-20240714141151148.png)
成功
第二关
Check out the ascii value of handle 0x002e and submit it to the flag submision handle 0x002c. If you are using gatttool, make sure you convert it to hex with xxd. If you are using bleah, you can send it as a string value.
想让我们读取0x002e句柄的值,然后传递给0x002c句柄
1 | gatttool -b 78:EE:4C:01:D2:FE --char-read -a 0x002e |
![image-20240714142925657](/picture/BLECTF低功耗蓝牙CTF change/image-20240714142925657.png)
成功
第三关
Check out the ascii value of handle 0x0030. Do what it tells you and submit the flag you find to 0x002c.
让我们检查 0x0030 这个句柄的值,看看想让我们做啥,查看后转为 ASCII 是 MD5 of Device Name,设备名称自然就是 BLECTF 了,取其 MD5 值的前 20 个字符
![image-20240714143121022](/picture/BLECTF低功耗蓝牙CTF change/image-20240714143121022.png)
1 | gatttool -b 78:EE:4C:01:D2:FE --char-read -a 0x0030 |
![image-20240714143255015](/picture/BLECTF低功耗蓝牙CTF change/image-20240714143255015.png)
第四关
Bluetooth GATT services provide some extra device attributes. Try finding the value of the Generic Access -> Device Name.
蓝牙GATT服务提供了一些额外的设备属性。尝试查找通用访问->设备名称的值。
“服务”是数据片段的集合(每个数据点称为“特征”),用于完成特定功能或提供设备的特征。根据蓝牙核心规范,通用访问服务(或者更正式地说,“通用访问配置文件/GAP服务”)是所有GATT服务器的强制性服务,它具有某些必需的特征,包括设备名称。蓝牙分配号码文档指定设备名称特征具有UUID 0x2A00
(参见前面的挑战以获得关于UUID格式的更详细解释)。
就是让我们找到设备名称的值,我通过手机的LightBlue找到了对应的设备名称
![image-20240714144458362](/picture/BLECTF低功耗蓝牙CTF change/image-20240714144458362.png)
或者读取UUID开头为2A00
的句柄
![image-20240714211542888](/picture/BLECTF低功耗蓝牙CTF change/image-20240714211542888.png)
通过句柄0x16读取
1 | gatttool -b 78:EE:4C:01:D2:FE --char-read -a 0x0016 |
![image-20240714145406163](/picture/BLECTF低功耗蓝牙CTF change/image-20240714145406163.png)
第五关
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.
先读 0x0032 句柄的内容是 Write anything here,那就随便写点东西
![image-20240714145921042](/picture/BLECTF低功耗蓝牙CTF change/image-20240714145921042.png)
成功读取到flag,然后0x2c句柄提交flag即可
![image-20240714150116960](/picture/BLECTF低功耗蓝牙CTF change/image-20240714150116960.png)
成功
第六关
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
按照读取句柄0x0034的说明操作。请记住,有些工具只写十六进制值,而其他工具提供了写十六进制或ascii的方法。
按照要求写“yo”到0x0034
![image-20240714150808693](/picture/BLECTF低功耗蓝牙CTF change/image-20240714150808693.png)
得到flag,并提交
![image-20240714150915649](/picture/BLECTF低功耗蓝牙CTF change/image-20240714150915649.png)
![image-20240714150923993](/picture/BLECTF低功耗蓝牙CTF change/image-20240714150923993.png)
成功
第七关
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
按照读取句柄0x0036的说明操作。请记住,有些工具只写十六进制值,而其他工具提供了写十六进制或ascii的方法
直接不转换,直接传递即可
1 | gatttool -b 78:EE:4C:01:D2:FE --char-read -a 0x0036 | cut -d ":" -f 2 | xxd -r -p |
![image-20240714151510853](/picture/BLECTF低功耗蓝牙CTF change/image-20240714151510853.png)
第八关
Follow the instructions found from reading handle 0x0038. Pay attention to handles here. Keep in mind handles can be refrenced by integer or hex. Most tools such as gatttool and bleah allow you to specify handles both ways.
按照读取句柄0x0038的说明操作。注意这里的句柄。请记住句柄可以被整数或十六进制引用。大多数工具(如gatttool和bleah)允许您以两种方式指定句柄。
直接按照要求写入
1 | sudo gatttool -b 78:EE:4C:01:D2:FE --char-write-req -a 58 -n c9 |
![image-20240714152448156](/picture/BLECTF低功耗蓝牙CTF change/image-20240714152448156.png)
![image-20240714152601506](/picture/BLECTF低功耗蓝牙CTF change/image-20240714152601506.png)
成功
—————————————————————–分割线
因为后面的实验是我吃了晚饭回来做的,设备被我关掉了直接重启了,所以后面的分数都是从0开始的了
![image-20240714201940857](/picture/BLECTF低功耗蓝牙CTF change/image-20240714201940857.png)
第九关
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.
看看句柄0x003c,并按照它所说的去做。你应该为这个问题编写一个解决方案。还要记住,有些工具编写速度比其他工具快。
句柄0x003C为暴力破解我的值 00 到 ff
让我们对它进行暴力破解,直接用 python 写个循环就行了
python 中有一个 zfill 方法用来给字符串前面补 0,n.zfill(2) 表示 n 要是不足两个字符的话就左边补零
1 | import os |
![image-20240714202225294](/picture/BLECTF低功耗蓝牙CTF change/image-20240714202225294.png)
![image-20240714202723174](/picture/BLECTF低功耗蓝牙CTF change/image-20240714202723174.png)
读取flag和提交flag
![image-20240714203428350](/picture/BLECTF低功耗蓝牙CTF change/image-20240714203428350.png)
成功
第十关
Talke 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.
看一下句柄0x003e并按照它所说的去做。请记住,在进行读写操作时,有些工具的连接速度比其他工具要快。这与工具提供的功能或它如何在主机操作系统上使用缓存的BT连接有关。尝试为这个标志测试不同的工具。找到最快的方法后,编写一个脚本或bash 1命令行来完成任务。仅供参考,一旦运行,如果操作正确,这个任务大约需要90秒才能完成。
Read me 1000 times 读 1000 次?还是用 python 循环执行系统命令不就行了?
1 | import os |
![image-20240714203930229](/picture/BLECTF低功耗蓝牙CTF change/image-20240714203930229.png)
![image-20240714204006691](/picture/BLECTF低功耗蓝牙CTF change/image-20240714204006691.png)
成功
第十一关
Check out handle 0x0040 and google search gatt notify. Some tools like gatttool have the ability to subscribe to gatt notifications
检查句柄0x0040然后谷歌搜索gatt notify。一些工具,如gatttool,具有订阅gatt notifications的功能
0x0040 这个句柄给出的提示信息是:Listen to me for a single notification,用 gatttool 监听从蓝牙发送过来通知(notification)的数据,涉及到 GATT 的通知,客户端(kali)可以向服务端(esp32)请求通知一项特征值,当该特征可用时服务端会通知客户端,通知(notification)不需要客户端回应 ACK
1 | gatttool -b 78:EE:4C:01:D2:FE --char-write-req -a 0x0040 -n 00 --listen |
![image-20240714205213437](/picture/BLECTF低功耗蓝牙CTF change/image-20240714205213437.png)
提交flag
![image-20240714205201379](/picture/BLECTF低功耗蓝牙CTF change/image-20240714205201379.png)
第十二关
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.
检查处理0x0042和谷歌搜索gatt指示。对于单个响应指示消息,如此挑战,诸如gatttool之类的工具可以很好地工作。
0x0042 句柄说:Listen to handle 0x0044 for a single indication,这个会从 ESP32 发送指示给我们,与上一个的区别在于这一个需要回应 ACK
![image-20240714205521463](/picture/BLECTF低功耗蓝牙CTF change/image-20240714205521463.png)
1 | gatttool -b 78:EE:4C:01:D2:FE --char-write-req -a 0x0044 -n 00 --listen |
![image-20240714205836116](/picture/BLECTF低功耗蓝牙CTF change/image-20240714205836116.png)
第十三关
Check out handle 0x0046 and do what it says. Keep in mind that this notification clallange requires you to recieve multiple responses in order to complete.
检查句柄0x0046并按照它所说的去做。请记住,此通知请求需要您收到多个响应才能完成。
1 | gatttool -b 78:EE:4C:01:D2:FE --char-write-req -a 0x0046 -n 00 --listen |
![image-20240714210344515](/picture/BLECTF低功耗蓝牙CTF change/image-20240714210344515.png)
![image-20240714210306626](/picture/BLECTF低功耗蓝牙CTF change/image-20240714210306626.png)
提交flag
![image-20240714210423421](/picture/BLECTF低功耗蓝牙CTF change/image-20240714210423421.png)
第十四关
Check out handle 0x0042(源文件应该写错了,0x0048)) and google search gatt indicate. Keep in mind that this chalange will require you to parse multiple indicate responses in order to complete the chalange.
检查处理0x0042(源文件应该写错了,0x0048)和谷歌搜索gatt指示。请记住,为了完成更改,此更改将要求您解析多个指示响应。
0x0048 说:Listen to handle 0x004a for multi indications,跟十二关一样,就是等一会就出来了
1 | gatttool -b 78:EE:4C:01:D2:FE --char-write-req -a 0x004a -n 00 --listen |
![image-20240714210748968](/picture/BLECTF低功耗蓝牙CTF change/image-20240714210748968.png)
![image-20240714210841887](/picture/BLECTF低功耗蓝牙CTF change/image-20240714210841887.png)
第十五关
Check out handle 0x004c and do what it says. Much like ethernet or wifi devices, you can also change your bluetooth devices mac address.
检查句柄0x004c并按照它所说的去做。就像以太网或wifi设备一样,您也可以更改蓝牙设备的mac地址。
0x004c 这个句柄说:Connect with BT MAC address 11:22:33:44:55:66 希望我们用指定的 MAC 地址去连接。
这里列举几个方法把
- HCI 命令
网上找到了这一篇教程可以通过设置HCI的OGF和OCF进行修改,但是貌似和厂商的设备有关系。
用hcitool cmd
向蓝牙设备发送任意 HCI 命令。我不知道有哪些命令是可行的,所以查找这些命令,我找到了这个列表:HCI 命令列表。我也不明白 OGF 和 OCF 对于 HCI 命令的含义,所以我查了一下,在这里找到了一个很好的解释,它实际上直接来自蓝牙规范。
https://community.murata.com/s/article/Drill-down-HCI-Commands-and-Setting-BD-ADDR
1 | $ sudo hcitool cmd 0x3f 0x001 0x66 0x55 0x44 0x33 0x22 0x11 |
但是我测试没成功,应该是我的设备的OGF和那个师傅的不一样
- bdaddr 修改mac地址
网上搜到可以使用 bdaddr 去修改 MAC 地址,如果 make 的时候报错了,缺少 bluetooth/bluetooth.h 去安装依赖:
1 | sudo apt-get install libbluetooth-dev |
尽管这个工具说成功了,但并没有改掉,这个工具的 issue 也说 CSR 的设备有这个问题,暂时没有得到解决,另外 spooftooph 这个工具也不行,spooftooph这个工具应该是基于经典蓝牙的,而且dbaddr已经合并到里面里面去了
![img](/picture/BLECTF低功耗蓝牙CTF change/0020f5cac65a6ac1f37457525e0f896c.png)
直接提交flag
![image-20240715131453075](/picture/BLECTF低功耗蓝牙CTF change/image-20240715131453075.png)
成功,这里又重启了一次,所以重新开始了
第十六关
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. Try using gatttool’s interactive mode for this task. By default, the BLECTF server is set to force an MTU size of 20. The server will listen for MTU negotiations, and look at them, but we dont really change the MTU in the code. We just trigger the flag code if you trigger an MTU event with the value specified in handle 0x0048. GLHF!
读取句柄0x0048(源文件应该写错了,0x004e)并按照它所说的去做。设置MTU可能是一件棘手的事情。有些工具可能提供mtu标志,但它们似乎并没有真正触发服务器上的mtu协商。尝试使用gatttool的交互模式来完成此任务。缺省情况下,BLECTF服务器强制设置MTU值为20。服务器将监听MTU协商,并查看它们,但我们并没有在代码中真正改变MTU。如果你用句柄0x0048中指定的值触发MTU事件,我们只触发标志代码。GLHF !
句柄 0x004e 说:Set your connection MTU to 444,使用 -m 参数 指定 MTU 大小为 444,但是不起效果,使用交互模式指定
![image-20240715132021352](/picture/BLECTF低功耗蓝牙CTF change/image-20240715132021352.png)
提交flag
![image-20240715132056895](/picture/BLECTF低功耗蓝牙CTF change/image-20240715132056895.png)
第十七关
Check out handle 0x0050 and do what it says. This chalange differs from other write chalanges as your tool that does the write needs to have write response ack messages implemente correctly. This flag is also tricky as the flag will come back as notification response data even though there is no “NOTIFY” property.
检查句柄0x0050并按照它所说的去做。这种更改与其他写更改不同,因为执行写操作的工具需要正确实现写响应返回消息。这个标志也很棘手,因为即使没有“NOTIFY”属性,该标志也会作为通知响应数据返回。
这些说明比实际挑战更令人生畏。不确定gatttool
这是否只是“正确实施”还是什么。但只需要写入“hello”并重新读取句柄。我不明白的是,为什么标志从读取中返回,而提示说它应该作为通知响应返回。
感觉和前面的写入数据没什么区别
![image-20240715132441561](/picture/BLECTF低功耗蓝牙CTF change/image-20240715132441561.png)
![image-20240715133141405](/picture/BLECTF低功耗蓝牙CTF change/image-20240715133141405.png)
第十八关
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!
看看句柄0x0052。注意它没有notify属性。无论如何,在这里写一篇文章并收听通知!事情并不总是表里如一!
直接监听就行了,说是没有消息的,但是还是可以监听到
![image-20240715132956727](/picture/BLECTF低功耗蓝牙CTF change/image-20240715132956727.png)
![image-20240715133205643](/picture/BLECTF低功耗蓝牙CTF change/image-20240715133205643.png)
![image-20240715133149981](/picture/BLECTF低功耗蓝牙CTF change/image-20240715133149981.png)
第十九关
Check out all of the handle properties on 0x0054! Poke around with all of them and find pieces to your flag.
查看0x0054上的所有句柄属性!把他们都搜一遍,找到你的旗子的碎片。
查看属性
https://docs.silabs.com/bluetooth/3.2/group-sl-bt-gattdb-characteristic-properties
属性值0x9b的二进制形式为 1001 1011
。查看属性标志,它似乎有EXTENDED PROPERTIES (0x80)、NOTIFY (0x10)、WRITE (0x8)和READ (0x2)。可能也RELIABLE_WRITE (0x101)?
![image-20240715133543094](/picture/BLECTF低功耗蓝牙CTF change/image-20240715133543094.png)
先监听然后再查看即可
![image-20240715133709823](/picture/BLECTF低功耗蓝牙CTF change/image-20240715133709823.png)
提交flag
![image-20240715133812776](/picture/BLECTF低功耗蓝牙CTF change/image-20240715133812776.png)
第二十关
Figure out the authors twitter handle and do what 0x0056 tells you to do!
找出作者的twitter句柄,并按照0x0056告诉您的去做!
社工,直接看作者的简介或者该项目的README即可
1 | echo -n "@hackgnar" | md5sum | head -c 20 |
![image-20240715134229707](/picture/BLECTF低功耗蓝牙CTF change/image-20240715134229707.png)
完结
结束了BLECTF的学习,简单来说,这个挑战可以简单了解关于BLE的一些东西,但仅仅是简单了解,要获取更多知识应该去看更多博客或者文献