4、固件文件系统分析:识别文件系统类型与挂载遍历

拿到一个固件,解压之后看到一堆二进制文件,很多人第一反应就是「这玩意儿怎么打开?」。嗯,我刚开始做固件逆向的时候也懵过。后来发现,关键就在于识别文件系统类型。说白了,固件里的文件系统就像房子的骨架,搞清楚它,你才能知道数据是怎么组织的。

我个人习惯,拿到固件先跑一把 binwalk,看看能不能直接识别出文件系统。但有时候工具会骗人,或者固件被魔改过。这时候就得靠手动分析了。今天我就把这几年的经验捋一捋,带你走一遍完整的流程。

4.1 常见文件系统类型速览

嵌入式设备里,文件系统就那么几种。我列个表,你一看就明白:

文件系统类型 典型特征 常见设备 魔数(Magic Number)
SquashFS 只读、压缩率高 路由器、IoT设备 hsqssqsh
JFFS2 日志型、支持NAND Flash 老旧嵌入式设备 0x1985(大端)
CramFS 简单、只读 早期Linux设备 0x28CD3D45
UBIFS 新一代、支持磨损均衡 现代路由器、手机 无固定魔数,依赖UBI头
YAFFS2 专为NAND设计 部分相机、工控设备 无固定魔数,靠OOB区域识别

你可能会问:「为什么有这么多类型?」其实原因很简单——不同的Flash芯片有不同的特性。比如NAND Flash容易有坏块,JFFS2和UBIFS就是为这个设计的。而SquashFS因为压缩率高,特别适合存储空间紧张的路由器。

4.2 手动识别文件系统类型

工具不是万能的。我记得有一次,binwalk死活识别不出一个固件的文件系统。后来我用十六进制编辑器打开一看,发现魔数被改成了 0xDEADBEEF——明显是厂商故意混淆的。

这时候怎么办?我教你几招手动识别的方法:

  1. 看魔数:用 hexdump -C firmware.bin | head -20 查看文件头。SquashFS的魔数通常是 hsqs,JFFS2是 0x1985
  2. 看结构:SquashFS的超级块有固定偏移,比如 inode_countblock_size 字段。你可以用 dd 命令提取出来分析。
  3. 看压缩方式:SquashFS支持gzip、lzma、lzo等。如果固件里有一段连续的压缩数据,那大概率是SquashFS。
  4. 看文件系统大小:用 statls -l 查看固件大小,再对比常见文件系统的典型大小范围。
我的小技巧:如果你不确定,可以先用 file 命令试试。虽然它不一定准,但能给你一个方向。比如 file firmware.bin 可能会输出「SquashFS filesystem, little endian」。

4.3 挂载文件系统:从理论到实践

识别出类型之后,下一步就是挂载。挂载说白了就是把文件系统「展开」到本地目录,方便你浏览和提取文件。

我以最常见的SquashFS为例,给你演示一下完整流程:

# 1. 安装工具(Ubuntu/Debian)
sudo apt-get install squashfs-tools

# 2. 解压SquashFS
unsquashfs -d ./extracted_fs firmware.squashfs

# 3. 或者用挂载方式(需要内核支持)
sudo mount -t squashfs firmware.squashfs /mnt/squashfs -o loop,ro

如果是JFFS2,步骤稍微复杂一点:

# 1. 加载内核模块
sudo modprobe mtdblock
sudo modprobe jffs2

# 2. 创建模拟MTD设备
sudo modprobe mtdram total_size=65536 erase_size=256
sudo dd if=firmware.jffs2 of=/dev/mtdblock0

# 3. 挂载
sudo mount -t jffs2 /dev/mtdblock0 /mnt/jffs2
注意:JFFS2挂载时,total_sizeerase_size 必须和固件实际参数一致。我曾经因为 erase_size 设错了,挂载后文件全是乱码。后来查了芯片手册才搞定。

CramFS的挂载和SquashFS类似,但工具不同:

# 安装工具
sudo apt-get install cramfsprogs

# 挂载
sudo mount -t cramfs firmware.cramfs /mnt/cramfs -o loop,ro

4.4 遍历文件系统:找到关键文件

挂载成功后,下一步就是遍历。我个人习惯用 find 命令配合 grep,快速定位敏感文件:

# 查找所有可执行文件
find /mnt/squashfs -type f -executable

# 查找配置文件
find /mnt/squashfs -name "*.conf" -o -name "*.cfg"

# 查找包含密码的文件
grep -r "password" /mnt/squashfs --include="*.php" --include="*.sh"

# 查找Web服务相关文件
find /mnt/squashfs -name "*.html" -o -name "*.cgi"

你想想看,一个固件里最值钱的是什么?无非是配置文件、私钥、硬编码密码、还有Web接口。我一般会重点关注 /etc/var/www 这几个目录。

举个例子,我之前分析一个路由器固件,在 /etc/config 下找到了 shadow 文件,里面居然有明文密码。厂商把密码写死在固件里,所有设备都一样。这种漏洞一旦公开,后果很严重。

4.5 避坑指南:我踩过的那些坑

做固件分析这么多年,我踩过的坑不少。挑几个典型的跟你说说:

  • 文件系统被拼接:有些固件会把多个文件系统拼在一起。比如前面是SquashFS,后面是JFFS2。这时候 binwalk 可能只识别出第一个,你得手动分割。
  • 字节序问题:SquashFS有大端和小端两种。如果你挂载时报错「wrong magic number」,八成是字节序搞反了。用 unsquashfs -le-be 指定一下。
  • 压缩方式不匹配:有些厂商会魔改压缩算法。比如把gzip换成lzma,但魔数还是 hsqs。这时候标准工具解不了,你得自己写脚本。
  • 文件系统损坏:固件在传输或存储过程中可能损坏。我建议先校验一下哈希值,或者用 fsck 工具检查。
核心要点:文件系统分析是固件逆向的基石。识别类型、正确挂载、高效遍历,这三步走完,你就能拿到固件里的所有文件。剩下的就是找漏洞了。

4.6 知识体系图:文件系统分析全流程

下面这张图是我自己总结的,把整个流程串起来了。你照着这个思路走,基本不会迷路:

固件文件系统分析全流程 获取固件 识别文件系统类型 自动识别(binwalk) 手动识别(魔数/结构) 挂载文件系统 遍历文件系统 提取关键文件

这张图把整个流程分成了四步:获取固件、识别类型、挂载、遍历。每一步都有对应的工具和方法。你照着这个流程走,基本不会漏掉关键信息。

我的建议:刚开始做的时候,别急着用高级工具。先手动分析几个固件,把魔数、结构、挂载参数这些基础搞明白。工具只是辅助,理解原理才是根本。

好了,关于文件系统分析就讲这么多。记住,这一步是固件逆向的「敲门砖」。搞不定文件系统,后面的漏洞挖掘根本无从谈起。下一章我们会深入探讨如何从文件系统中提取敏感信息,敬请期待。

专注资料整理