虽然之前总结过:关于蓝牙的漏洞研究,但对于蓝牙还是很懵,因为从来没有实践过,西湖论剑IoT比赛时,蓝牙的题目一个也没做出来。每次看到蓝牙都不知道在说哪一层的协议,看到wireshark抓的包也感觉之前看的蓝牙包不长这样啊。这次经过一段时间的研究,才大概的明白:(1)蓝牙的协议栈之所以复杂,是由于历史的变迁,以及兼容性的考虑,导致出现了(老的)经典蓝牙和(新的)低功耗蓝牙并存复杂的协议栈,单独来看这新老两个技术的协议栈,都没有很复杂,并且其结构都是很清晰的。(2)蓝牙的数据包在其从用户程序发送到空中的过程中,封包并非如TCP/IP协议仅仅将上一层的数据进行简单的封装就传递到下一层,相邻层之间的数据变换可能比较复杂,于是就导致了由于抓包的层次不同,看到的同一过程的数据的组织方式是不同的,典型就是在空口抓包以及在HCI层抓包。(3)另外以西湖论剑的三道蓝牙题目为例子,总结了主机控制蓝牙不同层次的收发包工具以及背后原理。
蓝牙协议
协议简介
新老并存是蓝牙协议栈复杂的主要原因,协议分层如图:
想了解最全面的蓝牙协议栈设计,可以去 蓝牙官网 找,目前最新的白皮书是:Bluetooth Core Specification v5.3。
协议实现
谈协议分层总是很简单,因为上面这种图片随处可见,但其本质的内容是一个抽象的设计方案,而不是具体的实现方案(软件代码,硬件电路)。对于黑客来说,我们不仅仅关注抽象的协议设计上有没有问题,更关注的是协议的实现,因为设计一般都是经过世界上顶尖的大脑们反复推敲出来的,而实现可能就是某个开发者半夜一边吃外卖一边写出来的。协议设计的问题可能在白皮书中隐约看到,但实现的漏洞你是不可能从白皮书中看出来的,比如:
- Bleeding Tooth:Linux蓝牙驱动远程代码执行分析与利用
- bluetooth_stack开源蓝牙协议栈源码分析与漏洞挖掘
- 物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探
- 记一次智能印章设备的漏洞挖掘
这些漏洞他们的本体在:
- linux内核:linux-5.4/net/bluetooth/a2mp.c
- STM32应用代码:Bluetooth stack: Fix three stack overflow in att messages
- github上暴露的签名算法:miband/model/UserInfo.java
- android APP上不安全的秘钥使用:displayGattServices
所以我们要了解的是,整个蓝牙的通信过程中,其数据处理的每一个过程究竟在哪?换种说法就是:每层的协议到底是软件实现还是硬件实现?如果是软件实现,那是什么层次的软件(应用代码、内核代码、还是芯片固件等等)?也就是具体协议的落地层次,可以参考:
主要就是三种架构方案,后两者的最大区别是:蓝牙app的业务代码与蓝牙协议栈是否运行在同一个处理器上。当然这也就会造成两者蓝牙模组/SoC的开发厂商提供的SDK的本质不同,单芯片的SDK主要完成编译烧录运行,而双芯片主要完成通信过程。
PC和手机一般用蓝牙的都是host+controller双芯片标准架构,其通信的HCI协议也是蓝牙官方规定好的。通过分析linux的蓝牙驱动,以及相关芯片的datasheet,都能看出来这些芯片不参与任何上层协议的实现工作:
- linux/drivers/bluetooth
- Which mobile device has which bluetooth chip?
- 手机中的蓝牙模块一般是用什么芯片?
- BCM4330
- csr1010-data-sheet
- BCM4354 Datasheet
而嵌入式设备上的使用的蓝牙,可能会采用单芯片整体方案或者自定义双芯片架构,也就是那些蓝牙模组/SoC。模组,模块,SoC其实这些概念用起来比较混淆:
可见网上卖的大部分模组,模块,使用起来都应该属于自定义双芯片架构,因为你看上面的开发,配置一下串口然后就能直接使用GATT协议进行工作了,可见模组中已经实现了比较完整的蓝牙协议栈了。单芯片整体方案最常见的例子就是ESP32,我们的业务代码和蓝牙协议栈代码都运行在一个处理器上:
从 ESP32拆解图 可见:ESP32中就封装了一个ESP的SoC和flash
其蓝牙协议栈的实现在:https://github.com/espressif/esp-idf/tree/master/components/bt,即我们开发的业务代码最终会和这个蓝牙协议栈一起编译,打包,然后烧录进esp32的flash中,由esp32的xtensa处理器来执行。
攻击技能
这里只讨论从空口对另一台蓝牙设备的攻击,不讨论本地对自身的蓝牙驱动或者蓝牙芯片的攻击。
对于协议的抽象设计和实现方法有了清晰的认知之后,就是什么东西实现在哪?怎么实现的? 我们从开发者的视角切换成攻击者。我们不仅会对漏洞的发现,原理更加明晰,而且还能更清楚的知道,我们如何发动一次攻击:即在什么协议层次?怎么发送攻击流量?怎么完成这个层次的流量抓取? 此时我们需要回答一个问题:
- 问:基本所有的手机或电脑本身都是支持蓝牙的,那为什么还要其他的外置硬件才能进行某些场景下的安全研究呢?
- 答:研究一个通信的过程,黑客主要有五个动作:收、发、抓、断、改。本机的硬件可能不支持某些动作,比如发畸形链路层报文:CC2541 SweynTooth BLE漏洞实测、抓空中其他设备的通信报文等等。
对于空中信号,完成基于中间人的断、改,一般通过拉长双方距离,然后采用中继设备来实现中间人,比如NFCGate。不过除了在通信的物理链路上做手脚,还可以在通信过程的软件实现处完成中间人,就像可以使用frida来hook掉android侧的app进而完成对蓝牙数据的修改一样,只要在关注的目标层次之前,篡改其未来要处理的数据即可。对于蓝牙的中间人我还没有调研过,这里还是主要说,收、发、抓这三个动作。
层次抓包
其实在通信过程的任何阶段,都可以想办法捕获通信内容,所说的常规方法只不过因为是现成的方案。
蓝牙抓包一般来说有如下几种办法:
方法 | 抓包位置 | 所需硬件 | 特点 | 方法说明 |
---|---|---|---|---|
Ubertooth | 空口 | Ubertooth | BLE/BR, open source | 使用Ubertooth监听蓝牙通信 |
nRF52832 | 空口 | nRF52832 | only BLE | nRF52832 Sniffer 抓包使用体验 |
cc2540 | 空口 | cc2540 | only BLE | CC2540 USB Dongle 蓝牙抓包分析仪使用教程 |
hollong | 空口 | hollong | only BLE | Hollong 蓝牙4.0/4.1/4.2 BLE协议监控分析仪 文档 |
HCI接口 | 本机 | 本机蓝牙 | only local | 使用Ubuntu虚拟机抓Bluetooth报文 |
HCIlog | 本机 | 本机蓝牙 | only local | Android Bluetooth HCI log 详解 |
抓包位置不同,捕获的数据包层次就不同,看起来的样子也不同,主要是两种,空口和HCI:
- 使用ubertooth抓取的空口报文:HITCTF 2020 蓝牙原始数据解析
- 使用HCIlog在Android上抓取的蓝牙报文:android下的蓝牙HCI日志抓取方法
但是以上两个都不够直观,我们使用接下来的例题自己抓两个包:
- HCI 报文(wireshark抓取主机HCI接口):adv_hci.pcapng
- 空口报文(hollong抓取的空中信号):adv_hollong.pcapng
可以清楚的对比两种报文的差异了,其实大差不差:
HCI和空口是蓝牙协议栈的不同层次,协议对两个层次的数据组织并不是简单的封装。这个差异最开始很让我困惑,因为我们太熟悉以太网的报文了,以至于理所应当的认为:数据在通信的每一个层次的流动就是简单做一些数据的包裹,即添加或删除一些头之类的操作。但其实数据在他的整个生命周期的过程,除了基本的包裹操作,还可以有非常多的变换,比如加密解密,编码解码等。这里的本质原因是:每个层次所考虑的问题不仅仅是对下层负责,可能还要在本层完成一些事情。
高级收发
攻击行为本质就是恶意数据的收发,任何包含发送数据的攻击都必然要有攻击的信道。
如果只是BLE应用层(ATT流量)的简单读写交互的话,nRF connect 这个手机软件就足够了,但当我们需要:
- 攻击经典蓝牙
- 在ATT层有复杂的交互
- 攻击其他非ATT的底层协议
这时 nRF connect 就有些力不从心了,于是我们需要更高级的收发包方法,让我们能构造更丰富的恶意报文,所以我们需要尽量彻底的控制蓝牙设备,让其为我们工作。刚才我们说过,目前的手机以及PC都采用的是host+controller双芯片标准架构,所以由于硬件的限制,一般来说,我们只能构造链路层以上的报文。对于链路层和物理层的攻击,则需要更加可控的蓝牙设备,比如ESP32,Nordic52840,甚至是自己构建的SDR。这里我们只关注PC和手机平台作为攻击机:
攻击机 | 蓝牙设备 | 协议栈 | 原生API | 顶层工具 |
---|---|---|---|---|
linux PC | PC蓝牙controller | bluez | D-Bus API、C socket API | bluez tools、Scapy、pybluez、bluepy、pygatt、bluescan |
android | 手机蓝牙controller | Fluoride | java API | nRF connect |
iPhone | 手机蓝牙controller | 私有 | Objective-C API | nRF connect |
bluez API 说明:Linux Bluetooth API Function Locations
在以上原生API的帮助下,我们在空口收发包的最低层次能到L2CAP。值得注意的是,HCI层协议是主机和控制器的交互界面,其自身的生命周期只存在于二者交互的过程中,而不存在于纯空口过程中。所以对于从空口上完成的HCI层攻击,还是发送其他层协议的报文,从而触发对端的HCI过程,进而发生攻击。
- CVE-2020-0022 an Android 8.0-9.0 Bluetooth Zero-Click RCE – BlueFrag
- Android 蓝牙子系统 “BlueFrag” 漏洞分析(CVE-2020-0022)
- 蓝牙安全与攻击案例分析: bluefrag
- CVE-2020-0022漏洞分析
不过原生API的使用不够便捷与轻量,而linux的蓝牙攻击工具是生态最成熟的,基本都是python的库,只有bluez自带的用户态二进制工具除外。所以linux的PC是我们理想的攻击平台,但由于我们大都是使用linux虚拟机,其使用蓝牙设备的方式是和宿主机共享,在这种情况下可能会出现各种各样的问题,所以一般建议linux虚拟机独占一个蓝牙外设。比如我媳妇的惠普windows本中的linux虚拟机就可以使用共享本机的蓝牙设备正常攻击,而我的 MacBook Pro 上,虽然可以使用hciconfig看到蓝牙设备,但之后无法正常进行攻击,这里使用bluepy中的blescan进行测试。
所以当你尝试共享蓝牙设备给linux虚拟机不好使的情况下,才可能需要单独购买一个蓝牙USB外设。bluescan的官方文档中建议Ostran 奥视通 USB 蓝牙适配器 OST-105 CSR 8150 v4.0或者UD100 G03,我之前一直很奇怪为啥非得这俩蓝牙外设,他们多啥?这玩意淘宝一搜不一大堆么?后来仔细看看才发现,原来网上卖的蓝牙USB外设大部分没有linux的驱动,都是windows独占。另外这些蓝牙USB外设的信号也没有手机或者PC上自带的蓝牙芯片稳定,经常需要插拔,重新连接到虚拟机等重置操作。外设配置好后,就可以关注怎么控制外设收发包了,即linux上的蓝牙顶层工具,这些工具是各有特色:
工具 | 形态 | 底层 | 接口最低控制层次 | 特点 |
---|---|---|---|---|
bluez tools | 命令行 | bluez | HCI(BR/BLE) | 基础:主要用于配置检查,能完成一些基本的正常业务数据包 |
Scapy | python | bluez | HCI(BR/BLE) | 收发:使用复杂,可在python层面直接控制HCI,组织数据包灵活 |
pybluez | python | bluez | L2CAP(BR/BLE) | 收发:成熟的python蓝牙库,对L2CAP、RFCOMM层的接口友好 |
bluepy | python | bluez | GATT (BLE) | 收发:GATT相关处理较多,扫描脚本blescan命令行直接可用 |
pygatt | python | gatttool | GATT (BLE) | 收发:将gatttool(bluez tools)封装成python接口 |
bluescan | python | bluepy , pybluez | HCI(BR/BLE) | 扫描:安恒海特实验室 Sourcell Xu 开发,安全向,主要用于扫描,Python 3.9以上适配 |
工具使用示例文章:
有了这些工具,学会了怎么使用这些工具配置,发包,扫描,就可以完成下面的题目了。
题目实践
题目概述:
硬件环境:
软件环境(ubuntu21.04虚拟机):
➜ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 21.04
Release: 21.04
Codename: hirsute
➜ uname -a
Linux xuanxuan 5.11.0-22-generic #23-Ubuntu SMP Thu Jun 17 00:34:23 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
➜ python3 --version
Python 3.9.5
➜ pip list | grep -i blue
bluepy 1.3.0
bluescan 0.6.4
PyBluez
adv_sign
本题考查的层次为BLE的链路层,考查点是BLE广播报文的捕获与解析,需要了解的协议为:通用访问配置文件(GAP)
- 源码:adv_sign.py
- 解题过程HCI包:adv_sign_hci.pcapng
- 解题过程空口包:adv_sign_hollong.pcapng
题目将flag信息编码到了BLE广播报文的 General Access Profile
中,所以使用任何可以嗅探到BLE广播报文的手段都可以完成此题,以下使用bluescan
解题:
➜ sudo bluescan -m le
[WARNING] Before doing an active scan, make sure you spoof your BD_ADDR.
[INFO] LE active scanning on hci0 with timeout 10 sec
----------------LE Devices Scan Result----------------
Addr: A6:50:92:7A:97:14 (Unknown)
Addr type: public
Connectable: True
RSSI: -72 dBm
General Access Profile:
0xFE (Unknown): 74665a6d78415a323868
0xFD (Unknown): 51475666596a56775147
0xFC (Unknown): 596d786c
Complete Local Name: BCM20702A
然后将数据拼起来解码:
➜ python3
>>> import base64
>>> base64.b64decode(bytes.fromhex('596d786c51475666596a5677514774665a6d78415a323868'))
b'ble@e_b5p@k_fl@go!'
send_l2cap
本题考查的层次为经典蓝牙的L2CAP和SDP层,考查点是SDP服务的发现以及L2CAP的协议格式,需要了解的协议为:逻辑链路控制和适配层协议(L2CAP)
- 源码:l2cap_matryoshka.py
- 解题过程HCI包:send_l2cap_hci.pcapng
- 解题过程空口包:无,hollong无法捕获经典蓝牙数据包
首先使用bluescan扫描:
➜ sudo bluescan -m br
[INFO] BR scanning on hci0 with timeout 10.24 sec
Addr: A6:50:92:5A:93:14 (Unknown)
Page scan repetition mode: 1 (R1)
Reserved: 0x02
CoD: 0x000000
Service Class: 0b0
Major Device Class: 0b0, Miscellaneous
Clock offset: 0x616E
RSSI: -72
Extended inquiry response: None
➜ sudo bluescan -m sdp A6:50:92:5A:93:14
[INFO] Scanning...
Number of service records: 6
Service Record
0x0000: ServiceRecordHandle (uint32)
0x00010005
0x0001: ServiceClassIDList (sequence)
11111111-1111-1111-1111-111111111111: unknown
0x0003: ServiceID (uuid)
11111111-2222-3333-4444-555555555555: to be parsed
0x0004: ProtocolDescriptorList (sequence)
0x0100: L2CAP
PSM: 0x1031
0x0100: L2CAP
0x0100: L2CAP
0x0005: BrowseGroupList (sequence)
0x1002: PublicBrowseRoot
0x0009: BluetoothProfileDescriptorList (sequence)
22222222-2222-2222-2222-222222222222: unknown
0x0100: ServiceName (guess) (text)
L2CAP Matryoshka
0x0101: ServiceDescription (guess) (text)
What's the innermost part of this L2CAP Matryoshka?
0x0102: ProviderName (guess) (text)
Sourcell Xu of HatLab, DBAPP Security
完成题目需要与目标建立L2CAP连接,并发送数据,所以可以参考 pybluez 的 l2capclient.py 建立连接,最终的解题脚本如下:
#!/usr/bin/env python3
import sys
import bluetooth
sock = bluetooth.BluetoothSocket(bluetooth.L2CAP)
addr = "A6:50:92:5A:93:14"
port = 0x1031
recv = lambda : (print("[+] recv: "+str(sock.recv(1024))))
send = lambda data : (sock.send(bytes.fromhex(data)), print("[+] send: "+str(data)), recv())
print("[+] Trying to connect to %s on PSM %s..." % (addr,hex(port)))
sock.connect((addr, port))
print("Connected\n")
recv()
send('060001000aff0200ffff')
send('0800010002ff040041104000')
send('0800010004ff040041000F00')
recv()
send('0a004100060001000aff0200ffff')
send('0c0041000800010002ff040051104000')
send('0c0041000800010004ff040042000F00')
recv()
send('0800410004004200666c6167')
sock.close()
ubuntu21.04下我的蓝牙外设不稳定,后续攻击过程不需要bluescan
,最终在ubuntu16.04下稳定执行:
➜ python3 send_l2cap.py
[+] Trying to connect to A6:50:92:5A:93:14 on PSM 0x1031...
Connected
[+] recv: b'Level1:ConnectMe'
[+] send: 060001000aff0200ffff
[+] recv: b'\x16\x00\x01\x00\x0b\xff\x12\x00\xff\xff\x00\x00PSM1041ForConn'
[+] send: 0800010002ff040041104000
[+] recv: b'\x0c\x00\x01\x00\x03\xff\x08\x00A\x00@\x00\x00\x00\x00\x00'
[+] send: 0800010004ff040041000F00
[+] recv: b'\n\x00\x01\x00\x05\xff\x06\x00@\x00\x00\x00\x00\x00'
[+] recv: b'\x1e\x00@\x00Level1:Passed,Level2:ConnectMe'
[+] send: 0a004100060001000aff0200ffff
[+] recv: b'\x1a\x00@\x00\x16\x00\x01\x00\x0b\xff\x12\x00\xff\xff\x00\x00PSM1051ForConn'
[+] send: 0c0041000800010002ff040051104000
[+] recv: b'\x10\x00@\x00\x0c\x00\x01\x00\x03\xff\x08\x00B\x00@\x00\x00\x00\x00\x00'
[+] send: 0c0041000800010004ff040042000F00
[+] recv: b'\x0e\x00@\x00\n\x00\x01\x00\x05\xff\x06\x00@\x00\x00\x00\x00\x00'
[+] recv: b'\'\x00@\x00#\x00@\x00WantGetFlag?SendMeInfoPayload"flag"'
[+] send: 0800410004004200666c6167
[+] recv: b'#\x00@\x00\x1f\x00@\x00flag{br0h1pIt_l@cab_watrx0sHka}'
板子串口数据:
[DEBUG] Peer socket name
04:7F:0E:05:36:13
0x1031
[INFO] Accepted connection from 04:7F:0E:05:36:13, PSM 0x1031
[DEBUG] level0data_level1signal, recv
< b'\x06\x00\x01\x00\n\xff\x02\x00\xff\xff'
info_payload_len: 0x0006
CID: 0x0001
code: 0x0a
identifier: 0xff
length: 0x0002
data: b'\xff\xff'
InfoType: 0xffff
[INFO] Passed level0data_level1signal, L2CAP_INFOMATION
[DEBUG] level0data_level1signal, recv
< b'\x08\x00\x01\x00\x02\xff\x04\x00A\x10@\x00'
info_payload_len: 0x0008
CID: 0x0001
code: 0x02
identifier: 0xff
length: 0x0004
data: b'A\x10@\x00'
PSM: 0x1041
SCID: 0x0040
[INFO] Passed level0data_level1signal, L2CAP_CONNECTION
[DEBUG] level0data_level1signal, recv
< b'\x08\x00\x01\x00\x04\xff\x04\x00A\x00\x0f\x00'
info_payload_len: 0x0008
CID: 0x0001
code: 0x04
identifier: 0xff
length: 0x0004
data: b'A\x00\x0f\x00'
DCID: 0x0041
flags: 0x000f
config_opts: b''
[INFO] Passed level0data_level1signal, L2CAP_CONFIGURATION
[DEBUG] level1data_level2signal, recv
< b'\n\x00A\x00\x06\x00\x01\x00\n\xff\x02\x00\xff\xff'
info_payload_len: 0x0006
CID: 0x0001
code: 0x0a
identifier: 0xff
length: 0x0002
data: b'\xff\xff'
InfoType: 0xffff
[INFO] Passed level1data_level2signal, L2CAP_INFOMATION
[DEBUG] level1data_level2signal, recv
< b'\x0c\x00A\x00\x08\x00\x01\x00\x02\xff\x04\x00Q\x10@\x00'
info_payload_len: 0x0008
CID: 0x0001
code: 0x02
identifier: 0xff
length: 0x0004
data: b'Q\x10@\x00'
PSM: 0x1051
SCID: 0x0040
[INFO] Passed level1data_level2signal, L2CAP_CONNECTION
[DEBUG] level1data_level2signal, recv
< b'\x0c\x00A\x00\x08\x00\x01\x00\x04\xff\x04\x00B\x00\x0f\x00'
info_payload_len: 0x0008
CID: 0x0001
code: 0x04
identifier: 0xff
length: 0x0004
data: b'B\x00\x0f\x00'
DCID: 0x0042
flags: 0x000f
config_opts: b''
[INFO] Passed level1data_level2signal, L2CAP_CONFIGURATION
info_payload_len1: 8
CID1: 65
info_payload_len2: 4
CID2: 66
payload2: b'flag'
gatt_safe_box
本题考查的层次为BLE的GATT层,考查点是GATT业务的猜测分析,需要了解的协议为:通用属性配置文件(GATT)
- 源码:gatt_safe_box.py
- 解题过程HCI包:gatt_safe_box_hci.pcapng
- 解题过程空口包:gatt_safe_box_hci.pcapng
完成题目需要与目标完成GATT通信,可以参考 pygatt 的 subscribe_indicate_thermometer_sample.py ,最终解题脚本如下:
import pygatt,time
from Crypto.Cipher import AES
kl = [b'VmYZWYe2xGpy1Ifk',
b'm55GRyWz7jk6UL9O',
b'7Dz2UyaPTYaINOhT',
b'7DU4xpwOaBE9dVnu',
b'5vquNX1PZuatGD4X',
b'V6TNSErhXPgdJSZU',
b'8rrkcBSw9928pxmj',
b'rYA6xm9mP1gqdItZ',
b'dxj4iwXPBRPM2uk4',
b'lry0CrP5HDGL5VqY']
adapter = pygatt.GATTToolBackend()
adapter.start()
device = adapter.connect('82:56:42:A1:06:42')
print("connected successfully")
def log(handle, value):
value = bytes.fromhex(value.hex())
print(b"[+] recv: "+ value)
def battery(handle, value):
value = bytes.fromhex(value.hex())
key = kl[ int(int(value.hex(),16)/10) - 1 ]
a = AES.new(key, AES.MODE_ECB)
cipher = a.encrypt('DBAPPSecurHatLab'.encode())
device.char_write("11111111-1111-1111-1111-111111111110",cipher, wait_for_response=False)
print(b"[+] key: "+ key)
print(b"[+] cipher: "+ cipher)
device.subscribe("00002a19-0000-1000-8000-00805f9b34fb",callback=battery, wait_for_response=False)
device.subscribe("11111111-1111-1111-1111-111111111110",callback=log, wait_for_response=False)
time.sleep(1000)
ubuntu21.04下我的蓝牙外设不稳定,最终在ubuntu16.04下稳定执行:
➜ python3 connet_gatt.py
connected successfully
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: rYA6xm9mP1gqdItZ'
b'[+] cipher: Mw\xed\xbd\xb0R\xc6_\x985J\x91\t\x8d\x8e\x9e'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: 8rrkcBSw9928pxmj'
b'[+] cipher: \xc4\xc52\xb7+R\xe8\xb5\xc6\xbe\xa0\xbd\x1eJ\xc4\xdf'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: VmYZWYe2xGpy1Ifk'
b'[+] cipher: Vw-\x0b\xdc\xb6zz\x0f\xe79S\x80\xc0\x17)'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: 7DU4xpwOaBE9dVnu'
b'[+] cipher: #\x93B\x0f\xd6kr~\xc6\xe8\xc5_g\xed u'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: dxj4iwXPBRPM2uk4'
b"[+] cipher: \xfe\xe0\t\xd9i\xd0\x9f\xc3`\x8a\xaf'\x8f7\x9db"
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: V6TNSErhXPgdJSZU'
b'[+] cipher: \xb7`\xe071P\xbb\x00w\xd05-\x95\xbb\xad\xcd'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: rYA6xm9mP1gqdItZ'
b'[+] cipher: Mw\xed\xbd\xb0R\xc6_\x985J\x91\t\x8d\x8e\x9e'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: rYA6xm9mP1gqdItZ'
b'[+] cipher: Mw\xed\xbd\xb0R\xc6_\x985J\x91\t\x8d\x8e\x9e'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: dxj4iwXPBRPM2uk4'
b"[+] cipher: \xfe\xe0\t\xd9i\xd0\x9f\xc3`\x8a\xaf'\x8f7\x9db"
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: DBAPPSecurHatLab'
b'[+] key: V6TNSErhXPgdJSZU'
b'[+] cipher: \xb7`\xe071P\xbb\x00w\xd05-\x95\xbb\xad\xcd'
b'[+] recv: DBAPPSecurHatLab'
b'[+] recv: flag_6onT@ttach_bkdr'
板子串口输出:
hci0: Type: Primary Bus: UART
BD Address: A6:50:92:7A:97:14 ACL MTU: 1021:8 SCO MTU: 64:1
UP RUNNING
RX bytes:916 acl:0 sco:0 events:36 errors:0
TX bytes:428 acl:0 sco:0 commands:36 errors:0
[ 80.348495] g_ether gadget: high-speed config #1: CDC Ethernet (ECM)
[INFO] Using /org/bluez/hci0
[INFO] Registering RootObject...
[INFO] mainloop run
[DEBUG] RootObject, GetManagedObjects
[INFO] RootObject registered
[DEBUG] BatteryLevelCharac StartNotify
[DEBUG] BackdoorCharac StartNotify
[INFO] Current battery level: 80
[INFO] Current key: b'rYA6xm9mP1gqdItZ'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 1
[INFO] Current battery level: 70
[INFO] Current key: b'8rrkcBSw9928pxmj'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 2
[INFO] Current battery level: 10
[INFO] Current key: b'VmYZWYe2xGpy1Ifk'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 3
[INFO] Current battery level: 40
[INFO] Current key: b'7DU4xpwOaBE9dVnu'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 4
[INFO] Current battery level: 90
[INFO] Current key: b'dxj4iwXPBRPM2uk4'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 5
[INFO] Current battery level: 60
[INFO] Current key: b'V6TNSErhXPgdJSZU'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 6
[INFO] Current battery level: 80
[INFO] Current key: b'rYA6xm9mP1gqdItZ'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 7
[INFO] Current battery level: 80
[INFO] Current key: b'rYA6xm9mP1gqdItZ'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 8
[INFO] Current battery level: 90
[INFO] Current key: b'dxj4iwXPBRPM2uk4'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 9
[INFO] Current battery level: 60
[INFO] Current key: b'V6TNSErhXPgdJSZU'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 10
[INFO] Current battery level: 100
[INFO] Current key: b'lry0CrP5HDGL5VqY'
[DEBUG] BackdoorCharac, WriteValue
[INFO] plaintext_bin b'DBAPPSecurHatLab'
[INFO] Hit count: 11
[INFO] Current battery level: 30
[INFO] Current key: b'7Dz2UyaPTYaINOhT'
[DEBUG] BatteryLevelCharac StopNotify
[DEBUG] BackdoorCharac StopNotify