物联网协议逆向(MQTT / CoAP / BLE / Zigbee / NFC 智能卡)

SkillDev tools

物联网协议:MQTT/CoAP/BLE/Zigbee;BLE 链路层(广播解析/配对加密)与 NFC/智能卡(ISO14443/APDU/MIFARE)。 触发词:MQTT、CoAP、BLE、Zigbee、物联网协议、IoT协议、BLE链路、BLE嗅探、广播解析、配对加密、GATT、NFC、智能卡、MIFARE、APDU、ISO14443

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the 物联网协议逆向(MQTT / CoAP / BLE / Zigbee / NFC 智能卡) skill

What this skill tells your AI

The instructions your AI receives, as published by dslsdzc/rev-skills in .claude/skills/re-iot-proto/SKILL.md and read by ahel’s review.

何时使用 / 何时不用

  • 用:拿到 IoT 设备流量(pcap / 实时抓包)需要解析 MQTT / CoAP 语义
  • 用:BLE 设备(adv / GATT)交互分析
  • 用:Zigbee(802.15.4)网络抓包与 ZCL 命令分析
  • 用:需要理解"设备上报 / 下发控制"语义并联动固件
  • 不用:通用自定义协议(走 [[re-proto-rev]])
  • 不用:普通网络流量捕获(走 [[re-netcap]])
  • 不用:加密流量无密钥——先 [[re-crypto-id]] / [[re-crypto-keys]]

工具准备

物理设备抓包注意授权边界(见步骤 5),动态场景默认沙箱 / 隔离网络([[re-analyze/platform-tips]] 最高原则)。所有工具先验证再使用。

wireshark / tshark —— 解析主力(MQTT/CoAP/BLE/Zigbee dissector 内置)

  • Linux: apt install wireshark tshark / dnf install wireshark-cli wireshark / pacman -S wireshark-cli wireshark-qt(Arch 已拆分为 wireshark-cli + wireshark-qt;Debian 安装时选"允许非 root 抓包",或 sudo dpkg-reconfigure wireshark-common 后把用户加入 wireshark 组)
  • macOS: brew install --cask wireshark(含 tshark CLI;或 brew install wireshark 仅 CLI)
  • Windows: choco install wireshark;WSL 内用 Linux 版
  • 验证: tshark --versiontshark -G fields | grep -iE 'mqtt|coap|btatt|zbee' 列出字段名(各版本字段名有微调,以该输出为准)

scapy —— 可选解析 / 构造

  • 全平台: pip install scapy(Python 3)
  • 验证: python3 -c "import scapy; print(scapy.__version__)"

MQTT —— mosquitto 客户端(主动订阅/发布验证)

  • Debian/Ubuntu: apt install mosquitto-clients(mosquitto_pub / mosquitto_sub)
  • Fedora: dnf install mosquitto;Arch: pacman -S mosquitto;macOS: brew install mosquitto;Windows: choco install mosquitto
  • 验证: mosquitto_pub -hmosquitto_sub -h
  • GUI 替代: MQTT Explorer(桌面跨平台)

CoAP —— coap-client / aiocoap

  • Debian/Ubuntu: apt install libcoap3-bin(提供 coap-client)
  • Fedora: dnf install libcoap libcoap-utils(coap-client 位于 libcoap-utils 子包);Arch: pacman -S libcoap(extra);macOS: brew install libcoap
  • 发行版包若不含示例程序 → pip install aiocoap(命令 aiocoap-client,Python 3)
  • 验证: coap-client -h(或 aiocoap-client -h

BLE —— bluez + ubertooth

  • bluez(btmon / hcitool): Debian/Ubuntu apt install bluez;Fedora dnf install bluez;Arch pacman -S bluez bluez-utils;验证 btmon --help
  • ubertooth(2.4GHz 嗅探硬件): Debian/Ubuntu apt install ubertooth(固件另装 ubertooth-firmware);Fedora dnf install ubertooth(Fedora 43/44 官方仓库有);Arch 官方仓库无 → AUR;macOS brew install ubertooth;验证 ubertooth-btle -s
  • Android btsnoop(无需安装): 开发者选项 → 勾选"启用 Bluetooth HCI snoop 日志" → 复现交互 → adb bugreport 或拉取 /sdcard/btsnoop_hci.log(btsnoop 格式,Wireshark 直接打开)
  • nRF Sniffer for BLE(Nordic,可选): 需 nRF 系列 dongle + Wireshark extcap(Windows/macOS 为主)

Zigbee —— Wireshark + sniffer 硬件 + KillerBee

  • Wireshark zbee dissector 内置(zbee_nwk / zbee_aps / zbee_zcl);解密在 Preferences → Protocols → ZigBee → Security(勾 Decryption、填 Network Key / Link Key)
  • sniffer 硬件(无发行版包,硬件方案): TI CC2531 USB 棒(刷 Sniffer 固件)或 Silicon Labs EFR32MG(Simplicity Studio 刷 sniffer + Wireshark extcap)
  • KillerBee(Python,ZCL 抓取 / 构造 / 重放): Debian/Fedora/Arch 官方仓库均无该包 → pip3 install killerbee(PyPI;依赖 libusb/libpcap——Debian/Ubuntu apt install libusb-1.0-0-dev libpcap-dev、Fedora dnf install libusbx-devel libpcap-devel、Arch pacman -S libusb libpcap);固件烧写 sudo ./kb_install_firmware;验证 kb --version
  • ZBOSS 协议栈(DSR 公司 Zigbee 栈)文档作 NWK/APS/ZCL 结构参考
  • 密钥提取联动: [[re-firmware]](固件 flash 读密钥,配合 zbgoodfind)/ [[re-crypto-keys]]

操作步骤

按顺序执行,每步产物(pcap / 密钥 / 解析脚本 + sha256)存档。

  1. 协议识别
    tshark -r cap.pcap -q -z io,phs                                   # 协议分层统计
    tshark -r cap.pcap -T fields -e tcp.dstport -e udp.dstport | sort | uniq -c | sort -rn
    
    • 端口速查: MQTT 1883(明文)/ 8883(TLS);CoAP 5683(UDP)/ 5684(DTLS);BLE: 广播与 GATT(bthci_evt / bthci_acl / btatt 层,无端口);Zigbee: 802.15.4 帧(无端口,2.4GHz 信道 11-26)
    • 非标端口 → Wireshark Decode As / tshark -d tcp.port==9999,mqtt 强制指定
    • 特征确认: MQTT 首字节为控制类型(CONNECT 0x10 / PUBLISH 0x30 ...);CoAP 头 Ver 字段 2 位(值 01);BLE HCI 事件包 0x3e;Zigbee 帧首 2 字节 802.15.4 帧控制字段
  2. MQTT/CoAP 解析(topic / payload)
    tshark -r cap.pcap -Y mqtt -T fields -e mqtt.topic -e mqtt.msg
    tshark -r cap.pcap -Y 'mqtt.topic contains "ota"' -T fields -e mqtt.msg    # 按主题过滤
    tshark -r cap.pcap -Y coap -T fields -e coap.code -e coap.uri_path -e coap.opt.content_format
    
    • topic 即控制语义: device/<id>/sensorota/updatecmd/relay 等——先按 topic 分桶(-e mqtt.topic | sort | uniq -c
    • payload 常见 JSON / protobuf / 自定义二进制 → 字段含义对照设备 App 或固件(步骤 5)
    • 主动交互验证(授权内): mosquitto_sub -h <broker> -t '#' -v(全量订阅)、mosquitto_pub -h <broker> -t <topic> -m '{"relay":1}'coap-client -m get coap://<ip>/sensorcoap-client -m put -e '{"on":1}' coap://<ip>/relay
    • 加密(8883 / 5684): TLS 用 SSLKEYLOGFILE 解密;RSA 私钥只适用于旧式 static-RSA 密钥交换(TLS 1.3 与 ECDHE 会话解不开);DTLS PSK 在 Wireshark dtls 偏好填十六进制预共享密钥(密钥来源见步骤 4 与 [[re-crypto-keys]])
  3. BLE 抓包(adv / GATT)
    • Android btsnoop: 开发者选项开启 snoop 日志 → 复现 App 与设备交互 → 拉取 btsnoop_hci.log 用 Wireshark 打开(自动解 HCI)
    • Linux: btmon -w out.btsnoop(配合目标连接过程;写出的 btsnoop 格式 Wireshark 直接打开)
    • ubertooth(无主机侧蓝牙时可嗅 2.4GHz): ubertooth-btle -f -c 0(follow 模式观察广播 / 连接包)、ubertooth-btle -s(扫描)——实时显示不落盘,配合屏幕分析;要落盘进 Wireshark 用 btmon / Android btsnoop / nRF Sniffer(extcap)
    • GATT 解析:
      tshark -r ble.pcap -Y btatt -T fields -e btatt.opcode -e btatt.uuid -e btatt.value
      
    • 关注: 广播包(设备名 / 厂商数据 / 服务 UUID)与 GATT 读写特征(传感器值、控制指令、固件版本)
  4. Zigbee(802.15.4)
    • 硬件 sniffer 捕获(CC2531 / EFR32,选对信道)→ Wireshark zbee 解析
    • 解密: Preferences → Protocols → ZigBee → Security: 勾 Decryption、填 Network Key(16 字节 hex)与 Link Key(Zigbee 3.0 常见默认 TC link key 为 ZigBeeAlliance09
    • 密钥获取路径: ① 抓网络组网过程(Trust Center 向新节点下发 network key)② 默认 TC link key / install code ③ 固件 flash 提取([[re-firmware]] / [[re-hardware-io]],配合 zbgoodfind 在固件里找密钥)④ 物理访问协调器读配置
    • 层结构: NWK(寻址/加密)→ APS(端点/簇)→ ZCL(命令: 开关 / 读属性 / OTA)——tshark -r zigbee.pcap -Y zbee_zcl -T fields -e zbee_zcl.cmd 看命令(字段名以 tshark -G fields | grep -i zbee 为准)
    • KillerBee 交互(授权内): zbdump(抓包)、zbstumbler(扫网)、zbreplay(重放 ZCL 命令)
  5. 设备固件联动(走 [[re-firmware]])
    • 协议语义不明 / 自定义 payload → 固件提取(binwalk 解包)→ rootfs 里找协议实现(字符串 / so)、密钥、topic 硬编码 → [[re-fw-emulate]] 仿真设备复现协议行为
    • 协议常量与固件字符串交叉验证(端口、magic、topic 前缀)
    • OTA 通道也是协议面: MQTT topic ota/update 下发固件 → 截获的固件镜像可再走 [[re-firmware]]

BLE 链路层

应用层之外补链路层视角:空口嗅探、广播/连接帧结构、配对加密协商与密钥定位。抓包工具底座见上文「BLE —— bluez + ubertooth」,本节侧重链路语义与深挖点。

嗅探硬件与软件(泛化选购指引)

  • 主机侧(btmon / Android btsnoop)只能看到本机参与的过程;设备与第三方设备之间的交互需空口嗅探
  • nRF 系 dongle + Sniffer 固件 + Wireshark extcap(桌面端为主): 选购关注芯片覆盖的蓝牙核心版本(4.2 / 5.x 是否支持 LE Secure Connections 跟踪)、固件是否支持连接事件跟踪(跟随跳频)、天线形式(板载/外置,影响接收距离)
  • ubertooth 类 2.4GHz 嗅探器: 适合广播与无加密连接的链路层数据;不参与连接,加密连接内容看不到
  • 共性局限: 空口嗅探对加密连接只能看时序与包长,内容解密需 LTK(见下)

广播包解析

  • PDU 类型区分连接意图: ADV_IND(可连接非定向,最常见)、ADV_SCAN_IND(可扫描)、ADV_NONCONN_IND(纯广播)、ADV_DIRECT_IND(定向)
  • 帧结构: 2 字节头(PDU 类型 + 长度)+ Payload(AdvA + AdvData);AdvData 为 AD structure 链(Length + AD Type + Data): 0x01 Flags、0x03/0x07 服务 UUID、0x09 完整本地名、0x0A Tx Power、0xFF 厂商数据
  • 解析: tshark -r ble.pcap -Y btle -T fields -e btle.advertising_address -e btle.advertising_header.pdu_type -e btle.advertising_data(字段名以 tshark -G fields | grep -i btle 为准);0xFF 厂商数据段常含私有协议与设备标识,值得逐字节对照固件
  • 广播只承载低频状态通告(名字/状态/服务发现),业务数据一般在连接后 GATT 通道

连接事件时序与信道 37/38/39

  • 主广播信道固定 37/38/39(2402/2426/2480 MHz),广播事件在三信道轮转;扫描请求/响应与 CONNECT_IND 也在这三个信道
  • CONNECT_IND 携带访问地址、跳频增量与连接参数 → 据此可推算后续数据信道序列(0-36)与事件节奏
  • 连接参数: connInterval(1.25ms 步进)、slaveLatency、supervisionTimeout,在 HCI 层 LE Connection Complete 事件可见;连接事件以锚点(anchor point)起算,按 connInterval 周期出现
  • 验证: 抓包中连接数据包间隔应为 connInterval 的整数倍;间隔混乱或单侧缺失 → 跳频跟踪脱同步(见坑 3)

配对 / 加密协商

  • 流程: Pairing Request/Response(SMP)→ 临时密钥派生 → LTK 生成 →(绑定)双方存储 LTK
  • LE Legacy: 基于 PIN/临时值派生 STK;LE Secure Connections: P-256 ECDH,AuthReq 的 MITM 位决定是否防中间人(Just Works 无用户校验,Passkey / Numeric Comparison 有)
  • 定位点: Wireshark 中 SMP 交换看 AuthReq(SC / MITM / Bonding 位,字段以 tshark -G fields | grep -i smp 为准)——先确认模式再决定是解密还是只看时序
  • 绑定(bonding)后重连不重新配对,LTK 交换只出现在首次配对
  • 密钥存储: 主机侧(系统蓝牙配置 / 键值对存储)与设备侧(flash / 外部 EEPROM)→ [[re-firmware]] / [[re-crypto-keys]] 提取;拿到 LTK 填 Wireshark BLE 偏好可解密连接数据

GATT 服务与特征枚举

  • 被动: btmon / btsnoop 抓服务发现(Discover All Primary Services / 特征发现),btatt 层 UUID 与句柄映射直接可见
  • 主动(连接后): gatttool 类工具(bluez)primary / characteristics 列出 handle ↔ UUID ↔ 属性
  • 读写/通知点: 特征句柄 + CCCD(0x2902)开启通知/指示后,值流在 btatt.value;tshark -r ble.pcap -Y btatt -T fields -e btatt.handle -e btatt.value

坑与陷阱

  • 广播 vs 连接数据混淆:现象——在广播包厂商数据段看到疑似业务数据就当上报语义解析,结果与 App 行为对不上;原因——广播只承载低频通告,业务流在连接后的 GATT 通道且可能加密;对策——先按帧类型分流: btle advertising 包解析 AdvData,连接数据看 btatt 层;判断目标设备是否已进入连接态再决定抓哪段
  • 配对模式误判:现象——按"抓到配对过程即可解密"推进,实际要么连接全密文要么明文无校验;原因——AuthReq 位决定模式: SC=0 且 MITM=0 为 LE Legacy Just Works——无用户校验、不防窃听侧冒充;SC=1 为 LE Secure Connections(ECDH);对策——解析 SMP Pairing Request 的 AuthReq 先确认模式,再选解密(需 LTK)或只看时序
  • 抓包丢连接事件:现象——广播与连接建立都在,连接事件断断续续或只有单侧包;原因——数据信道跳频未被跟踪(错过锚点即脱同步)、只固定监听单信道、空口干扰丢包;对策——优先主机侧 btmon / btsnoop(全信道可靠);空口嗅探用带连接跟踪能力的固件,并按 CONNECT_IND 的访问地址 + 跳频增量验证跟踪
  • LTK 不在抓包里:现象——SMP 交换后无 LTK 相关包,解密无密钥;原因——绑定后重连直接用存储密钥,不重新交换;对策——清配对/重置后重抓首次配对,或从设备 flash / App 存储提取([[re-firmware]] / [[re-crypto-keys]])

NFC / 智能卡

接触式 / 无接触智能卡:ISO14443 链路、APDU 交互与常见卡族弱点。硬件用 proxmark3 类通用读写器(泛化选购),抓取/分析前确认授权边界。

ISO14443 帧结构与防冲突流程

  • ISO14443A 流程: REQA(0x26 短帧)→ ATQA → 防冲突(UID 按级联 CL1/CL2/CL3 逐位协商)→ SELECT → SAK(卡类型标识)
  • 帧结构: SOF + 数据字节(每字节带奇偶校验)+ CRC_A(2 字节)+ EOF;短帧 7 位(REQA/WUPA)
  • SAK 判型: 0x08/0x88 类 → MIFARE Classic 族(Crypto-1,扇区/块结构);0x20/0x40 类 → DESFire 族(文件系统 + AES/3DES)——先判型再选路径(见坑 1)
  • 读写器流程: hf 14a reader 类命令(proxmark3 类通用)一次输出 ATQA / UID / SAK,据此进入对应卡族工具

APDU 交互

  • ISO7816-4 APDU: CLA + INS + P1 + P2,其后 Lc/数据/Le 按 case 组合出现(Case1 三者皆无;Case2 无 Lc/数据可有 Le;Case3 有 Lc+数据无 Le;Case4 全有)——解析边界前先判定 case;响应 SW1/SW2(0x9000 成功)
  • 常见指令: 0xA4 SELECT(选应用)、0xB0 READ BINARY、0xB2 READ RECORD、0x20 VERIFY(口令验证)、0xD0 WRITE BINARY、0xD6 UPDATE BINARY——但各卡/应用命令集有差异(见坑 2)
  • 接触式走 ISO7816 T=0/T=1;无接触卡常把 APDU 透传(如 DESFire ISO 模式),抓包位置不同
  • 定位技巧: 抓已知合法交互(读写器日志 / 手机 NFC 日志)对照指令序列,比对着文档猜快

MIFARE Classic 与 Crypto-1 弱点(泛化)

  • Crypto-1 为 48 位流密码,认证时读写器发 challenge、卡返回加密响应;PRNG 与认证协议有已知弱点,可基于非加密认证响应样本做密钥恢复(重放 / 已知明文思路)
  • 前提: 卡响应任意读写器的认证请求(未被配置拒绝未知密钥);前提不满足则该思路不适用,转密钥提取([[re-crypto-keys]] / [[re-firmware]])或固件分析
  • 边界: 仅针对 Crypto-1 类卡;AES 类卡(DESFire 族)结构不同,不适用

proxmark3 类设备流程(泛化选购)

  • 选购关注: 13.56MHz 高频支持(必备)、固件是否活跃更新、是否支持现场刷写、天线性能与外壳形式
  • 流程: 上电自检 → hf 14a reader 判型 → 按卡族选攻击/读写流程 → 验证结果
  • 授权边界: 只读与写卡/复制均需授权,实验室环境确认卡归属与目的([[re-analyze/platform-tips]] 最高原则)

坑与陷阱

  • 卡类型判断错误(MIFARE vs DESFire 结构不同):现象——按 Classic 扇区/块结构解析一张卡,地址与数据全对不上;原因——Classic(Crypto-1、扇区块结构、SAK 0x08/0x88 类)与 DESFire(文件系统、AES/3DES、SAK 0x20/0x40 类)内部结构完全不同;对策——先看 SAK(结合 ATQA)判卡族再选解析/攻击路径,不要拿一个结构套所有卡
  • APDU 命令集差异:现象——同一指令在 A 卡成功、B 卡返回 0x6A82(文件未找到)/ 0x6D00(指令不支持)类错误;原因——不同卡/应用对 CLA 前缀、INS、P1/P2 约定不同(专有 CLA、扩展指令、参数含义差异);对策——先 SELECT 目标应用,用已知合法交互抓包对照指令序列,按 SW 状态码逐条校准
  • Crypto-1 攻击前提:现象——密钥恢复流程跑不起来或结果错误;原因——思路需要先拿到卡侧非加密认证响应样本,卡拒绝未知读写器认证、或环境无法插中间人时无从入手;对策——先验证卡是否响应任意读写器认证请求,前提成立再走攻击流程,否则转密钥提取 / 固件路径([[re-crypto-keys]] / [[re-firmware]])
  • UID 与数据块混淆:现象——写卡/复制后目标卡行为异常或读写失败;原因——UID 与厂商块(块 0)存在锁定/校验,部分卡族 UID 不可改,改后访问控制失效;对策——写前先读厂商块与扇区尾块(access bits),确认可写性与授权边界

跨域联合

  • [[re-protocol]]: 本技能是其 IoT 分支(工作流第 5 步之后的选择树入口)
  • [[re-netcap]]: 捕获原料(抓包点 / 隔离)
  • [[re-firmware]]: 固件联动(协议实现 / 密钥 / OTA 镜像,配合 [[re-fw-extract]] / [[re-fw-emulate]])
  • [[re-crypto-id]] / [[re-crypto-keys]] / [[re-crypto-decrypt]]: 加密流量链路(TLS / DTLS / PSK 密钥提取与解密)
  • [[re-proto-rev]]: 私有 IoT 协议状态机重建
  • [[re-hardware-io]]: 串口 / flash 芯片读密钥
  • [[re-sandbox]]: 设备测试网络隔离与授权边界([[re-analyze/platform-tips]] 最高原则)
  • 本技能被 [[re-analyze]] 的 triage「协议分析」路径引用(re-protocol → re-iot-proto)
  • 射频信号级逆向(采集/解调/帧恢复)→ [[re-sdr]]
  • [[re-javacard]]: NFC/智能卡链路之上的 applet 逻辑(CAP 文件解析、process(APDU) 分派还原)

常见坑与陷阱

  • MQTT 明文 topic 泄露控制语义:现象——pcap 里 topic 直接写明 device/x/ota/updatecmd/relay,业务意图一目了然但 payload 加密或二进制;原因——设备常只加密 payload、topic 明文(或 broker 无 TLS);对策——topic 是语义金矿:先 -e mqtt.topic | sort | uniq -c 分桶,按 topic 定位关键流再解 payload;payload 二进制用 JSON/protobuf 假设对照固件(步骤 5)
  • DTLS/PSK 加密需密钥:现象——5684 / 8883 流量熵高全是密文,dissector 只出乱码;原因——DTLS/TLS 加密层(PSK/RSA);对策——PSK 从设备固件 / App 侧提取([[re-crypto-keys]] → [[re-firmware]]),Wireshark dtls 偏好填十六进制 PSK;TLS 用 SSLKEYLOGFILE(RSA 私钥仅旧式 static-RSA 会话可用,现代 ECDHE/TLS 1.3 解不开);拿不到密钥则该通道只能看时序,标注局限并转向语义推测
  • BLE 白名单/配对绑定:现象——连接请求之后没有后续数据,或设备根本不广播;原因——白名单过滤未知主机、已配对设备按绑定信息直接连接(跳过广播 / 配对过程);对策——清除设备配对 / 出厂重置后重抓首次连接配对过程;广播阶段数据(adv 包,含设备信息与服务 UUID)先抓全
  • Zigbee 网络密钥获取困难:现象——zbee 帧可解析但 APS / ZCL 全密文(payload 乱码);原因——network key 未在手,链路/网络层加密;对策——按步骤 4 密钥路径逐项试: 组网期抓包 → 默认 TC link key → 固件提取(zbgoodfind 扫固件找 key);TC link key 与 network key 两层密钥都要拿
  • 抓包硬件/信道错配:现象——BLE 只抓到零星广播、Zigbee 一个包都没有;原因——BLE 40 信道跳频(普通适配器只能看到广播或部分连接包)、Zigbee 信道选错(11-26 选错即静默);对策——BLE 用 btmon / btsnoop(主机侧全信道)或 ubertooth 配合 follow;Zigbee 用 sniffer 信道扫描(zbstumbler)确认工作信道再抓

Signals

GitHub stars
57
Forks
8
Last commit
Sep 2026

ahel review

  • K1binfo
    installs-packages

Automated review, not a security audit. Ruleset v1+k2.

Advanced
Catalog kind
skill
Gateway key
re-iot-proto
Source
github.com/dslsdzc/rev-skills