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_addressbtle.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安全调试工具链的整体结构。你可以看到,从底层到上层,每个工具负责不同的层次。

BLE安全调试工具链 蓝牙控制器(硬件) HCI 命令 / 事件 / 数据 HCI 层 hcitool / btmon / Android HCI 日志 L2CAP / SMP 层 配对过程 / 密钥协商 / 加密启动 ATT / GATT 层 Wireshark 协议解析 / 服务发现 / 属性操作 底层 上层

从这张图你可以看到,hcitool和btmon主要工作在HCI层,Android HCI日志也是这一层。而Wireshark能解析从HCI到GATT的所有层次。我个人建议的调试流程是:先用hcitool做快速验证,再用btmon抓详细日志,最后用Wireshark做深度分析。

总结一下核心要点:

  • hcitool — 快速验证,适合做「有没有、能不能」的判断
  • btmon — 实时监控,适合做「发生了什么」的追踪
  • Wireshark — 深度分析,适合做「为什么这样」的根因定位
  • Android HCI日志 — 移动端调试,适合做「设备兼容性」的验证

嗯,这套工具链我用了好几年。每次遇到BLE安全问题,基本都能靠它们找到根因。你想想看,如果连协议层面的交互都看不清楚,那所谓的「安全分析」不就是盲人摸象吗?

最后一个小建议:别只依赖一种工具。hcitool告诉你「有设备」,btmon告诉你「设备在发什么包」,Wireshark告诉你「包里的每个比特是什么意思」。三个工具配合使用,才能看到全貌。

公众号:蓝海资料掘金营,微信deep3321