4、固件获取与预处理:从芯片、开发板、OTA包、官网等渠道获取固件,固件文件识别与解包

固件逆向分析的第一步,也是最容易被忽视的一步,就是“拿到正确的固件”并“正确地打开它”。在实际渗透测试、漏洞研究或产品调试中,分析人员往往花费大量时间在错误的文件格式、加密的OTA包或未文档化的私有头文件上。本章将系统梳理固件的四大获取渠道(芯片/板载存储、开发板/调试接口、OTA升级包、厂商官网/第三方聚合站),并深入讲解固件文件的识别方法(文件系统特征、头部魔数、熵值分析)与解包技术(binwalk、jefferson、sasquatch、手动拆分)。通过本章学习,读者应能独立完成从物理芯片到可分析文件系统的完整预处理链路。

固件获取与预处理工程链路 ① 芯片/板载存储 SPI Flash / eMMC / NAND ② 开发板/调试接口 JTAG / SWD / U-Boot ③ OTA升级包 加密 / 差分 / 签名 ④ 官网/聚合站 Firmware.info / 厂商FTP 原始固件二进制镜像(Raw Binary / HEX / BIN) 可能包含 Bootloader + Kernel + Rootfs + 配置分区 + 校准数据 ② 固件识别(文件类型 / 熵值 / 头部魔数) file命令 · hexdump · binwalk -E · 熵值分析(高熵=压缩/加密) ③ 固件解包(文件系统提取 / 内核解压) binwalk -e · jefferson (JFFS2) · sasquatch (SquashFS) · 手动dd拆分 可分析文件系统(rootfs / squashfs / jffs2 / ubifs) 下一步:文件系统挂载、符号分析、漏洞挖掘 风险点 加密固件 签名校验 私有文件系统 NAND坏块 OTA差分

4.1 固件获取的四大渠道与实战选择

核心原理:固件本质上是一段存储在非易失性存储器中的二进制数据,其物理位置决定了获取方式。从芯片直接读取是最底层、最完整的方式,但需要硬件工具和焊接/飞线能力;从开发板获取则依赖调试接口(JTAG/SWD)或Bootloader命令;OTA包是厂商分发更新的载体,通常经过压缩、加密和签名;官网/聚合站则是最便捷的途径,但可能版本滞后或缺少特定区域固件。选择哪种渠道,取决于分析目标——是研究启动流程、挖掘漏洞,还是提取配置文件。

渠道工具/方法优点缺点/风险适用场景
芯片直读SPI Flash编程器、NAND读取器、热风枪拆焊最完整、无校验绕过问题可能损坏芯片、需要焊接、NAND有坏块管理量产设备、无OTA渠道、深度研究
开发板/调试接口OpenOCD + JTAG、U-Boot tftp下载、fastboot无需拆芯片、可交互需要开发板或引出测试点、可能禁用调试口原型验证、固件开发阶段
OTA包抓包(mitmproxy)、固件提取脚本、差分工具获取最新版本、无需硬件加密/签名、差分包需还原、可能需服务器端配合漏洞对比、新版本分析
官网/聚合站wget、FTP爬取、Firmware.info、OpenWrt镜像方便快捷、版本全可能不包含bootloader、区域限制初步分析、已知CVE验证

操作流程(以SPI Flash读取为例):

  1. 识别芯片型号:观察PCB上的8脚或16脚SOIC封装,丝印如“25Q128FVSG”表示Winbond 128Mbit SPI NOR Flash。
  2. 连接编程器:使用CH341A或RT809H编程器,通过测试夹或飞线连接VCC、GND、CLK、MOSI、MISO、CS#。
  3. 读取与校验:在编程器软件中选择对应型号,读取全片数据并保存为.bin,建议读取两次并比对哈希值。
  4. 处理坏块(NAND):若为NAND Flash,需使用nanddump工具配合ECC校验,或使用专用NAND读取器。
风险提示:芯片直读时,若目标设备仍在保修期内或属于生产环境,拆焊操作可能造成物理损坏。务必先确认固件是否可从软件层面获取(如U-Boot环境变量中开启tftp下载),避免不必要的硬件操作。

4.2 固件文件识别:从魔数到熵值分析

判断方法:拿到一个.bin文件后,不能盲目解包。首先使用file命令查看文件类型,但固件通常是裸数据,file命令可能输出“data”。此时需要手动检查头部魔数(Magic Number)。常见固件头部包括:U-Boot的“U-Boot”字符串、Linux内核的“0x1F 0x8B”(gzip)或“0xFD 0x37 0x7A 0x58”(xz)、SquashFS的“hsqs”、JFFS2的“0x85 0x19”、CramFS的“0x28 0xCD 0x3D 0x45”等。

# 查看头部16进制
hexdump -C firmware.bin | head -20

# 使用binwalk扫描嵌入式文件
binwalk firmware.bin

# 熵值分析(识别压缩/加密区域)
binwalk -E firmware.bin

熵值分析原理:熵值(Entropy)衡量数据的随机性。未压缩的代码/文本熵值通常在4.5-6.5之间;压缩或加密数据熵值接近8.0。通过绘制熵值曲线,可以快速定位固件中哪些区域是压缩的rootfs、哪些是明文配置。例如,一个典型路由器固件,前0x20000字节是U-Boot(低熵),接着是内核(中等熵),最后是SquashFS(高熵)。

实战案例:某IP摄像头固件(firmware.bin,大小8MB)。binwalk扫描结果如下:
DECIMAL       HEXADECIMAL     DESCRIPTION
0             0x0             U-Boot version string "U-Boot 1.1.4"
131072        0x20000         Linux kernel ARM boot executable zImage
4194304       0x400000        SquashFS filesystem, little endian, version 4.0
通过dd if=firmware.bin of=kernel.bin bs=1 skip=131072 count=4063232提取内核,再使用dd if=firmware.bin of=rootfs.sqfs bs=1 skip=4194304提取文件系统。整个过程无需任何自动化工具,仅靠binwalk的偏移量提示即可完成。

4.3 固件解包:文件系统提取与手动拆分

核心工具链:binwalk是首选,但面对非标准文件系统或加密固件时,需要组合使用专用工具。SquashFS使用sasquatch(binwalk的-e参数会自动调用),JFFS2使用jefferson,CramFS使用cramfsck,UBIFS使用ubireader_extract_files。对于OTA差分包,可使用delta工具或手动对比新旧版本。

操作流程:

  1. 自动解包:binwalk -eM firmware.bin,-M参数递归扫描提取出的文件。
  2. 手动拆分:当binwalk无法识别时,根据熵值曲线和已知偏移量,使用dd命令手动切割。
  3. 文件系统挂载:对于SquashFS,使用unsquashfs rootfs.sqfs;对于JFFS2,使用jefferson rootfs.jffs2;对于UBIFS,需先模拟NAND设备(nandsim)再挂载。
  4. 处理加密固件:若熵值整体接近8.0且无文件系统特征,可能整体加密。需寻找固件解密密钥(通常在Bootloader中)或利用已知明文攻击。
文件系统类型魔数/特征解包工具备注
SquashFShsqs (0x68 0x73 0x71 0x73)unsquashfs / sasquatch只读压缩,最常见于路由器
JFFS20x85 0x19jefferson日志型,用于NAND Flash
CramFS0x28 0xCD 0x3D 0x45cramfsck老式设备,压缩比低
UBIFSUBI# (0x55 0x42 0x49 0x23)ubireader_extract_files需要处理UBI卷层
ext40x53 0xEFdebugfs / mount常见于eMMC设备
经验提醒:当binwalk解包失败时,不要立即放弃。尝试binwalk -A(扫描opcodes)或binwalk -W(对比不同固件版本)。另外,部分厂商会在固件头部添加自定义结构,可使用binwalk -R "字符串"搜索特定标记。

4.4 常见误区与总结复盘

误区一:盲目依赖binwalk。binwalk基于特征库匹配,对于私有文件系统或加密固件无能为力。正确做法是先做熵值分析,再结合硬件原理判断布局。

误区二:忽略OTA包的差分机制。许多智能设备OTA包是差分升级(如bsdiff),直接解包会得到乱码。需先使用bspatch将差分包与旧版本合并,或寻找全量包。

误区三:混淆NOR与NAND Flash。NOR可直接读取字节,NAND需通过控制器且存在坏块。若从NAND读取的固件出现大量0xFF,可能是坏块标记或ECC校验错误。

误区四:忘记检查签名和校验和。即使成功解包,修改后的固件也无法在目标设备上运行(安全启动)。预处理阶段应记录原始固件的哈希值,以便后续对比。

完整案例闭环:某工业路由器固件分析。初始现象:binwalk仅识别出U-Boot,后续数据熵值接近8.0。分析过程:使用binwalk -E绘制熵值曲线,发现0x20000-0x400000区域熵值波动,疑似加密内核;0x400000之后熵值稳定在7.9,疑似加密文件系统。进一步检查U-Boot环境变量,发现启动参数包含decrypt_rootfs命令。实际操作:在U-Boot中执行decrypt_rootfs 0x400000 0x800000,将解密后的数据写入内存,再通过tftp导出。结果:成功获得明文SquashFS。复盘经验:对于加密固件,Bootloader是天然的“解密机”,优先分析启动流程而非强行破解加密算法。

总结:固件获取与预处理是逆向工程的地基。本章强调“渠道选择-识别-解包”三步走方法论,并指出硬件调试接口往往比软件提取更可靠。在实际项目中,建议建立固件档案表,记录来源、哈希、芯片型号、文件系统类型、解包工具链,以便后续漏洞分析时快速回溯。下一阶段,我们将深入探讨如何从解包后的文件系统中定位敏感信息与攻击面。