Sweyntooth 低功耗蓝牙(BLE)漏洞的概念验证。
本仓库是 ASSET Research Group 研究成果的一部分。

SweynTooth 涵盖六大主要片上系统(SoC)厂商的不同低功耗蓝牙(BLE)软件开发套件(SDK)中的一系列 18 个漏洞。这些漏洞暴露了特定 BLE SoC 实现中的缺陷,使无线电范围内的攻击者能够根据具体情况触发死锁、崩溃和缓冲区溢出,或完全绕过 安全防护。(更新)我们还加入了一个测试脚本,用于检查设备是否受 BLE KNOB 变体影响。
你可以在 ASSET Research Group SweynTooth 披露网站 上查看有关这些漏洞、可用补丁和受影响设备的更多信息。
Fitbit、August Smart Lock、Eve Energy、CubiTag 以及其他“智能”设备均受影响。
此 PoC 使用了维护良好的库,例如 Scapy 和 Colorama。BLE 数据包的构造与解析通过定制的 Scapy 协议层完成(bluetooth4LE 和 bluetooth.py)。目前有一个正在进行中的合并请求,旨在将我们的新增内容包含到 Scapy 的主仓库中。
首先,你必须确保系统装有 Python2.7,并安装了 requirements.txt 文件中列出的 Python 包。
如果你使用的是 Ubuntu,请运行以下命令:
sudo apt-get install python2.7
sudo pip install -r requirements.txt
其次,SweynTooth 使用 Nordic nRF52840 Dongle 在无线链路上向易受攻击的外设发送和接收原始链路层数据包。在启动 Python 2.7 脚本之前,必须先将驱动固件烧录到开发板上。
我们固件代码的二进制文件位于 nRF52_driver_firmware.zip 文件中。你需要安装 nrfutil 工具才能将固件烧录到开发板上。请记住在烧录前将 nRF52840 置于 DFU 模式(在 USB Dongle 连接到 PC 时,按下小型重置按钮重置它)。
你可以运行以下命令来安装 Python 依赖项并烧录固件:
python -m pip install nrfutil pyserial pycryptodome
nrfutil dfu usb-serial -p COM_PORT -pkg nRF52_driver_firmware.zip
这些脚本可在 Linux 或 Windows 上运行。你只需更改 COM_PORT 参数,使其与 nRF52840 的端口名称匹配。
如果上述烧录方法无效,你还可以使用 nRF Connect App for Desktop 来烧录固件,它提供了一个良好的界面来烧录 hex 固件(nRF52_driver_firmware.hex)。
安装好所需依赖项后,你可以通过执行以下命令来运行漏洞利用脚本:
python Telink_key_size_overflow.py COM7 A4:C1:38:D8:AD:A9
第一个参数是串口名称(在 Linux 上通常是 /dev/ttyACM0),第二个参数是易受攻击的 BLE 设备的地址。你可以使用任何 BLE 扫描器或 nRF Connect App 来发现该地址。
以密钥长度溢出漏洞为例,如果易受攻击的设备在崩溃后挂起,脚本将输出以下内容:

如果你想通过 Docker 镜像使用 SweynTooth,从而避免安装 Python 依赖项,可以使用 docker.sh 辅助脚本来构建并运行 Docker 实例,或者从 releases 页面下载预构建的 Docker 镜像(链接)。docker.sh 的用法如下所述。
--------- HELP -------------
sudo ./docker run <script_name> <serial_port> <ble_target_address> - Start any sweyntooth script by its name (<script_name>)
sudo ./docker build - Build docker container
sudo ./docker build release - Build docker container and create compressed image for release
sudo ./docker shell - Start docker container shell
---------- EXAMPLE ----------
./docker.sh run extras/Microchip_and_others_non_compliant_connection.py /dev/ttyACM0 f0:f8:f2:da:09:63
每个漏洞利用脚本对应一个缺陷。下表总结了漏洞与在受影响 SoC 上利用漏洞的脚本之间的对应关系。
通常,使用受影响 SoC 的产品会采用看门狗(watchdog),在发生故障时自动重启 BLE SoC,因此并非所有产品都会被死锁。尽管如此,如果产品崩溃并重启,仍有可能从产品上获得一些视觉或音频提示。
SweynTooth 中最关键的漏洞是零 LTK 安装,它允许攻击者通过强制使用零填充 LTK 的加密设置过程,完全绕过最新的蓝牙配对流程(安全连接)。要对你的设备测试此漏洞,设备必须接受或支持将安全连接作为配对方式。你可以按如下方式运行 PoC:
python Telink_zero_ltk_installation.py COM7 A4:C1:38:D8:AD:A9
请注意,参数 COM7 和 A4:C1:38:D8:AD:A9 会因你的设置而异。如果设备存在漏洞,PoC 将输出以下内容:

LLID 死锁脚本在每次与外设重新连接时,以交替方式发送版本请求或配对请求,同时清除 LLID 字段。这样做是为了在 NXP 和 Cypress 的易受攻击 SoC 上触发该漏洞。当对易受攻击的 KW41Z 运行该脚本时,协议栈会发生死锁,并应发送乱序的链路层数据包。该脚本会尝试检测协议栈何时死锁,并对易受攻击的 KW41Z 设备输出以下内容:

易受攻击的 Cypress 设备通常会在攻击后禁用广播。因此,你应该会看到一条指示已检测到崩溃的错误消息。当使用此脚本对易受攻击的 Fitbit Inspire 进行测试时,智能手表要么立即崩溃,要么暂时禁用其广播。对此设备进行间歇性攻击应会导致永久性的 BLE 故障,需要用户手动重启 Fitbit Inspire。
虽然 KNOB 主要影响蓝牙经典设备(因为密钥长度被缩减到 1 字节),但在 SMP 配对过程中,仍然可以将低功耗蓝牙设备的密钥熵降低到 7 字节(符合规范的最小密钥长度)。这种合规的 BLE 熵降低的影响已在 《Low Entropy Key Negotiation Attacks on Bluetooth and Bluetooth Low Energy》(Antonioli, Daniele 等人著) 中进行了讨论。
我们提供了一个简单的脚本,用于检查 BLE 外设设备可接受哪些密钥长度。你可以按如下方式运行 BLE KNOB 测试器:
# Windows
python extras\knob_tester_ble.py COM6 a4:c1:38:d8:ad:a9
# Linux
python extras/knob_tester_ble.py /dev/ttyACM0 a4:c1:38:d8:ad:a9
不要忘记根据 nRF52 Dongle 的串口(在 Linux 上通常是 /dev/ttyACM0)和被测 BLE 设备的地址,将 COM6 和 a4:c1:38:d8:ad:a9 改为其他值。如果工具检测到外设接受除 16 字节以外的其他密钥长度,则会列出它们,如下所示:

captures 文件夹包含每个漏洞的一些示例捕获文件。我们还添加了一些在部分 SoC 中检测到的不合规案例。
extras 文件夹 包含一些与不合规情况以及某些 SweynTooth 变体相关的附加脚本。有关更多信息,请查看 extras/README.md 中的附加脚本表。
本研究部分得到了 Keysight Technologies 的支持。
| 漏洞 | CVE(s) | 厂商 | 脚本文件 |
|---|
| 链路层长度溢出 | CVE-2019-16336 CVE-2019-17519 | Cypress NXP | link_layer_length_overflow.py |
| LLID 死锁 | CVE-2019-17061 CVE-2019-17060 | Cypress NXP | llid_dealock.py |
| 截断的 L2CAP | CVE-2019-17517 | Dialog | DA14580_exploit_att_crash.py |
| 静默长度溢出 | CVE-2019-17518 | Dialog | DA14680_exploit_silent_overflow.py |
| 公钥崩溃 | CVE-2019-17520 | Texas Instruments | CC2640R2_public_key_crash.py |
| 无效的连接请求 | CVE-2019-19193 | Texas Instruments | CC_connection_req_crash.py |
| 无效的 L2CAP 分片 | CVE-2019-19195 | Microchip | Microchip_invalid_lcap_fragment.py |
| 顺序 ATT 死锁 | CVE-2019-19192 | STMicroelectronics | sequential_att_deadlock.py |
| 密钥长度溢出 | CVE-2019-19196 | Telink | Telink_key_size_overflow.py |
| 零 LTK 安装 | CVE-2019-19194 | Telink | Telink_zero_ltk_installation.py |
| DHCheck 跳过 | CVE-2020-13593 | Texas Instruments | non_compliance_dhcheck_skip.py |
| ESP32 HCI 失步 | CVE-2020-13595 | Espressif Systems | esp32_hci_desync.py |
| Zephyr 无效序列 | CVE-2020-10061 | Zephyr Project | zephyr_invalid_sequence.py |
| 无效信道映射 | CVE-2020-10069 CVE-2020-13594 | Zephyr Project Espressif Systems Microchip | invalid_channel_map.py |