Nordic nRF Sniffer实战:5分钟搞定BLE加密报文抓包与解密(附LESC配对调试技巧)

Nordic nRF Sniffer实战:5分钟搞定BLE加密报文抓包与解密(附LESC配对调试技巧)

如果你正在开发基于BLE的物联网设备,或者需要对蓝牙通信进行安全分析,那么抓包和解密加密报文无疑是绕不开的关键技能。很多开发者第一次尝试抓取BLE通信时,常常在设备配对后陷入困境——Wireshark里一片“Encrypted packet decrypted incorrectly”的红色警告,加密后的数据包完全无法解析。这背后其实是BLE安全机制在起作用,特别是从BLE 4.2开始引入的LE Secure Connections(LESC)配对机制,它让传统的抓包工具束手无策。

不过别担心,今天我要分享的这套方案,能让你在5分钟内搭建起完整的BLE抓包环境,并且连LESC加密后的通信也能轻松解密。这套方案基于Nordic官方的nRF Sniffer固件和Wireshark,成本极低(只需要一块几十元的nRF52840 Dongle),却能提供接近专业协议分析仪的效果。更重要的是,我会详细拆解如何通过修改SDK启用Debug模式来获取私钥,让你不仅能抓包,还能深入理解BLE加密通信的每一个细节。

1. 环境搭建:从零开始的抓包平台

1.1 硬件选择与准备

要搭建BLE抓包环境,首先需要选择合适的硬件。市面上有多种BLE Sniffer方案,但Nordic的nRF Sniffer因其开源、易用且成本低廉而备受青睐。

硬件对比表:

硬件设备 价格范围 优点 缺点 推荐场景
nRF52840 Dongle 50-100元 成本极低,官方支持完善,性能强劲 需要烧录Sniffer固件 个人开发者、教育研究
nRF52 DK开发板 300-500元 自带调试器,功能全面 价格较高,体积较大 专业开发团队
Ellisys蓝牙分析仪 20-30万元 专业级,功能强大,支持多种协议 价格昂贵 企业级产品开发、深度安全分析
Ubertooth One 1000-2000元 开源硬件,社区活跃 配置复杂,性能有限 安全研究人员

对于大多数开发者来说,nRF52840 Dongle是最佳选择。它基于Nordic的nRF52840芯片,支持BLE 5.0,性能足够应对绝大多数场景。

注意:购买时请确保选择正品,市面上有些仿制品可能存在固件兼容性问题。推荐从官方授权渠道或信誉良好的代理商处购买。

1.2 软件环境配置

软件环境的配置相对简单,但有几个关键步骤需要注意:

第一步:安装Wireshark

# Ubuntu/Debian系统
sudo apt update
sudo apt install wireshark

# macOS系统
brew install wireshark

# Windows系统
# 从官网下载安装包:https://www.wireshark.org/download.html

安装完成后,需要配置Wireshark以支持nRF Sniffer插件:

  1. 打开Wireshark,进入“帮助”->“关于Wireshark”->“文件夹”
  2. 找到“个人插件”目录(通常是~/.local/lib/wireshark/plugins%APPDATA%\Wireshark\plugins
  3. 下载nRF Sniffer插件并放置到该目录

第二步:获取并烧录Sniffer固件

Nordic官方提供了预编译的Sniffer固件,可以从GitHub仓库获取:

# 克隆nRF Sniffer for Bluetooth LE仓库
git clone https://github.com/nordicsemiconductor/nRF-Sniffer-for-Bluetooth-LE.git

# 进入固件目录
cd nRF-Sniffer-for-Bluetooth-LE/hex

固件文件按照硬件型号分类:

  • sniffer_nrf52840dongle_nrf52840_*.hex - 用于nRF52840 Dongle
  • sniffer_nrf52dk_nrf52832_*.hex - 用于nRF52 DK开发板
  • sniffer_nrf5340_dk_nrf5340_*.hex - 用于nRF5340 DK开发板

烧录固件有多种方法,这里以nRF52840 Dongle为例:

使用nRF Connect for Desktop烧录:

  1. 安装nRF Connect for Desktop(可从Nordic官网下载)
  2. 打开Programmer工具
  3. 将Dongle插入电脑,点击“Select device”
  4. 选择对应的Dongle,点击“Write”按钮
  5. 选择下载的hex文件,开始烧录

使用命令行工具烧录:

# 安装nrfutil
pip install nrfutil

# 进入DFU模式:按住Dongle上的按钮,插入USB,等待LED开始呼吸闪烁
nrfutil dfu usb-serial -pkg nrf_sniffer.zip -p COMx  # Windows
nrfutil dfu usb-serial -pkg nrf_sniffer.zip -p /dev/ttyACM0  # Linux/macOS

第三步:配置Wireshark抓包

烧录完成后,重新插入Dongle,打开Wireshark:

  1. 在捕获接口列表中,你应该能看到“nRF Sniffer for Bluetooth LE COMx”
  2. 双击该接口开始捕获
  3. 在工具栏中,点击“nRF Sniffer”->“Device”,选择要监控的BLE设备地址

提示:如果看不到nRF Sniffer接口,可能需要手动安装USB驱动。在Windows上,可以使用Zadig工具为Dongle安装WinUSB驱动。

1.3 基础抓包实战

让我们先从一个简单的例子开始。假设我们要监控一个心率监测设备(比如Nordic的HRM示例):

# 模拟BLE设备广播(仅用于理解广播过程)
import time

def simulate_ble_advertisement():
    # BLE设备上电后开始广播
    print("设备开始广播...")
    
    # 广播数据包含:
    # 1. 设备名称
    # 2. 服务UUID(心率服务、电池服务等)
    # 3. 发射功率
    # 4. 连接参数建议
    
    advertisement_data = {
        "device_name": "Nordic_HRM",
        "services": ["180D", "180F", "180A"],  # 心率、电池、设备信息服务
        "tx_power": -20,  # dBm
        "connectable": True
    }
    
    return advertisement_data

# 在Wireshark中,你可以看到类似这样的广播包:
# ADV_IND类型,包含完整的广播数据

在Wireshark中捕获到的广播包会显示详细的信息:

关键字段解析:

  • PDU Type: ADV_IND(可连接的非定向广播)
  • AdvA: 广播设备地址(通常是随机地址)
  • AdvData: 广播数据,包含:
    • Flags: LE通用发现模式
    • 完整的16位服务UUID列表
    • 设备名称
    • 发射功率级别

Wireshark过滤技巧:

# 只显示特定设备的广播包
btle.advertising_address == aa:bb:cc:dd:ee:ff

# 只显示包含特定服务的广播
btle.advertising_data.service_uuid16 == 0x180D

# 排除空数据包
btle.length != 0

# 组合过滤条件
btle.advertising_address == aa:bb:cc:dd:ee:ff && btle.advertising_data.service_uuid16 == 0x180D

2. BLE协议层深度解析:从GAP到GATT

2.1 GAP层:连接建立的基石

GAP(Generic Access Profile)负责BLE设备的发现、连接建立和安全初始化。理解GAP过程对于调试连接问题至关重要。

连接建立过程详解:

当Central设备(如手机)扫描到Peripheral设备(如心率监测器)的广播后,会发起连接请求:

# 连接请求包(CONNECT_IND)的关键参数
connect_ind_packet = {
    "initiator_address": "11:22:33:44:55:66",  # 发起者地址
    "advertiser_address": "aa:bb:cc:dd:ee:ff",  # 广播者地址
    "access_address": 0x8E89BED6,  # 访问地址(随机生成)
    "crc_init": 0x555555,  # CRC初始值
    "connection_parameters": {
        "conn_interval": 30,  # 连接间隔:30 * 1.25ms = 37.5ms
        "conn_latency": 0,    # 从设备延迟
        "supervision_timeout": 600  # 监控超时:600 * 10ms = 6s
    },
    "channel_map": 0x1FFFFFFFFF,  # 信道映射(使用所有37个数据信道)
    "hop_increment": 11  # 跳频增量
}

在Wireshark中分析连接建立过程时,要特别关注以下几个关键点:

  1. 连接参数协商:连接间隔、从设备延迟、监控超时这三个参数直接影响功耗和响应速度
  2. 信道选择算法:BLE使用自适应跳频来避免干扰
  3. 访问地址:每个连接都有唯一的访问地址,用于区分不同连接

常见连接问题排查:

问题现象 可能原因 排查方法
连接频繁断开 监控超时设置过短 检查supervision_timeout是否足够大
数据传输延迟大 连接间隔过长 检查conn_interval是否合理
功耗过高 连接间隔过短 适当增大conn_interval
数据传输不稳定 信道质量差 检查channel_map和实际环境干扰

2.2 链路层控制协议:连接维护的核心

连接建立后,设备会通过链路层控制协议(LLCP)交换能力和更新参数。这是BLE通信中最容易被忽视但至关重要的部分。

能力交换(Feature Exchange):

# LL_FEATURE_REQ/RSP报文结构
feature_exchange = {
    "supported_features": {
        "le_encryption": True,  # 支持加密
        "conn_param_req": True,  # 支持连接参数请求
        "extended_reject": True,  # 支持扩展拒绝指示
        "slave_initiated_feature_exchange": True,  # 从设备发起能力交换
        "le_ping": True,  # 支持Ping
        "le_data_packet_length_extension": True,  # 支持数据包长度扩展
        "ll_privacy": False,  # 是否支持隐私
        "extended_scanner_filter_policies": False,  # 扩展扫描器过滤策略
        "le_2m_phy": True,  # 支持2M PHY
        "le_coded_phy": False,  # 支持Coded PHY
        "le_extended_advertising": False,  # 支持扩展广播
        "le_periodic_advertising": False  # 支持周期广播
    }
}

关键参数更新过程:

数据长度更新(Data Length Update):

# 在Wireshark中过滤LLCP数据包
btl2cap.cid == 0x0004  # LLCP信道

# 查看数据长度更新过程
btle.ll.opcode == 0x22  # LL_LENGTH_REQ
btle.ll.opcode == 0x23  # LL_LENGTH_RSP

数据长度更新是BLE 4.2引入的重要特性,将最大数据包长度从27字节扩展到251字节,显著提升了吞吐量。

连接参数更新(Connection Parameters Update):

# 连接参数更新请求
conn_param_update = {
    "conn_interval_min": 15,  # 最小连接间隔:15 * 1.25ms = 18.75ms
    "conn_interval_max": 30,  # 最大连接间隔:30 * 1.25ms = 37.5ms
    "conn_latency": 0,        # 从设备延迟
    "supervision_timeout": 600,  # 监控超时
    "preferred_periodicity": 0,  # 首选周期
    "reference_conn_event_count": 0,  # 参考连接事件计数
    "offset0": 0,
    "offset1": 0,
    "offset2": 0,
    "offset3": 0,
    "offset4": 0
}

PHY更新(PHY Update): BLE 5.0引入了2M PHY和Coded PHY,PHY更新过程允许设备协商使用更高速率或更长距离的物理层。

注意:PHY更新可能会影响通信距离和功耗,需要根据实际应用场景谨慎选择。

2.3 GATT服务发现与数据交换

GATT(Generic Attribute Profile)是BLE应用层通信的核心,定义了服务(Service)、特征(Characteristic)和描述符(Descriptor)的发现和访问机制。

MTU交换过程: 在开始服务发现之前,设备需要交换最大传输单元(MTU):

# Exchange MTU Request/Response
mtu_exchange = {
    "client_rx_mtu": 247,  # 客户端接收MTU
    "server_rx_mtu": 247   # 服务器接收MTU
}

MTU大小直接影响数据传输效率。较大的MTU可以减少协议开销,但需要设备支持数据长度扩展特性。

服务发现流程:

def discover_services(connection_handle):
    # 1. 发现所有主要服务
    services = []
    start_handle = 0x0001
    end_handle = 0xFFFF
    
    while True:
        # 发送Read By Group Type Request
        request = {
            "opcode": 0x10,  # Read By Group Type Request
            "starting_handle": start_handle,
            "ending_handle": end_handle,
            "attribute_type": 0x2800  # Primary Service
        }
        
        # 接收响应
        response = send_request(request)
        
        if response["opcode"] == 0x11:  # Read By Group Type Response
            for service in response["services"]:
                services.append({
                    "handle": service["handle"],
                    "group_end_handle": service["group_end_handle"],
                    "uuid": service["uuid"]
                })
            
            # 更新起始句柄
            start_handle = services[-1]["group_end_handle"] + 1
            
            if start_handle > end_handle:
                break
        else:
            # 错误响应,结束发现
            break
    
    return services

特征发现与读写操作: 发现服务后,需要进一步发现每个服务包含的特征:

def discover_characteristics(service):
    characteristics = []
    start_handle = service["handle"] + 1
    end_handle = service["group_end_handle"]
    
    while start_handle <= end_handle:
        # 发送Read By Type Request
        request = {
            "opcode": 0x08,  # Read By Type Request
            "starting_handle": start_handle,
            "ending_handle": end_handle,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值