3、固件解包与文件系统分析

好,咱们进入正题。拿到一个智能家居固件,第一件事是什么?不是反汇编,不是找漏洞。而是——把它拆开,看看里面到底装了啥。

说白了,固件就是个打包好的文件。里面可能有操作系统、文件系统、应用程序、配置文件。我们得先把它解包,才能做后续分析。这步做不好,后面全是白搭。

3.1 binwalk:我的瑞士军刀

binwalk 这工具,我用了快十年了。它是我分析固件时最常用的工具,没有之一。它的核心能力就两个:扫描提取

先说说扫描。你拿到一个固件,不知道它里面嵌了什么?跑一下 binwalk 就知道了:

binwalk firmware.bin

它会告诉你:这里有 SquashFS 文件系统,那里有 LZMA 压缩数据,还有一段 U-Boot 引导程序。嗯,一目了然。

我个人习惯,扫描时加个 -e 参数,直接提取:

binwalk -e firmware.bin

它会自动识别文件类型,把能解的都解出来。省事。

小技巧: 如果遇到提取失败,试试 binwalk -Me firmware.bin。这个 -M 参数会递归扫描子文件,-e 是提取。我曾经遇到过一个固件,里面嵌套了三层压缩,普通提取根本搞不定,用这个参数一次搞定。

但 binwalk 也不是万能的。有时候它识别不出来,或者提取出来的文件不完整。这时候我会用 dd 命令手动切割。你想想看,binwalk 已经告诉你偏移地址了,剩下的就是手工活。

dd if=firmware.bin of=rootfs.squashfs bs=1 skip=0x123456

3.2 常见文件系统:SquashFS、JFFS2、YAFFS2

智能家居设备里,最常见的文件系统就这三种。我一个个说。

SquashFS

这是最最常见的。压缩率高,只读,适合嵌入式设备。binwalk 通常能直接识别并提取。

提取出来后,怎么挂载查看?我一般用 unsquashfs

unsquashfs rootfs.squashfs

它会解压到当前目录的 squashfs-root 文件夹里。然后你就可以像浏览普通文件夹一样,查看里面的文件了。

注意: 有些厂商会魔改 SquashFS,比如修改魔数或压缩算法。这时候 binwalk 可能认不出来。我曾经遇到过一个大厂的智能摄像头固件,binwalk 死活扫不出文件系统。后来我手动分析二进制,发现厂商把 SquashFS 的魔数从 hsqs 改成了 hsqX。改回来就能正常解包了。

JFFS2

JFFS2 是专门为 NAND Flash 设计的日志型文件系统。它支持磨损均衡和掉电保护。在高端智能家居设备里比较常见。

提取 JFFS2 稍微麻烦点。你需要先知道它的偏移地址,然后用 jefferson 工具:

jefferson rootfs.jffs2

或者用 flash_erasenandwrite 模拟 NAND Flash 环境。嗯,这个操作有点复杂,我建议初学者先用 jefferson

YAFFS2

YAFFS2 也是为 NAND Flash 设计的。它比 JFFS2 更轻量,但支持度不如 JFFS2 广泛。我一般在一些老旧的设备上见到它。

提取 YAFFS2 可以用 unyaffs

unyaffs rootfs.yaffs2

或者用 yaffs2utils 工具集。说实话,YAFFS2 的提取成功率不如前两个高,因为厂商经常魔改。

文件系统 特点 提取工具 常见场景
SquashFS 高压缩、只读 unsquashfs 绝大多数智能家居设备
JFFS2 日志型、支持磨损均衡 jefferson 高端摄像头、路由器
YAFFS2 轻量、NAND 优化 unyaffs 老旧设备、部分 IoT 模块

3.3 固件加密与压缩识别

这是最头疼的部分。厂商不傻,他们知道你会拆固件,所以会加密或混淆。

怎么判断固件是否加密?我一般看这几个特征:

  • 熵值过高:用 binwalk -E firmware.bin 查看熵值。如果整个固件的熵值接近 1.0,那大概率是加密了。
  • 没有明文特征:扫描不到文件系统、没有 U-Boot 字符串、没有文件头。
  • 文件头异常:比如以随机字节开头,而不是常见的 7f45 4c46(ELF)或 hsqs(SquashFS)。

如果确认加密了,怎么办?

嗯,这里要分情况:

  • 简单 XOR 加密:很多厂商用 XOR 加密,密钥就藏在固件里。用 binwalk -X 可以尝试暴力破解。
  • AES 加密:这个就麻烦了。你需要找到密钥,通常藏在 U-Boot 或 Bootloader 里。我曾经分析过一个智能门锁,它的 AES 密钥就硬编码在 U-Boot 的源码里。嗯,厂商连编译都没优化,直接明文存储。
  • 自定义加密:这个最头疼。没有通用工具,只能逆向分析 Bootloader 的加解密函数。
核心思路: 加密固件的突破口通常在 Bootloader。因为 Bootloader 必须能解密固件才能启动。找到 Bootloader 里的解密函数,你就拿到了钥匙。

至于压缩识别,这个相对简单。binwalk 能识别大部分压缩算法:LZMA、gzip、zlib、LZO 等。如果它识别不出来,你可以用 file 命令试试:

file unknown_part.bin

有时候 file 能给出线索。比如它可能会说「gzip compressed data」,那你就用 zcatgunzip 解压。

最后,我画了一张图,总结一下固件解包的整体流程:

固件解包与文件系统分析流程 获取固件 binwalk 扫描 是否加密? binwalk -e 提取 分析 Bootloader 识别文件系统类型

这张图把流程串起来了。你拿到固件,先扫,判断是否加密。没加密就直接提取,加密了就去找 Bootloader。最后识别文件系统类型,用对应工具解包。

嗯,这一章的内容就这些。记住:解包是基础,基础不牢,地动山摇。我见过太多人跳过这步直接反汇编,结果分析半天发现分析的是加密数据,白费功夫。

避坑指南: 我曾经分析过一个智能插座固件,binwalk 扫出来一个 SquashFS,我直接 unsquashfs 解压,结果解出来一堆乱码。后来才发现,厂商在 SquashFS 之后又加了一层自定义压缩。所以,解包后一定要验证文件完整性,比如看看有没有 /bin/etc 这些标准目录。没有?那说明解包不完整。

专注资料整理