3. 固件文件系统分析:文件系统类型、挂载与关键文件识别

拿到一个固件,解压只是第一步。真正的好戏,在文件系统里。

我个人习惯,先看文件系统类型。这决定了你用什么工具、怎么挂载。搞错了,轻则解不开,重则把固件搞坏。嗯,咱们一步步来。

3.1 文件系统类型:Squashfs、JFFS2、YAFFS2

嵌入式设备里,文件系统就那么几种。说白了,它们都是为了在有限的Flash空间里,高效、可靠地存数据。

类型 特点 常见场景
Squashfs 只读、压缩率高、体积小 固件根文件系统(最常见)
JFFS2 可读写、磨损均衡、掉电安全 配置分区、日志分区
YAFFS2 专为NAND Flash设计、速度快 大容量存储、多媒体设备

Squashfs 是我遇到最多的。为什么?因为它只读,固件厂商不希望你在运行时改系统文件。压缩率很高,一个几十兆的固件,解出来可能上百兆。

避坑指南: 我曾经遇到一个路由器固件,binwalk解出来全是Squashfs碎片。后来发现厂商用了非标准的压缩参数。这时候,你得手动指定块大小和压缩算法。

JFFS2YAFFS2 都是可写的。JFFS2有磨损均衡,适合频繁擦写的分区。YAFFS2更快,但只支持NAND Flash。

你想想看,如果固件里有个config分区,大概率是JFFS2。如果是摄像头存视频的,可能是YAFFS2。

3.2 文件系统挂载与浏览

知道了类型,接下来就是挂载。我一般用两种方式:

  1. binwalk -Me:自动解压并挂载。适合快速浏览。
  2. 手动挂载:更可控,适合调试。

手动挂载Squashfs的典型命令:

# 先找到偏移量(如果有)
binwalk firmware.bin | grep "Squashfs"

# 假设偏移是 0x100000
dd if=firmware.bin of=rootfs.squashfs bs=1 skip=$((0x100000))

# 挂载
sudo mount -t squashfs -o loop rootfs.squashfs /mnt/firmware

为什么用 dd 切出来?因为很多固件前面有uboot头、内核,直接挂载会报错。我习惯先切出纯文件系统镜像。

小技巧: 挂载JFFS2时,记得加 -o ro 只读挂载。我曾经手滑写入了东西,结果固件校验失败,设备变砖。嗯,血的教训。

浏览文件系统,我推荐用 tree 命令看整体结构:

tree -L 3 /mnt/firmware

这样一眼就能看出目录布局。常见的目录有 /bin/sbin/usr/etc/lib/www 等。

3.3 关键文件识别

挂载后,别急着到处翻。我有个固定的检查清单:

  • /etc/passwd, /etc/shadow:用户和密码。很多设备用硬编码密码。
  • /etc/inittab:启动进程。看哪些服务开机自启。
  • /etc/init.d//etc/rc.d/:启动脚本。这里经常藏着后门。
  • /bin/busybox:嵌入式瑞士军刀。版本号能暴露漏洞。
  • /www//htdocs/:Web管理界面。找硬编码API、未授权接口。
  • /lib/modules/:内核模块。驱动漏洞常在这里。
  • *.conf, *.cfg, *.xml:配置文件。找明文密码、密钥。

实战案例: 我分析过一个摄像头固件,在 /etc/init.d/S99local 里发现一行 telnetd -l /bin/sh。厂商居然留了个telnet后门,密码是空。这就是典型的「调试接口未关闭」。

还有一个容易被忽略的:/tmp 目录。虽然挂载时是空的,但运行时会有日志、临时文件。如果固件里有 /tmp 下的脚本,说明它会在运行时写东西。

为什么会这样?很多厂商图省事,把调试脚本直接打包进固件。你想想看,这些脚本在运行时暴露的信息,往往比静态分析更多。

3.4 知识体系结构图

下面这张图,是我自己总结的固件文件系统分析流程。你可以照着这个顺序来,不容易漏东西。

固件文件系统分析流程 1. 识别文件系统类型 Squashfs(只读) JFFS2(可读写) YAFFS2(NAND) 2. 挂载文件系统 3. 浏览目录结构 4. 识别关键文件(passwd、脚本、配置)

重要提醒: 分析固件时,一定要在隔离环境里操作。有些固件里的脚本会尝试连接网络、执行危险命令。我一般用Docker或者虚拟机,快照随时回滚。

好了,文件系统这块就这些。记住:类型决定工具,挂载要小心,关键文件别放过。下次你拿到一个固件,按这个流程走一遍,基本不会漏掉重要信息。

专注资料整理