第 30 章 硬件破解与嵌入式调试(IoT 硬件)
软件逆向的尽头是硬件:串口、JTAG、SPI Flash、芯片引脚。当固件加密、bootloader 锁定、软件分析走到死胡同时,物理接口就是突破口。本章讲硬件攻击的知识架构。
📍 知识点地图 | 主题:硬件破解 | 前置:第15章 | 后续:— | 核心概念:UART、JTAG、SPI、故障注入、侧信道
30.1 硬件逆向的定位(和软件逆向的关系)
软件视角(第 15 章): 固件提取 → 解包 → 静态分析 → 仿真
硬件视角(本章): 物理接口 → 拿 shell/数据 → 辅助软件分析
核心价值:
1. 拿到软件分析拿不到的东西(加密固件/密钥/bootloader 限制)
2. 绕过软件限制(认证/区域锁/固件签名校验)
3. 理解设备(引脚定义/外设/启动流程)
30.2 硬件接口攻击面总览(按难度排序)
| 接口 | 获取什么 | 难度 | 设备前提 |
|---|---|---|---|
| UART 串口 | shell / 日志 / bootloader 菜单 | ★ | 找到 TX/RX/GND 引脚 |
| JTAG | 完整调试(读写内存/寄存器) | ★★ | 找到 TMS/TCK/TDI/TDO |
| SPI Flash | 固件镜像(绕过固件加密逻辑) | ★★ | 找到 SO/SI/CS/CLK |
| SWD | ARM 调试接口 | ★★ | 找到 SWDIO/SWCLK |
| 电源侧信道 | 密钥(功耗分析 SPA/DPA) | ★★★★★ | 专业设备 |
| 故障注入 | 跳过校验(glitch) | ★★★★ | 电压/时钟毛刺 |
30.3 UART(最常遇到的第一站)
原理
UART = 通用异步收发,3 线: TX(设备发送)、RX(设备接收)、GND(共地)
参数: 波特率(通常 9600/57600/115200)
特征: 嵌入式设备 90% 都有调试串口(出厂时用)
找 UART 引脚
方法 1: 看 PCB 丝印(TX/RX/GND 或 T/R/G 标记,或 4 针排针)
方法 2: 万用表测电压:
- 3.3V = 电源
- 0V = GND
- 空闲 3.3V、传输时跳动 = TX
- 空闲 3.3V、无活动 = RX
方法 3: 示波器看启动时的串口活动
连接与爆破
# USB-TTL 转换器(CH340/CP2102)接 GND-TX-RX
# Linux: minicom / screen
screen /dev/ttyUSB0 115200
# 不知道波特率 → 自动检测
baudrate (GitHub 工具) 或 picocom + 遍历常见波特率
拿到 shell 后的标准操作
□ bootloader 菜单(U-Boot: 中断启动进命令行)
□ 改启动参数(init=/bin/sh 跳过系统启动)
□ dump 环境变量(U-Boot env: 常含密码/密钥)
□ 从 shell 拉固件/配置文件
□ 检查写保护(flash 分区能否读写)
30.4 SPI Flash(固件提取的核心)
原理
SPI = 串行外设接口,4 线: CS(片选)、CLK(时钟)、SO(数据出)、SI(数据入)
板上 Flash 芯片(W25Q64 等)存固件
只要能从物理层面读芯片 = 拿到完整固件镜像(无视软件加密!)
两种读取方式
方式 A: 板载读取(芯片在板上,用 flashrom 对芯片编号)
方式 B: 拆芯片用编程器(CH341A 等)离线读
# flashrom 读 SPI Flash
flashrom -p ch341a_spi -r firmware.bin
硬件加密固件怎么办
固件加密的常见形态:
- 启动代码(bootrom)解密固件 → 运行时内存中有明文
- 直接读 flash 拿到的是密文
对策:
- 读"运行中的内存"(JTAG dump 或 boot 过程抓明文)
- 逆 bootrom 的解密逻辑(从芯片商泄露/逆向获取 key)
- 修改 boot 流程让设备自己解密输出
30.5 JTAG / SWD(硬件调试接口)
原理
JTAG: TMS(模式) TCK(时钟) TDI(数据入) TDO(数据出) — 4 线调试协议
SWD: SWDIO + SWCLK 两线(ARM 简化)
能做什么: 读写内存、设断点、读寄存器、dump Flash → 完整调试权限
连接与工具
# 硬件: OpenOCD 支持的调试器(FT2232H / ST-Link / J-Link)
openocd -f interface/ft2232h.cfg -f target/stm32f4x.cfg
telnet localhost 4444
# OpenOCD 命令
halt
dump_image flash_dump.bin 0x08000000 0x100000
load_image payload.bin 0x20000000
reg pc
JTAG 锁(读保护 RDP)与绕过
RDP Level 1: 读保护 → 普通读取被禁
绕过思路:
- 降级攻击(读保护级别降级 bug)
- 故障注入(glitch 绕过检查)
- 从 RAM 恢复(芯片在运行时 RAM 里有明文)
- 换思路: 不读 flash,分析运行时行为
30.6 故障注入(Glitching)——进阶
原理: 在精确时间点制造电压/时钟毛刺 → 跳过安全检查(如签名校验)
形态:
- 电压毛刺(VCC 快速跌落)
- 时钟毛刺(CLK 快慢切换)
- 电磁注入(EMFI,非接触)
用途: 绕过 bootloader 校验、绕过 pin 码、降级安全级别
工具: ChipWhisperer(入门标准套件)、故障注入编程器
30.7 侧信道分析(SPA/DPA)——专业级
原理: 芯片执行加密时的功耗/电磁变化与密钥相关
SPA: 单条功耗曲线 → 看操作序列(简单攻击)
DPA: 大量曲线统计分析 → 恢复密钥字节(差分功耗分析)
工具: ChipWhisperer、Scope 采集 + 分析脚本
实战: AES 密钥提取(每条迹线已知明文/密文 → 关联功耗)
30.8 硬件逆向方法论(架构)
Phase 1: 侦察(不动硬件)
□ 拆机拍照: PCB 布局、芯片丝印、排针、测试点
□ 查芯片型号: datasheet → 引脚功能、调试接口、Flash 类型
□ 查已知漏洞: 该芯片/固件/协议的公开攻击(CVE/论文)
Phase 2: 找接口(最省力路径优先)
1. UART(丝印/电压法)→ 可能要 shell
2. SPI Flash(读固件)
3. JTAG/SWD(完整调试)
按"一个接口解决战斗"的目标选型
Phase 3: 利用
□ 串口 shell → 系统命令/文件/配置
□ 固件镜像 → 走第 15 章软件分析
□ JTAG dump → 内存/Flash 数据
□ 交互限制 → 故障注入/侧信道(进阶)
Phase 4: 闭环
□ 固件分析发现的逻辑 + 硬件获取的数据互证
□ 密钥提取 → 解密通信/固件
□ 沉淀: 引脚定义/接口位置 → 下次同类设备秒开
30.9 工具链清单
| 类别 | 工具 |
|---|---|
| USB-TTL 转换 | CH340 / CP2102 / FT232 |
| SPI 读取 | flashrom + CH341A / 编程器 |
| 调试器 | OpenOCD + FT2232H / ST-Link / J-Link |
| 故障注入 | ChipWhisperer / GlitchKit |
| 示波器/逻辑分析 | Saleae / DSLogic / 自制 |
| 万用表 | 电压测量找引脚 |
| 拆焊 | 热风枪 / 烙铁(读取 Flash 用) |
30.10 安全提醒
□ 物理改造设备 = 可能损坏(电压反接/短路)
□ 只在你拥有/有授权的设备上操作
□ 先拍照记录原始状态(可恢复性)
□ 侧信道/故障注入需要重复实验,做好数据记录
动手练习
- 找一个带 UART 的开发板(Arduino/ESP32/路由器),练习找 TX/RX/GND 并连上 shell。
- 用 flashrom 读一个开发板的 SPI Flash,对比板上固件和软件提取的固件。
- 用 OpenOCD 连接一个 STM32 开发板,练习 halt/dump_image/load_image。
- 阅读一个 IoT 硬件破解 writeup(如 routersploit/exploit-db 硬件案例),画它的 Phase 1-4 流程图。
深入阅读
- 仓库:
skills/reverse-engineering/platforms-hardware.md(HD44780、RISC-V、ARM64、MIPS 硬件逆向) - 仓库:
skills/reverse-engineering/platforms.md(嵌入式/IoT 固件、UART/JTAG/SPI、RTOS) - 仓库:
skills/firmware-pentest/references/extraction-methodology.md(固件提取方法论) - 实战案例:
skills/field-journal/seed-015_iot-firmware-uart.md(IoT 固件 UART 实战) - 仓库:
CTF-Sandbox-Orchestrator/competition-firmware-layout/(固件布局 CTF 子技能)