逆向工程实战手册 第 30 章

第 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 安全提醒

□ 物理改造设备 = 可能损坏(电压反接/短路)
□ 只在你拥有/有授权的设备上操作
□ 先拍照记录原始状态(可恢复性)
□ 侧信道/故障注入需要重复实验,做好数据记录

动手练习

  1. 找一个带 UART 的开发板(Arduino/ESP32/路由器),练习找 TX/RX/GND 并连上 shell。
  2. 用 flashrom 读一个开发板的 SPI Flash,对比板上固件和软件提取的固件。
  3. 用 OpenOCD 连接一个 STM32 开发板,练习 halt/dump_image/load_image。
  4. 阅读一个 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 子技能)