首页
社区
课程
招聘
[原创]通过BLECTF入门BLE
发表于: 2024-4-13 11:57 11134

[原创]通过BLECTF入门BLE

2024-4-13 11:57
11134

iot小白最近入门BLE,看到yichen115师傅关于BLECTF的文章,感觉挺不错的,同时去年该项目有了更新,就自己试着做了做。并且针对yichen115师傅文章没写的地方进行补充。

首先你得有一块 esp32 的板子跟一个支持linux平台的蓝牙适配器或者USB加密狗

安装 esptool 工具,这是一个基于 Python、开源、独立于平台的实用程序,用于与 Espressif 芯片中的 ROM 引导加载程序进行通信。我们得用它来烧录

构建 ble_ctf 项目,/dev/ttyUSB0 是我们的串口名称

在打开蓝牙设备后,就可以使用 hcitool 工具来对 BLE 设备进行控制

这个项目就需要使用 hcitool 搜索 BLE 设备来找到我们蓝牙设备的 MAC 地址

Untitled

通用属性配置文件(GATT) 详细描述了 BLE 设备建立连接后如何传输属性(数据),其中有三个相当重要的概念:Profile(配置文件)、Service(服务)、Characteristics(特征) ,它们可以抽象成以下包含关系:

Untitled

首先 GATT 主要是负责在两个已经连接的设备交互数据,定义了 BLE 网络堆栈的一般拓扑的 GAP 层把 BLE 设备区分为主机 Master(Central) 和从机 Slave(Perpherial) 。一般我们将 从机 具有的数据或者属性特征,称之为 Profile(配置文件)

一个或多个 Characteristic 组成一个 Service,一个或多个 Service 组成 Profile

主机可以发现和获取从机的 ServiceCharacteristic,然后与之通信。Service 可以理解为一个功能集合,Characteristic 是主从通信的最小单元,是一个抽象功能单元

而在 GATT 层则区分为 ServerClient

Characteristic 一般包含以下特征:

比如我现在的服务端是我的烧录了 BLECTFesp32 ,它由很多 Characteristic 组成

Untitled

拿着为0x45的 handle 举例,它就相当于某个 Characteristic 的编号

去读取这个0x45的 handleValue/Descriptor ,可以得到以下信息

Untitled

1a 就是特征属性,代表权限

46 是这个特征的特征值的句柄 ,我们可以通过其去查看这个特征的描述

00 0f ffUUID 的缩略

通过0x46的 handle 去读取 Value/Descriptor ,得到的就是这个特征的描述

Untitled

通过uuid去读取也是一样的结果

Untitled

在BLE中,我们有时候会看到 Attributes(属性) ,这是一个更一般的术语,用于表示 特征 中的各种信息。它可以包含 Characteristic 的UUID、Properties、Value、Descriptors等。Attributes用于描述和定义 特征 的各个方面,以便设备之间能够理解和交换数据。

hcitool 对于 BLE 设备只能进行连接上的管理,如果需要更精细化的管理,就需要使用 gatttool

交互模式下的命令

我们这里可以查看一下设备上所有的特征(Characteristic)

Untitled

handle 是特征的句柄,char properties 是特征的属性,char value handle 是特征值的句柄,uuid 是特征的通用唯一标识符

Untitled

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!

这关主要是让我们熟悉对 BLE 句柄的特征进行简单的写入

首先,查看分数,初始分数为0/20

Untitled

然后,提交向 0x2c 句柄提交flag

Untitled

最后,检查我们的分数来查看flag是否被接受,发现分数变成了1/20

Untitled

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句柄的特征,只需要 --char-read-a 指定 0x002e

Untitled

转为ASCII值为 d205303e099ceff44835

Untitled

Check out the ascii value of handle 0x0030. Do what it tells you and submit the flag you find to 0x002c.

跟上一题差不多

Untitled

转为ASCII值为 MD5 of Device Name

之前用hcitool扫描出的结果就是设备名加MAC地址

Untitled

将设备名BLECTF 进行 MD5 加密后得到值取前20位就是flag

Untitled

Bluetooth GATT services provide some extra device attributes. Try finding the value of the Generic Access -> Device Name.

首先我们得知道 Generic Access 服务的UUID是预定义为 00001800-0000-1000-8000-00805f9b34fb

使用 --primary 指令来发现所有的 GATT 主服务

Untitled

从输出可以看到第二个服务的uuid就是 00001800-0000-1000-8000-00805f9b34fb ,所以第二个服务就是 Generic Access ,根据它提供的句柄范围再去查看特征与句柄

Untitled

一般第一个就是我们的设备

Untitled

转为ASCII值为 2b00042f7481c7b056c4b410d28f33cf 取前20位

Untitled

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句柄的特征的值

Untitled

转ASCII值为 Write anything here

我们只需要往这个句柄里随便写点东西,这个特征的值就会变成flag

Untitled

转为ASCII值为 3873c0270763568cf7aa

Untitled

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

Untitled

转为ASCII值为 Write the ascii value "yo" here

Untitled

转为ASCII值为 c55c6314b3db0a6128af

Untitled

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

Untitled

转为ASCII值为 Write the hex value 0x07 here

我们之前写入的数据的格式都是字符串,现在需要的是整数类型,所以只需要 -n 直接接上对应的值就行了

Untitled

转为ASCII值为 1179080b29f8da16ad66

Untitled

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.

Untitled

转为ASCII值为 Write 0xC9 to handle 58

跟上一题差不多

Untitled

转为ASCII值为 f8b136d937fad6a2be9f

Untitled

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.

Untitled

转为ASCII值为 Brute force my value 00 to ff

就是让我们写个脚本来往这个0x003c句柄的特征里写数据

Untitled

转为ASCII值为 933c1fcfa8ed52d2ec05

Untitled

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.

Untitled

转为ASCII值为 Read me 1000 times

比上一个简单,时间间隔调小一点

Untitled

转为ASCII值为 6ffcd214ffebdc0d069e

Untitled

Check out handle 0x0040 and google search gatt notify. Some tools like gatttool have the ability to subscribe to gatt notifications

Untitled

转为ASCII值为 Listen to me for a single notification ,这个是让我们监听该句柄的一次通知

因为主机可主动向从机 Write 写入或 Read 读取数据,从机可主动向主机 Notify 通知数据。

这里的命令分为两步,首先需要 char-write-req -a 0x0040 -n 00 ,往该句柄以需要响应的形式写入数据,这样就可以启用通知

然后 --listen 开启监听就能接收到该句柄发送的通知(Notify)和指示(indicate

Untitled

转为ASCII值为 5ec3772bcd00cf06d8eb

Untitled

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.

Untitled

转为ASCII值为 Listen to handle 0x0044 for a single indication ,让我们监听该句柄的一次指示。

通知和指示在作用上很相似,都是在客户端发送请求后,服务器发相应的数据给客户端。不同的地方在协议层,通知是无应答的发送但是速度快,而指示是有应答机制的,更安全,它需要我们的客户端发送确认(ACK)来表示确认收到。

所以,其实 gatttool 的操作其实跟上一题一样

Untitled

转为ASCII值为 c7b86dd121848c77c113

Untitled

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.

Untitled

转为ASCII值为 Listen to me for multi notifications ,就是接收多个通知,没啥区别,因为我们的监听功能是持续的,能一直接收

Untitled

转为ASCII值为 c9457de5fd8cafe349fdU no want this msg

Untitled

Check out handle 0x0042 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.

这里题目写错了,把0x0048写成了0x0042

Untitled

转为ASCII值为 Listen to handle 0x004a for multi indications ,上题同理

Untitled

转为ASCII值为 b6f3a47f207d38e16ffa

Untitled

Check out handle 0x004c and do what it says. Much like ethernet or wifi devices, you can also change your bluetooth devices mac address.

Untitled

转为ASCII值为 Connect with BT MAC address 11:22:33:44:55:66

这个的意思其实就是让我们将我们蓝牙适配器的MAC地址改成 11:22:33:44:55:66

这里需要一个 bdaddr 工具,根据这个项目的 README,是支持我这个 CSR4.0 的蓝牙适配器的。但是如果你去看看这个项目 issue,可以发现修改 CSR 的设备的 MAC 地址时会有问题,就是显示修改成功,但是实际 MAC 地址还是原来的那个,我自己在修改时也发现这个问题。不过后来,把蓝牙适配器拔了再插上去后去查看,发现 MAC 地址成功改变了!

Untitled

转为ASCII值为 aca16920583e42bdcf5f

Untitled

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!

这里题目写错了,把0x004e写成了0x0048

Untitled

转为ASCII值为 Set your connection MTU to 444

直接使用 -m 来设置有些问题,不过可以进入交互模式来设置

Untitled

Untitled

转为ASCII值为 b1e409e5a4eaf9fe5158

Untitled

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.

Untitled

转为ASCII值为 Write+resp 'hello' ,只需要注意只能使用--char-write-req ,而不能使用 --char-write 就行了

Untitled

转为ASCII值为 d41d8cd98f00b204e980

Untitled

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!

Untitled

转为ASCII值为 No notifications here! really?

这题的意思应该是,没有允许通知属性的句柄,也可能拥有通知的能力

Untitled

根据常见的特征属性及其对应的位标志:

我们 0x0052 句柄值对应属性值为 0x0a,所以它应该只有写入和读取权限,但是我们主动向其写入输入来启用通知,从而监听服务端的通知

Untitled

转为ASCII值为 fc920c68b6006169477b

Untitled

Check out all of the handle properties on 0x0054! Poke around with all of them and find pieces to your flag.

Untitled

转为ASCII值为 So many properties! ,我们可以看到该句柄属性值为0x9b,其对应权限为广播、读取、带响应写入、通知、扩展

Untitled

也就是说,我们可以写入,也可以监听。根据之前解题的思路,flag应该由此而来(什么MISC)

Untitled

写入跟监听分别得到部分flag,转为ASCII值为 fbb966958f07e4a0cc48

Untitled

Figure out the authors twitter handle and do what 0x0056 tells you to do!

Untitled

转为ASCII值为 md5 of author's twitter handle

作者的推特名在项目那里有:@hackgnar

Untitled

将其md5加密后取前20位得到 d953bfb9846acc2e15ee

Untitled

至此,BLECTF挑战成功!
这个项目主要是引导我们使用gatttool工具去管理BLE设备,从而学习BLE的相关知识,总体体验下来还是挺不错的。
参考资料:

https://bbs.kanxue.com/thread-271543.htm

http://doc.iotxx.com/index.php?title=BLE技术揭秘#

https://leconiot.com/download/cc2640r2f/ble_stack_app/stack/gatt/gatt.html

https://www.cnblogs.com/iini/p/12334646.html

sudo apt-get install esptool
sudo apt-get install esptool
git clone https://github.com/hackgnar/ble_ctf
cd ble_ctf
esptool -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
git clone https://github.com/hackgnar/ble_ctf
cd ble_ctf
esptool -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
sudo hcitool lescan
sudo hcitool lescan
GATT commands
  --primary                                 用于进行主服务发现,查找蓝牙设备上的主服务
  --characteristics                         用于进行特征发现,查找指定主服务下的特征
  --char-read                               用于写入特征的值,需要指定一个句柄
  --char-write                              用于写入特征的值,不需要响应
  --char-write-req                          用于写入特征的值,需要响应
  --char-desc                               于进行特征描述符发现,查找指定特征下的描述符
  --listen                                  监听特征的通知和指示
  
Primary Services/Characteristics arguments
  -s, --start=0x0001                        用于指定起始句柄(可选)
  -e, --end=0xffff                          用于指定结束句柄(可选)
  -u, --uuid=0x1801                         用于指定16bit或者128bit的UUID(可选)
  
Characteristics Value/Descriptor Read/Write arguments
  -a, --handle=0x0001                       用于指定要读取或写入的特征或描述符的句柄
  -n, --value=0x0001                        用于指定要写入的特征值
  
Application Options:
  -i, --adapter=hciX                        用于指定本地适配器接口,如hci0
  -b, --device=MAC                          用于指定远程蓝牙设备的MAC地址
  -t, --addr-type=[public | random]         用于设置LE地址类型,可以选择公共地址还是随机地址,默认公共地址
  -m, --mtu=MTU                             用于指定ATT协议MTU大小
  -p, --psm=PSM                             用于指定GATT/ATT over BR/EDR的PSM
  -l, --sec-level=[low | medium | high]     用于设置安全级别,可以选择低、中、高,默认低安全级别
  -I, --interactive                         用于启用交互模式
GATT commands
  --primary                                 用于进行主服务发现,查找蓝牙设备上的主服务
  --characteristics                         用于进行特征发现,查找指定主服务下的特征
  --char-read                               用于写入特征的值,需要指定一个句柄
  --char-write                              用于写入特征的值,不需要响应
  --char-write-req                          用于写入特征的值,需要响应
  --char-desc                               于进行特征描述符发现,查找指定特征下的描述符
  --listen                                  监听特征的通知和指示
  
Primary Services/Characteristics arguments
  -s, --start=0x0001                        用于指定起始句柄(可选)
  -e, --end=0xffff                          用于指定结束句柄(可选)
  -u, --uuid=0x1801                         用于指定16bit或者128bit的UUID(可选)
  
Characteristics Value/Descriptor Read/Write arguments
  -a, --handle=0x0001                       用于指定要读取或写入的特征或描述符的句柄
  -n, --value=0x0001                        用于指定要写入的特征值
  
Application Options:
  -i, --adapter=hciX                        用于指定本地适配器接口,如hci0
  -b, --device=MAC                          用于指定远程蓝牙设备的MAC地址
  -t, --addr-type=[public | random]         用于设置LE地址类型,可以选择公共地址还是随机地址,默认公共地址

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2024-4-13 12:26 被Arahat0编辑 ,原因:
收藏
免费 8
支持
分享
最新回复 (6)
雪    币: 340
活跃值: (14000)
能力值: ( LV13,RANK:606 )
在线值:
发帖
回帖
粉丝
2
很详细哇,感谢分享
2024-4-13 14:24
0
雪    币: 3024
活跃值: (30866)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2024-4-13 15:31
1
雪    币: 2737
活跃值: (2795)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
yichen115 [em_84]很详细哇,感谢分享
学pwn就是看的您的语雀
2024-4-13 15:43
0
雪    币: 6008
活跃值: (2575)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
5
太成功了
2024-4-23 16:18
0
雪    币: 76
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
yichen115 [em_84]很详细哇,感谢分享
hack by yichen!
2024-4-23 17:30
0
雪    币: 3928
活跃值: (6505)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
7
Flag 0x0016 判断依据 => Generic Access uuid(1800) -> Device Name uuid(2a00)。此外 Generic Attribute uuid(1801),Appearance uuid(2a01)
2024-5-6 17:57
0
游客
登录 | 注册 方可回帖
返回
//