第一章:信息收集与固件提取

大家好,我是你们的嵌入式安全讲师。今天咱们聊聊固件安全里最基础、也最关键的一步——怎么把固件从设备里“掏”出来。

你想想看,没有固件,后面所有的分析都是空谈。我这些年做过的项目,至少有三分之一的时间都花在了信息收集和提取上。说白了,这一步做扎实了,后面才能顺风顺水。

1.1 硬件接口:UART、JTAG、SWD

拿到一个设备,我第一件事就是找它的调试接口。这就像医生看病先找脉搏一样。

UART(通用异步收发器)

UART 是最常见的调试接口。很多嵌入式设备都会留一组 TX、RX、GND 的焊盘或排针。

怎么找?

  • 看 PCB 上有没有 3 针或 4 针的排针,旁边通常有丝印标注(比如 TX、RX、GND)。
  • 用万用表量电压:TX 引脚在空闲时通常是高电平(3.3V 或 1.8V)。
  • 逻辑分析仪抓波形:接上 TX 和 GND,上电后看有没有串口数据。
我的小技巧: 我习惯用 Saleae 逻辑分析仪,设置成异步串行模式,波特率从 9600 开始自动扫描。大部分设备用 115200 或 57600。

连接方法:

设备 TX → USB转串口 RX
设备 RX → USB转串口 TX
设备 GND → USB转串口 GND

连接好后,用 PuTTY 或 screen 打开串口,波特率设对,就能看到启动日志了。有时候还能直接拿到一个 shell。

注意: 有些设备会禁用 UART 控制台,或者只输出日志不接收输入。这时候别灰心,我们还有别的路子。

JTAG 和 SWD

JTAG 是 5 线接口(TMS、TCK、TDI、TDO、TRST),SWD 是 2 线接口(SWDIO、SWCLK)。它们主要用于调试和编程。

怎么识别?

  • JTAG 通常有 10 针或 20 针的排针,有标准定义(比如 ARM 的 20 针 JTAG)。
  • SWD 的 SWDIO 和 SWCLK 引脚,旁边通常有 GND 和 VCC。
  • 用 JTAGulator 或 J-Link 的自动识别功能,可以快速找到引脚定义。

我记得有一次,一个路由器死活找不到 UART 口,后来用 J-Link 的 SWD 模式直接连上了主控芯片,把整个 Flash 都读了出来。嗯,有时候换个思路反而更快。

1.2 读取 SPI Flash

很多设备的固件存在 SPI Flash 里。常见的型号有 Winbond、Macronix、GigaDevice 等。

工具准备:

  • 硬件:CH341A 编程器、树莓派、或者专门的 SPI Flash 编程器。
  • 软件:flashrom、ch341prog、或者厂家提供的工具。

用 flashrom 读取:

# 先识别芯片
flashrom -p ch341a_spi -V

# 读取整个 Flash
flashrom -p ch341a_spi -r firmware.bin

# 如果芯片是 16MB,大概需要 2-3 分钟
重要: 读取前一定要确认芯片型号和电压。3.3V 的芯片用 5V 去读,会烧掉的。我刚开始做的时候烧过一块,心疼了好几天。

用树莓派读取:

树莓派的 GPIO 可以模拟 SPI 接口。接线方式如下:

树莓派 Pin 19 (MOSI) → Flash Pin 5 (DI)
树莓派 Pin 21 (MISO) → Flash Pin 2 (DO)
树莓派 Pin 23 (SCLK) → Flash Pin 6 (CLK)
树莓派 Pin 24 (CE0)  → Flash Pin 1 (CS)
树莓派 Pin 25 (GND)  → Flash Pin 4 (GND)
树莓派 Pin 1 (3.3V)  → Flash Pin 8 (VCC)

然后用 flashrom 的 linux_spi 驱动:

flashrom -p linux_spi:dev=/dev/spidev0.0,spispeed=1000 -r firmware.bin

1.3 固件文件头解析

拿到固件文件后,第一件事就是看看它是什么格式。我常用的工具是 Binwalk 和 Firmware Mod Kit。

Binwalk 的使用

Binwalk 可以自动识别固件里的文件系统、压缩包、Bootloader 等。

# 扫描固件
binwalk firmware.bin

# 提取所有文件
binwalk -e firmware.bin

# 只提取特定类型
binwalk -D 'png:image:raw' firmware.bin

输出结果会显示每个段的偏移地址、大小和类型。比如:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             U-Boot version string, "U-Boot 2016.01"
262144        0x40000         uImage header, header size: 64 bytes
524288        0x80000         Squashfs filesystem, little endian, version 4.0

看到 Squashfs 了吗?这就是文件系统。我们可以用 Firmware Mod Kit 来解包和重新打包。

Firmware Mod Kit 的使用

这个工具集成了很多脚本,可以自动处理常见的固件格式。

# 解包固件
./extract-firmware.sh firmware.bin

# 修改文件系统
# 进入 fmk/rootfs/ 目录,修改你需要的文件

# 重新打包
./build-firmware.sh firmware-new.bin
避坑指南: 我曾经遇到过一个固件,Binwalk 识别出了 Squashfs,但 Firmware Mod Kit 解包失败。后来发现是文件系统有校验和,需要先去掉校验头。用 dd 命令把文件系统段单独切出来,再用 unsquashfs 手动解包。

1.4 知识体系总览

下面这张图总结了本章的核心流程,我画出来方便大家记忆:

固件提取与解析流程 硬件接口识别 UART / JTAG / SWD SPI Flash 读取 flashrom / 编程器 固件文件头解析 Binwalk / Firmware Mod Kit UART 控制台 波特率扫描 日志输出 / Shell JTAG/SWD 调试 J-Link / OpenOCD 内存读取 / Flash 编程 SPI Flash 读取 CH341A / 树莓派 flashrom 命令 获取原始固件文件 firmware.bin 固件解析与提取 Binwalk 扫描 → 文件系统提取 → 修改 → 重打包

1.5 实战要点总结

好了,这一章的内容就这些。我给大家总结几个关键点:

  1. 先看后动: 拿到设备先拍照、查芯片型号、找文档。别上来就焊线。
  2. 多备工具: 逻辑分析仪、万用表、编程器,一个都不能少。
  3. 备份原始固件: 读出来先存好,万一改坏了还能恢复。
  4. 学会看日志: UART 输出的启动信息里,经常藏着芯片型号、内存大小、文件系统类型等关键信息。
记住: 信息收集阶段花的时间越多,后面分析阶段踩的坑就越少。我见过太多人急着提取固件,结果读出来的数据是错的,白白浪费几天时间。

下一章我们会深入讲解固件文件系统的解包和修改,到时候会用到这章学到的知识。嗯,今天就到这里,大家回去可以找个旧路由器练练手。


公众号:蓝海资料掘金营,微信deep3321