20、BLE安全调试与测试:hcitool使用、btmon抓包分析、Wireshark BLE协议解析、Android HCI日志
做BLE安全分析,说白了就是一场「你 vs 协议栈」的博弈。你猜设备在干什么,但只有抓到包才能实锤。我个人习惯把这套调试工具链称为「BLE安全三件套」——hcitool、btmon、Wireshark。再加上Android的HCI日志,基本能覆盖从底层到应用层的所有调试需求。
嗯,咱们一个一个来聊。
20.1 hcitool:命令行里的瑞士军刀
hcitool是BlueZ工具集里最常用的一个。它可以直接跟蓝牙控制器对话,不需要经过上层协议栈。你想想看,这意味着什么?意味着你能绕过很多「安全过滤」,直接看到硬件层面的行为。
核心用法:
hcitool dev— 列出本地蓝牙设备hcitool scan— 执行经典蓝牙扫描hcitool lescan— 执行BLE扫描(注意:需要sudo)hcitool lecc— 发起BLE连接hcitool leinfo— 获取连接参数
我在项目中遇到过一件事:某款智能门锁在配对时,用hcitool lescan能直接抓到它的广播包,里面竟然包含了设备的静态地址。你猜怎么着?这个地址在整个生命周期里都不变。说白了,这就是一个可以被追踪的「硬件指纹」。
# 扫描BLE设备
sudo hcitool lescan --passive
# 连接指定设备
sudo hcitool lecc --random AA:BB:CC:DD:EE:FF
# 查看连接信息
sudo hcitool leinfo --random AA:BB:CC:DD:EE:FF
我的小技巧:用--passive参数做被动扫描,这样不会主动发送扫描请求,能避免被某些「反扫描」设备检测到。
20.2 btmon:蓝牙监控器的正确打开方式
btmon是BlueZ自带的蓝牙监控工具。它能捕获HCI层、L2CAP层、甚至部分ATT层的流量。我个人觉得,btmon最大的优势是——它跟系统协议栈是「同源的」,所以解析出来的信息非常准确。
我曾经调试过一个配对失败的案例。设备A和设备B明明都支持LE Secure Connections,但就是配对不成功。用btmon一抓,发现是设备A在发送Pairing Request时,把IO Capability设成了NoInputNoOutput,而设备B要求至少一方有输入能力。嗯,这就是典型的「能力不匹配」问题。
# 启动btmon,实时监控蓝牙流量
sudo btmon
# 保存到文件,方便后续分析
sudo btmon -w ble_trace.log
# 读取已有的日志文件
sudo btmon -r ble_trace.log
注意:btmon需要root权限。而且它捕获的是HCI层的流量,所以只能看到主机和控制器之间的交互。如果你想看空中的无线电信号,那得用专门的嗅探硬件。
20.3 Wireshark BLE协议解析:从比特到语义
Wireshark是协议分析的终极武器。它支持BLE协议栈的完整解析,从HCI到L2CAP,再到ATT、GATT、SMP。你想想看,一个配对请求包,Wireshark能帮你把每个字段都拆开——AuthReq里的哪些位被置位了,IO Capability是什么,OOB数据有没有带。
我个人习惯的做法是:先用btmon抓原始数据,然后用Wireshark打开分析。为什么?因为btmon的格式Wireshark直接支持,而且Wireshark的图形化界面比命令行友好太多了。
Wireshark中BLE分析的关键过滤器:
| 过滤器 | 作用 |
|---|---|
btle |
过滤所有BLE流量 |
btl2cap |
过滤L2CAP层 |
btatt |
过滤ATT协议 |
btsmp |
过滤安全管理协议(SMP) |
btle.advertising_address |
按广播地址过滤 |
我记得有一次分析一个「中间人攻击」的案例。攻击者伪造了一个蓝牙设备,广播包里的Service UUID跟正品一模一样。但用Wireshark一解析,发现攻击者的广播包在Manufacturer Specific Data字段里少了一个字节。就这一个字节的差异,暴露了攻击者的身份。
调试技巧:在Wireshark里右键点击某个字段,选择「Apply as Column」,就能把这个字段单独显示成一列。比如把btle.advertising_address和btle.advertising_data都设成列,一眼就能看出哪些设备在「撞地址」。
20.4 Android HCI日志:移动端的调试利器
Android设备上的蓝牙调试,比Linux桌面要麻烦一些。但Google还是留了后门——HCI日志。你可以在开发者选项里开启「蓝牙HCI日志」功能,系统会把所有蓝牙HCI包保存到/sdcard/btsnoop_hci.log。
这个日志的格式是标准的btsnoop格式,Wireshark可以直接打开。我建议你在做Android BLE安全测试时,一定把这个功能打开。为什么?因为很多安全问题,比如配对过程中的密钥协商、加密启动流程,只有看HCI日志才能搞清楚。
# 开启HCI日志(需要开发者选项)
设置 → 开发者选项 → 蓝牙HCI日志 → 开启
# 日志文件位置
/sdcard/btsnoop_hci.log
# 用adb拉取日志
adb pull /sdcard/btsnoop_hci.log .
注意:开启HCI日志会影响蓝牙性能,而且日志文件会持续增长。我建议只在调试阶段开启,调试完就关掉。另外,有些厂商的定制ROM可能移除了这个功能,或者改了日志路径。
我曾经在测试一款Android平板时,发现它的BLE配对总是失败。开启HCI日志后,发现设备在收到Pairing Response后,直接发了一个Pairing Failed,错误码是0x05(PIN or Key Missing)。这说明设备端的LTK存储出了问题。后来确认是厂商的蓝牙驱动在休眠后丢失了密钥。
20.5 知识体系总览
下面这张图,是我整理的BLE安全调试工具链的整体结构。你可以看到,从底层到上层,每个工具负责不同的层次。
从这张图你可以看到,hcitool和btmon主要工作在HCI层,Android HCI日志也是这一层。而Wireshark能解析从HCI到GATT的所有层次。我个人建议的调试流程是:先用hcitool做快速验证,再用btmon抓详细日志,最后用Wireshark做深度分析。
总结一下核心要点:
- hcitool — 快速验证,适合做「有没有、能不能」的判断
- btmon — 实时监控,适合做「发生了什么」的追踪
- Wireshark — 深度分析,适合做「为什么这样」的根因定位
- Android HCI日志 — 移动端调试,适合做「设备兼容性」的验证
嗯,这套工具链我用了好几年。每次遇到BLE安全问题,基本都能靠它们找到根因。你想想看,如果连协议层面的交互都看不清楚,那所谓的「安全分析」不就是盲人摸象吗?
最后一个小建议:别只依赖一种工具。hcitool告诉你「有设备」,btmon告诉你「设备在发什么包」,Wireshark告诉你「包里的每个比特是什么意思」。三个工具配合使用,才能看到全貌。