3. 固件获取与预处理:从芯片、板卡、OTA包、官网等途径获取固件,固件格式识别与解包

固件逆向分析的第一步,也是最容易被忽视的一步,是“拿到”并“读懂”固件本身。在实际的嵌入式安全评估、漏洞挖掘或产品研发中,我们面对的不是一个抽象的程序,而是一个封装在特定硬件介质、特定文件格式或特定传输协议中的二进制镜像。如果无法准确获取固件并正确解包,后续的静态分析、动态调试都将成为无源之水。本章将系统讲解固件的四大获取途径(芯片直读、板卡提取、OTA包捕获、官网下载),深入剖析固件格式的识别方法,并详细演示从二进制文件到可分析文件系统的完整解包流程。

固件获取与预处理工程链路 获取途径 ① 芯片直读 (SPI/JTAG) ② 板卡提取 (U-Boot/Shell) ③ OTA 包捕获 ④ 官网/论坛下载 格式识别 file/binwalk/hexdump 解包处理 • 固件头解析 • 压缩算法识别 • 文件系统提取 • 加密/签名绕过 • 目录结构重建 可分析镜像 rootfs/内核/应用 关键决策点: 1. 固件是否加密? → 若加密,需先定位密钥或硬件安全模块(HSM) 2. 固件是否带签名? → 若验签,需提取公钥或绕过校验逻辑 3. 文件系统类型? → SquashFS / JFFS2 / CramFS / ext4 / UBI 4. 压缩算法? → gzip / lzma / lz4 / zstd / xz

上图展示了固件获取与预处理的完整工程链路。从左侧的四大获取途径出发,经过格式识别、解包处理,最终得到可分析的文件系统与内核镜像。整个过程环环相扣,任何一个环节的失误都可能导致后续分析方向错误。下面我们将逐一深入每个环节。

3.1 固件获取的四大途径与实战要点

3.1.1 芯片直读:SPI Flash 与 JTAG 提取

核心原理:绝大多数嵌入式设备(路由器、IoT 网关、工业控制器)使用 SPI NOR Flash 或 NAND Flash 存储固件。芯片直读是最底层的获取方式,通过编程器(如 CH341A、RT809H)或调试接口(JTAG/SWD)直接读取 Flash 中的原始二进制数据。这种方式不依赖设备是否运行,即使设备完全变砖也能提取。

操作流程:

  1. 拆解设备:定位 PCB 上的 Flash 芯片,记录型号(如 Winbond W25Q128FV、MXIC MX25L25645G)。
  2. 连接编程器:使用 SOP8/SOP16 测试夹或热风枪拆焊后连接编程器。注意电压匹配(3.3V 为主,部分老芯片为 5V)。
  3. 读取数据:在编程器软件中识别芯片型号,设置读取大小为芯片容量(如 16MB),读取并保存为 .bin 文件。
  4. 校验:读取两次并比对哈希值,确保数据完整性。
风险提示:芯片直读可能触发硬件保护机制(如读保护 RP/OTP)。部分现代 MCU(如 STM32)具有 RDP 级别保护,直接读取会得到全 0xFF 或全 0x00。此时需考虑通过漏洞降级 RDP 级别,或改用其他途径。

3.1.2 板卡提取:利用 U-Boot 或系统 Shell

如果设备可以正常启动或进入 U-Boot 命令行,板卡提取是更便捷的方式。常见方法包括:

  • U-Boot 下导出:在 U-Boot 提示符下使用 md(内存显示)、mw(内存写)、nand read、sf read 等命令将 Flash 内容读取到内存,再通过 tftp 或 loadb 传输到主机。
  • 系统 Shell 下复制:若设备开放 telnet/SSH,可直接查看 /dev/mtd* 设备节点,使用 dd if=/dev/mtd0 of=/tmp/fw.bin 备份。
  • 利用漏洞获取 Shell:如通过命令注入、硬编码后门等获取 root 权限。
# U-Boot 下读取 SPI Flash 示例
U-Boot> sf probe 0
U-Boot> sf read 0x82000000 0x0 0x1000000  ; # 读取 16MB 到内存
U-Boot> tftp 0x82000000 firmware.bin      ; # 通过 TFTP 上传到主机

3.1.3 OTA 包捕获:中间人代理与流量分析

智能设备(如智能摄像头、扫地机器人)通常通过 OTA 升级。捕获 OTA 包需要搭建代理环境:

  1. 配置代理:在路由器或主机上运行 mitmproxy / Burp Suite,将设备流量指向代理。
  2. 绕过 TLS 校验:部分设备会校验服务器证书,需将代理 CA 证书安装到设备信任库(若可写)或使用 SSL 剥离。
  3. 触发升级:在 App 端点击“检查更新”,捕获 HTTP/HTTPS 请求,定位固件下载 URL。
  4. 下载固件:直接使用 wget/curl 下载固件包,注意可能需要伪造请求头(如 User-Agent、签名参数)。
经验:OTA 包往往经过双重封装:外层为厂商自定义格式(如 .bin 带头部),内层才是标准文件系统。捕获后不要急于分析,先观察文件头结构。

3.1.4 官网与第三方渠道

厂商官网的“技术支持/下载中心”是最合法的获取途径。但需注意:官网固件可能为增量升级包(仅包含差异文件),而非完整镜像。第三方论坛(如 OpenWrt 社区、Hackaday)常提供由开发者提取的完整固件,但需警惕被植入后门的风险,下载后务必校验哈希值。

3.2 固件格式识别:从二进制到结构化

3.2.1 文件类型初步判断

拿到固件文件后,第一步是使用 file 命令和 hexdump 查看文件头。

$ file firmware.bin
firmware.bin: data  # 未知格式

$ hexdump -C firmware.bin | head -20
00000000  27 05 19 56  88 93 4d 61  67 69 63 00  00 00 00 00  |'..V..Magic.....|
00000010  00 00 00 00  00 00 00 00  00 00 00 00  00 00 00 00  |................|

常见的固件魔数(Magic Number)包括:

魔数(十六进制)ASCII 标识含义
1F 8Bgzipgzip 压缩流
FD 37 7A 58 5Axzxz 压缩流
42 5A 68BZhbzip2 压缩流
53 51 55 41 53 48 46 53SQUASHFSSquashFS 文件系统
31 19 00 00—JFFS2 文件系统
55 42 49 23 01UBI#UBI 文件系统
7F 45 4C 46ELFLinux 内核或可执行文件

3.2.2 Binwalk 深度扫描

Binwalk 是固件分析的核心工具,它通过特征签名扫描固件中的嵌入文件。

$ binwalk firmware.bin

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             DLOB firmware header, boot partition
262144        0x40000         LZMA compressed data
1048576       0x100000        SquashFS filesystem, little endian, version 4.0, compression:lzma

Binwalk 输出清晰地展示了固件布局:头部 + LZMA 压缩的内核 + SquashFS 根文件系统。此时可执行 binwalk -e 自动提取。

进阶技巧:当 Binwalk 无法识别时,可尝试 binwalk -A(opcode 扫描)或 binwalk -W(熵分析)。熵值高的区域通常为加密数据或压缩数据,熵值低的区域可能为明文代码或填充。

3.3 固件解包实战:从镜像到文件系统

3.3.1 手动解包流程

以典型的“头部 + 内核 + 文件系统”三段式固件为例:

  1. 跳过头部:使用 dd 跳过头部,提取内核和文件系统。
  2. 解压内核:若内核为 LZMA 压缩,使用 lzma -d 或 7z x 解压。
  3. 挂载文件系统:SquashFS 可使用 unsquashfs 直接解包;JFFS2 需使用 jefferson 或 mtd-utils。
# 提取文件系统(偏移 0x100000,大小 0x800000)
$ dd if=firmware.bin of=rootfs.squashfs bs=1 skip=1048576 count=8388608
$ unsquashfs rootfs.squashfs
Parallel unsquashfs: Using 4 processors
1792 inodes (2048 blocks) to write
[===============================================================|] 2048/2048 100%
$ ls squashfs-root/
bin  dev  etc  lib  proc  sbin  usr  var

3.3.2 处理加密与签名固件

现代设备普遍采用 AES 加密 + RSA 签名。面对加密固件,思路如下:

  • 寻找密钥:在 U-Boot 环境变量、设备树(DTB)、或未加密的引导程序中搜索硬编码密钥。
  • 利用解密预言机:若设备支持“恢复模式”或“调试模式”,可能提供解密接口。
  • 动态提取:在设备运行时从内存中 dump 解密后的数据(使用 devmem 或冷启动攻击)。
法律与道德边界:绕过加密和签名仅限用于自己拥有或已获授权的设备安全研究。对受版权保护的固件进行解密和分发可能违反 DMCA 及相关法律。

3.4 案例拆解:某品牌 IP 摄像头的固件获取与解包

背景与目标:某安防厂商的 IP 摄像头(固件版本 V2.1.4)被曝存在多个漏洞,但厂商未提供完整固件下载,仅支持 App 内 OTA 升级。我们的目标是获取完整文件系统以进行漏洞分析。

初始现象:通过官网下载的固件仅为 2MB 的增量包,不包含完整 rootfs。使用 Binwalk 扫描仅发现少量 PNG 图标和配置文件。

关键输入数据:

  • 设备型号:IPC-2340F,主控 SoC:海思 Hi3516EV200
  • Flash 布局:4MB SPI NOR(uboot 256KB + kernel 2MB + rootfs 1.5MB + config 256KB)
  • 网络环境:设备通过 DHCP 获取 IP,App 与设备通信使用 TLS 1.2

分析判断过程:

  1. 首先尝试 U-Boot 提取:通过串口进入 U-Boot,执行 sf read 读取整个 Flash,成功获取 4MB 完整镜像。
  2. 使用 Binwalk 扫描完整镜像,发现偏移 0x100000 处有 SquashFS 文件系统。
  3. 但 unsquashfs 解包时报错“Filesystem uses unsupported compression type: lzma”。
  4. 检查 SquashFS 超级块,发现压缩类型为 LZMA,而系统默认 unsquashfs 不支持。需使用 sasquatch(Binwalk 的补丁版)解包。

实际操作步骤:

# 1. 从完整镜像提取 rootfs
$ dd if=full_flash.bin of=rootfs.squashfs bs=1 skip=1048576 count=1572864

# 2. 使用 sasquatch 解包
$ sasquatch rootfs.squashfs
Processing 'rootfs.squashfs'...
Found a valid SquashFS 4.0 little-endian superblock
Compression type: lzma
Inodes count: 2048
...
$ ls squashfs-root/
bin  etc  lib  usr  var  www  init

结果对比:成功提取出完整的 Linux 文件系统,包含 Web 服务程序、摄像头控制程序、以及一个隐藏的 telnetd 二进制。后续分析发现该 telnetd 存在硬编码后门账号,与厂商公告的漏洞一致。

风险与代价:串口提取需要拆机并焊接调试线,存在损坏设备的风险;且设备在保修期内拆机会失去保修资格。

复盘经验:

  • 优先尝试非侵入式方法(OTA 捕获、官网下载),最后才考虑硬件拆解。
  • Binwalk 默认工具链不完整,建议安装 sasquatch、jefferson、ubi_reader 等扩展工具。
  • 提取固件后立即计算 SHA-256 并记录来源、日期、设备版本,便于审计追溯。

3.5 常见误区与总结复盘

误区后果正确做法
拿到固件直接 Binwalk -e,不检查头部提取出大量碎片文件,无法还原文件系统先 hexdump 查看头部,理解固件布局
忽略 OTA 包的增量特性分析的是补丁而非完整系统,遗漏核心逻辑结合当前运行版本,用 diff 工具对比
使用系统自带 unsquashfs 解包所有镜像遇到 LZMA/XZ 压缩时报错或解包不完整安装 sasquatch、squashfs-tools-ng 等增强工具
不记录固件来源和哈希值无法复现分析结果,法律合规风险建立固件样本库,记录元数据
忽略 Flash 分区表提取的镜像可能包含 OOB 数据或冗余区域从 U-Boot 环境变量或 DTS 中获取分区布局

总结:固件获取与预处理是逆向分析的地基。一个合格的固件分析师应掌握至少两种获取途径(如 OTA 捕获 + 芯片直读),并能熟练使用 Binwalk、Sasquatch、U-Boot 命令等工具。在解包过程中,保持对固件头部、压缩算法、文件系统类型的敏感度,遇到异常时善用熵分析和字符串搜索。最重要的是,始终记录操作日志和样本哈希,确保分析过程可复现、可审计。下一阶段,我们将基于提取出的文件系统,展开内核与应用程序的静态分析。