BleedingTooth: Linux 蓝牙零点击远程代码执行漏洞
字数 1598 2025-08-05 11:39:35
Linux蓝牙零点击远程代码执行漏洞(BleedingTooth)分析
漏洞概述
BleedingTooth是Linux蓝牙子系统中的一组零点击漏洞集合,允许未经授权的远程攻击者在近距离内以内核权限执行任意代码。这组漏洞包括:
- BadVibes (CVE-2020-24490):基于堆的缓冲区溢出漏洞
- BadChoice (CVE-2020-12352):基于栈的信息泄漏漏洞
- BadKarma (CVE-2020-12351):基于堆类型的混淆漏洞
漏洞详情
BadVibes: 基于堆的缓冲区溢出漏洞
影响版本:Linux内核4.19及以上
漏洞位置:hci_le_adv_report_evt()和hci_le_ext_adv_report_evt()函数
漏洞原理:
- 蓝牙5.0规范将广播有效载荷从31字节扩展到255字节
- Linux实现中
last_adv_data缓冲区仍保持31字节大小 - 当处理扩展广播报告时,未检查长度是否超过
HCI_MAX_AD_LENGTH - 导致
memcpy(d->last_adv_data, data, len)堆溢出
利用条件:
- 受害者设备使用蓝牙5芯片
- 受害者正在扫描蓝牙设备(如打开蓝牙设置)
BadChoice: 基于栈的信息泄漏漏洞
影响版本:Linux内核3.6及以上
漏洞位置:a2mp_getinfo_req()函数
漏洞原理:
- 当处理无效控制器ID时,
a2mp_info_rsp结构体未完全初始化 - 响应中包含16字节未初始化的栈内存
- 可泄漏内核栈上的敏感信息,包括指针
利用条件:
- 需要
CONFIG_BT_HS=y(默认启用)
BadKarma: 基于堆类型的混淆漏洞
影响版本:Linux内核4.8及以上
漏洞位置:A2MP信道处理
漏洞原理:
- A2MP信道配置为ERTM模式
chan->data应为struct sock类型,但实际为struct amp_mgr- 导致
sk_filter()中类型混淆 - 可控制
sk_filter指针实现任意代码执行
漏洞利用链
1. 利用BadChoice泄漏内存布局
通过发送精心构造的A2MP_GETINFO_REQ请求:
- 泄漏内核.text段地址(计算KASLR偏移)
- 泄漏
l2cap_chan对象地址
2. 构造可控堆布局
利用A2MP_GETAMPASSOC_RSP指令:
- 使用
kmemdup()分配可控大小的内存 - 通过多次分配/释放构造特定堆布局
- 使
struct amp_mgr对象后跟随可控内存块
3. 触发BadKarma类型混淆
- 重新配置A2MP信道为BASIC模式绕过初始检查
- 通过污染
sk_filter指针控制执行流 - 利用BPF机制实现RIP控制
4. 内核ROP链执行
构建ROP链实现任意命令执行:
- 使用stack pivot gadget将RSP指向可控内存
- 调用
run_cmd()执行反向shell命令 - 调用
do_task_dead()终止内核线程
漏洞修复
补丁发布时间线:
- 2020-07-30:BadVibes补丁提交
- 2020-09-25:BadChoice和BadKarma补丁提交
- 2020-10-13:公开披露
主要修复措施:
- 添加广播数据长度检查
- 初始化响应结构体
- 修正类型使用
防护建议
- 及时更新内核至修复版本
- 禁用不必要的蓝牙功能
- 限制蓝牙设备发现范围
- 考虑禁用蓝牙5.0高速功能
技术总结
BleedingTooth漏洞链展示了蓝牙协议栈中多个组件的安全问题:
- 规范变更与实现不一致导致边界问题
- 未初始化内存导致信息泄漏
- 类型系统混淆导致权限提升
- 复杂的协议状态机引入安全风险
该研究也推动了Linux内核蓝牙子系统的进一步安全审计和改进。