Skip to content

7x01 - Bluetooth Security

Android 的蓝牙协议栈是近年远程RCE漏洞的重灾区。

蓝牙的安全研究价值在于:

  • 无需用户交互:通过无线近场即可触发
  • 协议复杂度高:多层协议栈(HCI/L2CAP/SDP/RFCOMM/GATT...)
  • 实现差异大:芯片厂商(Broadcom/Qualcomm)与系统层实现各异
  • 攻击面广:从固件到framework多层可攻击

1. 架构与协议栈

1.1 分层结构

text
┌─────────────────────────────────────┐
│   Java Framework (Settings/BT App)  │  ← 应用层API
├─────────────────────────────────────┤
│   com.android.bluetooth Process     │  ← Java服务(GATT/A2DP/HFP)
├─────────────────────────────────────┤
│   Bluetooth Stack (Fluoride/Gabeldorsche) │ ← C++协议栈
│   - L2CAP, SDP, RFCOMM, GATT        │
├─────────────────────────────────────┤
│   HCI (Host Controller Interface)   │  ← 与芯片通信接口
├─────────────────────────────────────┤
│   Bluetooth Controller (Firmware)   │  ← 芯片固件
└─────────────────────────────────────┘

1.2 关键组件

Fluoride vs Gabeldorsche:

  • Fluoride:Android传统蓝牙栈(至Android 12)
  • Gabeldorsche:Google 重构的蓝牙栈(逐步引入,Android 13 起更广泛采用),引入 Rust 组件以提升内存安全性

核心协议:

  • L2CAP:逻辑链路控制与适配协议,提供分片重组
  • SDP:服务发现协议
  • RFCOMM:串口仿真协议(蓝牙串口profile基础)
  • GATT:BLE通用属性协议(蓝牙低功耗核心)
  • SMP:安全管理协议(配对/加密)

2. 历史重大漏洞分析

2.3 BrakTooth系列(2021) - 芯片层漏洞

特点:影响蓝牙芯片固件而非Android系统

典型漏洞

  • LMP协议解析错误:link management protocol处理缺陷
  • 固件崩溃/DoS:大部分为拒绝服务,少数可RCE
  • 影响范围:Broadcom/Qualcomm/Intel等主流芯片

攻击路径

text
HCI命令 → 芯片固件 → LMP消息解析 → 固件崩溃/代码执行

防御难度:需要芯片厂商固件更新,Android系统层无法直接修复

2.4 近期持续漏洞

注:此前本节曾将 CVE-2023-20938 列为 L2CAP 整数溢出漏洞,但该 CVE 实际为 Binder 驱动 UAF 漏洞,与蓝牙无关,已移除。

L2CAP 协议解析仍是蓝牙安全的高发攻击面,历史上多次出现类似漏洞,证明此类攻击面仍未完全收敛。

3. 攻击面深度剖析

3.1 经典蓝牙攻击面

L2CAP - 最高危

  • 分片重组:历史上多次出现堆溢出(BlueBorne/BlueFrag)
  • 配置协商:参数验证不足导致整数溢出
  • 状态机:连接/断开竞态条件

RFCOMM

  • 信用流控制逻辑错误
  • 串口数据解析(AT命令注入等应用层问题)

SDP (服务发现)

  • 响应包解析(长度字段/嵌套TLV)
  • 服务记录注入

3.2 BLE (蓝牙低功耗) 攻击面

GATT

  • 特征值读写时的内存管理
  • 通知/指示的序列化/反序列化
  • 服务发现响应解析

SMP (安全配对)

  • 配对过程的密码学实现错误
  • Just Works模式的中间人风险
  • 密钥协商的整数溢出

3.3 进程与权限边界

com.android.bluetooth进程

bash
u:r:bluetooth:s0    bluetooth  12345  1  ...

关键特征

  • UID: bluetooth (1002)
  • SELinux域: bluetooth
  • 权限:可访问蓝牙硬件、配置、部分系统服务
  • 限制:不能访问应用私有数据、不能直接访问网络

横向移动路径

  • 攻击bluetooth进程 → 通过Binder利用system_server
  • 需要结合其他漏洞才能达成完整设备控制

4. 漏洞挖掘方法

4.1 静态分析重点

协议解析关键模式

cpp
// 危险模式1: 信任外部长度字段
uint16_t pkt_len = *(uint16_t*)data;  // 来自无线包
buffer = malloc(pkt_len);              // 未检查上界
memcpy(buffer, data+2, pkt_len);     // 堆溢出

// 危险模式2: 分片重组
total_len = first_fragment->total;
buffer = malloc(total_len);
for each fragment:
    offset += fragment->len;           // ❌ 未检查累计长度
    memcpy(buffer+offset, fragment->data, fragment->len);

// 危险模式3: 状态机竞态
if (connection->state == CONNECTED) {
    // ❌ 检查与使用之间可能被异步修改
    process_data(connection);
}

审计Checklist

  • [ ] 所有来自HCI的长度字段是否有上界检查
  • [ ] 分片重组是否防止超界累加
  • [ ] 并发场景的连接对象生命周期管理
  • [ ] 配对状态与权限检查的一致性

4.2 Fuzzing策略

HCI Fuzzing

python
# 使用btlejack/scapy等工具构造畸形HCI包
from scapy.all import *

# 构造畸形L2CAP包
l2cap_pkt = L2CAP_Hdr(len=0xFFFF) / Raw(b"A"*1000)
send_hci_packet(l2cap_pkt)

工具链

  • btlejack:BLE嗅探与注入
  • ubertooth:经典蓝牙嗅探
  • InternalBlue:Broadcom芯片调试框架
  • BLEah:自动化BLE fuzzing

关键测试点

  • L2CAP MTU边界值
  • 分片序列异常顺序(乱序/重复/缺失)
  • SDP服务记录嵌套深度
  • GATT特征值超长数据

4.3 动态调试

日志收集

bash
# 开启蓝牙详细日志
adb shell setprop log.tag.bluetooth VERBOSE
adb shell setprop log.tag.bt_btif VERBOSE

# 实时监控
adb logcat -b main | grep -iE 'bluetooth|l2cap|gatt|btif'

# HCI snoop log(需要开发者选项)
adb shell setprop persist.bluetooth.btsnooplogmode full
# 日志位置: /data/misc/bluetooth/logs/btsnoop_hci.log
adb pull /data/misc/bluetooth/logs/btsnoop_hci.log

使用Wireshark分析HCI日志

bash
wireshark btsnoop_hci.log
# 过滤器: bthci || btl2cap || btatt

5. 漏洞复现与利用

5.1 环境准备

硬件需求

  • 攻击端:Linux机器 + 蓝牙USB适配器 / Ubertooth One / BLE dongle
  • 目标端:待测试的Android设备

软件工具

bash
# 安装BlueZ协议栈工具
apt-get install bluez libbluetooth-dev

# 安装分析工具
apt-get install wireshark

# Python蓝牙库
pip install pybluez PyBluez-wheels scapy

5.2 PoC开发流程

python
#!/usr/bin/env python3
# 仅供教育目的,请勿用于未授权测试
import socket
from struct import pack

def send_malicious_l2cap(target_mac):
    # 建立L2CAP连接
    sock = socket.socket(socket.AF_BLUETOOTH, socket.SOCK_RAW, socket.BTPROTO_L2CAP)
    sock.connect((target_mac, 1))  # PSM=1
    
    # 构造畸形分片序列
    # 第一个分片声称总长度很小
    frag1 = pack('<HH', 0x100, 0x00) + b'A' * 0x100
    
    # 后续分片累计超出总长度
    frag2 = b'B' * 0x1000
    frag3 = b'C' * 0x1000
    
    sock.send(frag1)
    sock.send(frag2)
    sock.send(frag3)
    
    sock.close()

# 使用时需修改为目标设备MAC
# send_malicious_l2cap("XX:XX:XX:XX:XX:XX")

5.3 漏洞利用难点

现代缓解机制

  1. ASLR:需要信息泄露漏洞
  2. DEP/NX:需要ROP/JOP
  3. SELinux:bluetooth域权限有限
  4. 进程隔离:com.android.bluetooth权限不足以完全控制设备

实战利用链

text
[信息泄露] → 破解ASLR

[堆溢出/UAF] → 控制EIP/RIP

[ROP chain] → 绕过DEP执行shellcode

[Binder exploit] → 横向攻击system_server

[Kernel LPE] → 获取root权限

6. 防御与加固

6.1 系统层防护

进程隔离

  • com.android.bluetooth运行在独立进程
  • UID=1002 (bluetooth)
  • SELinux domain=bluetooth

权限限制

text
# bluetooth域典型SELinux策略(简化版)
allow bluetooth bluetooth_prop:file read;
allow bluetooth hci_device:chr_file rw;
neverallow bluetooth app_data_file:file *;  # 禁止访问应用数据

Seccomp过滤

  • 限制bluetooth进程可用syscall
  • 禁止execve/ptrace等危险调用

6.2 开发建议

协议解析安全编码

cpp
// ✅ 安全模式
bool parse_l2cap_fragment(const uint8_t* data, size_t len) {
    if (len < L2CAP_HDR_SIZE) return false;
    
    uint16_t pkt_len = *(uint16_t*)data;
    
    // 严格上界检查
    if (pkt_len > L2CAP_MAX_MTU) {
        LOG_ERROR("Packet too large: %u", pkt_len);
        return false;
    }
    
    // 检查实际数据长度
    if (len < L2CAP_HDR_SIZE + pkt_len) {
        return false;
    }
    
    // 安全分配
    uint8_t* buffer = (uint8_t*)calloc(1, pkt_len);
    if (!buffer) return false;
    
    memcpy(buffer, data + L2CAP_HDR_SIZE, pkt_len);
    
    // ... process buffer ...
    free(buffer);
    return true;
}

状态机安全模式

cpp
class Connection {
    std::mutex state_mutex;
    ConnectionState state;
    
    void process_data(const uint8_t* data, size_t len) {
        std::lock_guard<std::mutex> lock(state_mutex);
        
        // TOCTOU安全:在锁内检查和使用状态
        if (state != CONNECTED) {
            return;
        }
        // ... 处理数据 ...
    }
};

6.3 用户防护

最佳实践

  • 不使用时关闭蓝牙
  • 避免在公共场所开启"可发现"模式
  • 及时安装安全更新
  • 警惕未知设备的配对请求

参考(AOSP)