在寻找IOT设备的攻击面之路的时候,发现蓝牙这块的知识很薄弱,这次借着esp32+BLE_CTF这个组合来认识一下蓝牙的协议栈以及蓝牙之类的知识
蓝牙简介
在蓝牙诞生之前是通过一些复杂的电缆线或者是红外线,来实现设备与设备之间的通信的,蓝牙的前生今世看下面的链接就差不多了,这里简单介绍一下目前蓝牙的现状,目前的蓝牙是由三部分所组成的,分别是BLE(低功耗蓝牙),BT(经典蓝牙),高速蓝牙,他们三者都有各自的应用场景,同时还有Mesh网状网络技术支持成千个设备进行互联互通,这不就是正好赶上IOT的大时代趋势了吗?
-
「硬核无线技术」系列视频 蓝牙篇(上)
-
「硬核无线技术」系列视频 蓝牙篇(下)
-
一文读懂蓝牙技术从 1.0 到 5.0 的前世今生
-
经典蓝牙介绍
服务发现协议 (SDP/GAP)
SDP/GAP 是在所有蓝牙设备上发现服务的基础,这对于所有蓝牙模型都是必不可少的,因为可以通过 SDP/GAP 设备信息、服务和服务的特性来查询,然后可以在两个或多个蓝牙设备之间建立连接
射频通信(RFCOMM/GATT&&ATT)
RFCOMM 协议用于蓝牙中的电缆更换选项。它是一种简单的传输协议,具有额外的规定,用于通过蓝牙协议栈的 L2CAP 部分模拟 RS232 串行端口的九个电路。它支持使用串行通信的应用程序的大型基础。它提供可靠的数据流、多重连接、流量控制和串行电缆线路设置
逻辑链路控制和适配 – 层 (L2CAP)
蓝牙逻辑链路控制和适配层支持更高级别的多路复用、分段和数据包重组以及服务质量通信和组。该层不负责可靠性并使用 ARQ 来确保它
主机制器接口 (HCI)
HCI 为基带控制器、链路管理器以及对硬件状态和控制寄存器的访问提供命令接口。该接口提供了访问蓝牙基带功能的统一方法。主机控制传输层去除了传输依赖并提供了一个通用的驱动程序接口。核心规范中定义了三个接口:USB、RS-232 和 UART。
再往下就是硬件相关的信息处理,在此就不做过多介绍了,下面的BLE_CTF研究的是BLE中的GATT层,attribute是此层中最重要的信息,它包括包括service, characteristic,descriptor,每一个attribute都有handle、UUID、data、properties,在后面的bleah探测当中可以发现这几个属性,例如对于某个characteristic来说,他有个独一无二的handle代表server里面的attribute table里面序号,有attribute properties代表这个characteristic的类型,之后是attribute value,后面是可以通过某些方法修改这些属性的,这样属性映射到真实的设备上面就是一个个功能模块!
ESP32环境搭建
配置的环境按照芯片文档上面的就成功把环境拉起来,一定要看到下面的输出才算配置完成
-
配置步骤
.
Hello world!
Restarting in 10 seconds...
This is esp32 chip with 2 CPU core(s), WiFi/BT/BLE, silicon revision 1, 2MB external flash
Minimum free heap size: 298968 bytes
Restarting in 9 seconds...
Restarting in 8 seconds...
Restarting in 7 seconds...
Restarting in 6 seconds...
Restarting in 5 seconds...
搭建踩坑
-
设备管理器无法找到此设备:
-
可能一:USB线没有数据传输功能
原因:有些比较便宜的USB线只能进行供电,不能进行数据传输,剪开看可以发现它只有地线和±5V
解决办法:换条可以传输数据的线即可
-
可能二:供电不正常
原因:可能排线有点问题,供电不上
检查办法:用万用表测试一下VCC和GND是否正常
-
可能三:芯片供电不正常
原因:可能排线有点问题,供电不上
检查方法:用USB转TTL的设备通过杜邦线连接ESP32,需要连接VCC,GUN,TX(转换设备连接RX),再用串口连接工具看看有无输出,下面为输出样例:
-
ets Jun 8 2016 00:22:57
rst:0x5 (DEEPSLEEP_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
ets Jun 8 2016 00:22:57
rst:0x7 (TG0WDT_SYS_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0x00
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0008,len:8
load:0x3fff0010,len:3464
load:0x40078000,len:7828
load:0x40080000,len:252
entry 0x40080034
I (44) boot: ESP-IDF v2.0-rc1-401-gf9fba35 2nd stage bootloader
I (45) boot: compile time 18:48:10
...
-
识别不到COM口:
-
CP210X驱动安装链接
-
可能一:未安装驱动
解决办法:安装CP210X驱动
我踩的坑就是上面这些....
BLE_CTF环境搭建
刷入固件
在识别到COM之后,ESP-IDF 4.3 Powershell输入下面的命令,记得替换port,就可以直接将BLE_CTF的固件刷入ESP32里面
--chip esp32 --port (yours port)
--baud 115200 --before default_reset --after hard_reset write_flash
-z --flash_mode dio --flash_freq 40m --flash_size detect
0x1000 build/bootloader/bootloader.bin
0x10000 build/gatt_server_service_table_demo.bin
0x8000 build/partitions_singleapp.bin
刷入之后,就能在蓝牙识别中看见BLECTF这个设备,此时已经成功刷入固件了!
寻找MAC地址
在拉起来BLE_CTF之后,还需要知道它的MAC地址才能与它进行通信,笔者是用树莓派来寻找它的MAC地址的,在kali和ubuntu都不太行,允许搜索附近的BLE设备的时候,报一个I/O设备的错误,解决不了,然后想到了树莓派,最后成功得到ESP32的MAC地址
链接:
-
Linux下蓝牙工具:hcitool使用教程
-
树莓派通过蓝牙进行串口通讯
-
低功耗蓝牙(BLE)的简要学习分析
-
树莓派进阶之路 (022) - 串口篇 - 通过串口连接控制树莓派
-
使用串口线连接树莓派
-
树莓派三种连接电脑的方式
下面是找到BLECTF的MAC地址:
➜ ~ sudo hcitool lescan
LE Scan
...
44:17:93:5e:46:06 BLECTF
...
开启BLE_CTF之路
要想实现蓝牙的收发包,有几种方法来实现,下图展示了具体是哪几种方法:
gatttool介绍
链接:
-
gatttool命令详解
-
BlueZ gatttool操作
bleah介绍
Traceback (most recent call last):
File "/usr/local/bin/bleah", line 4, in <module>
__import__('pkg_resources').run_script('bleah==1.0.0', 'bleah')
File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 666, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python2.7/dist-packages/pkg_resources/__init__.py", line 1446, in run_script
exec(code, namespace, namespace)
File "/usr/local/lib/python2.7/dist-packages/bleah-1.0.0-py2.7.egg/EGG-INFO/scripts/bleah", line 119, in <module>
main()
File "/usr/local/lib/python2.7/dist-packages/bleah-1.0.0-py2.7.egg/EGG-INFO/scripts/bleah", line 113, in main
bleah = Bleah(args)
File "/usr/local/lib/python2.7/dist-packages/bleah-1.0.0-py2.7.egg/bleah/scan.py", line 277, in __init__
self.start_scan()
File "/usr/local/lib/python2.7/dist-packages/bleah-1.0.0-py2.7.egg/bleah/scan.py", line 344, in start_scan
self.devices += self.scanner.scan(self.args.timeout)
File "/usr/local/lib/python2.7/dist-packages/bluepy-1.3.0-py2.7.egg/bluepy/btle.py", line 881, in scan
self.start(passive=passive)
File "/usr/local/lib/python2.7/dist-packages/bluepy-1.3.0-py2.7.egg/bluepy/btle.py", line 818, in start
self._startHelper(iface=self.iface)
File "/usr/local/lib/python2.7/dist-packages/bluepy-1.3.0-py2.7.egg/bluepy/btle.py", line 281, in _startHelper
self._lineq = Queue()
TypeError: 'module' object is not callable
flag1
第一个flag目的在说明如何提交flag,执行下面的命令即可得到一个flag:
gatttool -b 44:17:93:5e:46:06 --char-write-req -a 0x002c -n $(echo -n "12
345678901234567890"|xxd -ps)
参数介绍:
-b <MAC>
--char-write-req
-a <handle>
执行下面的命令可以得知目前的socre为多少:
gatttool -b 44:17:93:5e:46:06 --char-read -a 0x002a|awk -F':' '{print $2}'|tr -d ' '|xxd -r -p;printf 'n'
flag2
开始我们的夺旗之旅,hint告诉我们要去查看句柄0x002e的ascii值,有两种方法可以查看:
第一种是bleah,它可以将此设备的所有属性给列出来,所以相对来说它的速度要慢一些:
sudo bleah -b "44:17:93:5e:46:06" -e
第二种就是gatttool,它可以选择输出指定句柄的data:
➜ ~ gatttool -b 44:17:93:5e:46:06 --char-read -a 0x002e
Characteristic value/descriptor: 64 32 30 35 33 30 33
65 30 39 39 63 65 66 66 34 34 38 33 35
将输出的ascii转换成字符串就可以了:
import binascii
str = "64 32 30 35 33 30 33 65 30 39 39 63 65 66 66 34 34 38 33 35"
list_str = list(str)
while ' ' in list_str:
list_str.remove(' ')
print(binascii.unhexlify(''.join(list_str)))
也可以用命令行来转换:
➜ ~ echo "64 32 30 35 33 30 33 65 30 39 39 63 65 66 66 34 34 38 33 35"
|tr -d ' '|xxd -r -p;printf 'n'
其实就是linux命令,参考下面的链接
-
Linux tr命令
-
xxd命令功能
最后交上获得的flag就能得分!!
sudo bleah -b "A4:C1:38:21:2C:E2" -e
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "d205303e099ceff44835"
flag3
此题要md5设备的名称,这个名称有点坑,一直以为是下图的值的md5,导致直接卡死....
最后才知道是要将BLECTF进行md5...,md5的方法有很多就不介绍了:
➜ ~ echo -n "BLECTF"|md5sum 5cd56d74049ae40f442ece036c6f4f06 -
最后取20位作为flag:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "5cd56d74049ae40f442e"
flag4
此题才是上面找错的值,Generic Access -> Device Name的data为2b00042f7481c7b056c4b410d28f33cf,同样取20位提交:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "2b00042f7481c7b056c4"
flag5
此处提示"Write anything here",尝试写入"zyen"在这个句柄里面:
gatttool -b 44:17:93:5e:46:06 --char-write-req -a 0x0032 -n $(echo -n "zyen"|xxd -ps)
或者
sudo bleah -b "44:17:93:5e:46:06" -n 0x0032 -d "hello"
提交flag:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "3873c0270763568cf7aa"
flag6
和上题大差不差:
sudo bleah -b "44:17:93:5e:46:06" -n 0x0034 -d "yo"
最后查看答案:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "c55c6314b3db0a6128af"
flag7
还是一模一样,只是将写入的字符串改成了十六进制的数字:
sudo bleah -b "44:17:93:5e:46:06" -n 0x0036 -d "0x07"
提交得分:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "1179080b29f8da16ad66"
flag8
这题虽然没有看到有58这个句柄,但是还是可以往这个句柄里面写值的,猜测应该是隐藏了:
sudo bleah -b "44:17:93:5e:46:06" -n 0x003a -d '0xc9'
提交得分:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "f8b136d937fad6a2be9f"
flag9
这题就有点不一样了,hint说要写入一个值,但是没有告诉你这个值具体的值是多少,只说这是一个00到ff的值,所以我们爆破这个值就好啦
import os
for i in range(0,256):
bash = 'sudo bleah -b "44:17:93:5e:46:06" -n 0x003c -d "' + '0x{0:02x}'.format(i) + '"'
print(bash)
os.system(bash)
爆破完回去看就发现,那里已经出现flag了
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "933c1fcfa8ed52d2ec05"
flag10
这题hint说要读此句柄1000次:
import os
for i in range(0,1000):
bash = 'gatttool -b 44:17:93:5e:46:06 --char-read -a 0x003e'
os.system(bash)
脚本读完目标句柄1000之后就会出现flag,提交
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "6ffcd214ffebdc0d069e"
flag11
题目提示:Listen to me for a single notification
-
通知和指示有什么不同?
-
低功耗蓝牙:在 linux 中监听通知/指示
-
GATT 服务器和客户端角色
notification只是通知,在某一个句柄是不断发送一个value
indicate和notification一样,只不过多了一个ACK的模式
gatttool -b 44:17:93:5e:46:06 --char-write-req --handle=0x0040 --value=0100 --listen
接收到:35 65 63 33 37 37 32 62 63 64 30 30 63 66 30 36 64 38 65 62
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "5ec3772bcd00cf06d8eb"
小tips:
0100 是获取 notifications
0200 是获取 indications
0300 两个都获取
0000 全部关闭
flag12
题目提示:Listen to handle 0x0044 for a single indication
刚刚讲到indication是需要多发一个ACK的:
gatttool -b 44:17:93:5e:46:06 --char-write-req --handle=0x0040 --value=0200 --listen
出现flag,提交即可:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "c7b86dd121848c77c113"
flag13
监听之后出现两个两个flag:
0x0046 value: 55 20 6e 6f 20 77 61 6e 74 20 74 68 69 73 20 6d 73 67 00 00 =
0x0046 value: 63 39 34 35 37 64 65 35 66 64 38 63 61 66 65 33 34 39 66 64 =
第一个拿去解码之后为:"U no want this msgx00x00",很明显不是flag,第二个解码就为flag:c9457de5fd8cafe349fd,提交得分:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "c9457de5fd8cafe349fd"
flag14
同12题:
gatttool -b 44:17:93:5e:46:06 --char-write-req --handle=0x004a --value=02
00 --listen
提交flag:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "b6f3a47f207d38e16ffa"
flag15
此题是需要修改MAC,但是修改的有点问题,暂时还没解决
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "aca16920583e42bdcf5f"
flag16
用交互模式修改MTU为444就行:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "b1e409e5a4eaf9fe5158"
flag17
用--char-write-req参数指定数据即可:
gatttool -b 44:17:93:5e:46:06 --char-write-req -a 0x0050 -n $(echo -n "he
llo"|xxd -ps)
提交flag:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "d41d8cd98f00b204e980"
flag18
No notifications here! really?一样去监听notifications就行:
gatttool -b 44:17:93:5e:46:06 --char-write-req --handle=0x0052 --value=02
00 --listen
提交flag:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "fc920c68b6006169477b"
flag19
此GATT属性有NOTIFY BROADCAST READ WRITE EXTENDED PROPERTIES,前半段是写句柄,后半段是监听
gatttool -b 44:17:93:5e:46:06 --char-write-req --handle=0x0054 --value=02
00 --listen
提交flag:
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "fbb966958f07e4a0cc48"
flag20
最后以md5作者的推特账号提交,
echo -n "@hackgnar" | md5sum
sudo bleah -b "44:17:93:5e:46:06" -n 0x002c -d "d953bfb9846acc2e15ee"
至此,已经完成所有BLECTF的内容!!!不过后面的题目耦合性有点大了...
总结
完成此CTF挑战是为了更好地了解蓝牙这个协议,为后面的研究打下一定的基础,从GATT层面来看,某些蓝牙设备也是存在一些问题的,可以通过这个来进行切入。
参考链接
BLECTF Capture_flag
BLUETOOTH LOW ENERGY CTF - WRITE UP
Bluetooth Protocol (Part 2): Types, Data Exchange, Security
BLUETOOTH FRAMEWORK AND RFCOMM PROTOCOL
Bluetooth: ATT and GATT
Bluetooth Protocol Stack
GATT Server and Client Roles
原文始发于微信公众号(广软NSDA安全团队):Bluetooth学习之esp32
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论