4、固件文件系统分析:识别文件系统类型与挂载遍历
拿到一个固件,解压之后看到一堆二进制文件,很多人第一反应就是「这玩意儿怎么打开?」。嗯,我刚开始做固件逆向的时候也懵过。后来发现,关键就在于识别文件系统类型。说白了,固件里的文件系统就像房子的骨架,搞清楚它,你才能知道数据是怎么组织的。
我个人习惯,拿到固件先跑一把 binwalk,看看能不能直接识别出文件系统。但有时候工具会骗人,或者固件被魔改过。这时候就得靠手动分析了。今天我就把这几年的经验捋一捋,带你走一遍完整的流程。
4.1 常见文件系统类型速览
嵌入式设备里,文件系统就那么几种。我列个表,你一看就明白:
| 文件系统类型 | 典型特征 | 常见设备 | 魔数(Magic Number) |
|---|---|---|---|
| SquashFS | 只读、压缩率高 | 路由器、IoT设备 | hsqs 或 sqsh |
| JFFS2 | 日志型、支持NAND Flash | 老旧嵌入式设备 | 0x1985(大端) |
| CramFS | 简单、只读 | 早期Linux设备 | 0x28CD3D45 |
| UBIFS | 新一代、支持磨损均衡 | 现代路由器、手机 | 无固定魔数,依赖UBI头 |
| YAFFS2 | 专为NAND设计 | 部分相机、工控设备 | 无固定魔数,靠OOB区域识别 |
你可能会问:「为什么有这么多类型?」其实原因很简单——不同的Flash芯片有不同的特性。比如NAND Flash容易有坏块,JFFS2和UBIFS就是为这个设计的。而SquashFS因为压缩率高,特别适合存储空间紧张的路由器。
4.2 手动识别文件系统类型
工具不是万能的。我记得有一次,binwalk死活识别不出一个固件的文件系统。后来我用十六进制编辑器打开一看,发现魔数被改成了 0xDEADBEEF——明显是厂商故意混淆的。
这时候怎么办?我教你几招手动识别的方法:
- 看魔数:用
hexdump -C firmware.bin | head -20查看文件头。SquashFS的魔数通常是hsqs,JFFS2是0x1985。 - 看结构:SquashFS的超级块有固定偏移,比如
inode_count和block_size字段。你可以用dd命令提取出来分析。 - 看压缩方式:SquashFS支持gzip、lzma、lzo等。如果固件里有一段连续的压缩数据,那大概率是SquashFS。
- 看文件系统大小:用
stat或ls -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
total_size 和 erase_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 知识体系图:文件系统分析全流程
下面这张图是我自己总结的,把整个流程串起来了。你照着这个思路走,基本不会迷路:
这张图把整个流程分成了四步:获取固件、识别类型、挂载、遍历。每一步都有对应的工具和方法。你照着这个流程走,基本不会漏掉关键信息。
好了,关于文件系统分析就讲这么多。记住,这一步是固件逆向的「敲门砖」。搞不定文件系统,后面的漏洞挖掘根本无从谈起。下一章我们会深入探讨如何从文件系统中提取敏感信息,敬请期待。