3、固件文件系统分析:常见文件系统(Squashfs、JFFS2、Cramfs)、文件系统挂载与遍历、关键文件识别
拿到固件之后,第一件事是什么?
我个人习惯,不是急着去逆向,也不是去跑什么自动化工具。而是先看看它的文件系统长什么样。说白了,固件里的文件系统,就是整个设备的“硬盘”。里面藏着配置文件、密码、启动脚本、甚至后门。你想想看,如果连这个都摸不清楚,后面的漏洞挖掘基本就是瞎蒙。
3.1 常见文件系统:Squashfs、JFFS2、Cramfs
嵌入式设备里,文件系统种类其实不多。我这些年挖过的固件,90%以上就这三种:Squashfs、JFFS2、Cramfs。它们各有各的脾气。
| 文件系统 | 特点 | 压缩方式 | 常见场景 |
|---|---|---|---|
| Squashfs | 只读、高压缩比、支持大文件 | gzip / lzma / lzo | OpenWrt、路由器、IoT设备 |
| JFFS2 | 可读写、支持NAND Flash、磨损均衡 | zlib / 无压缩 | 老款路由器、工控设备 |
| Cramfs | 只读、极简、不支持4GB以上 | zlib | 早期Linux设备、低内存设备 |
嗯,这里要注意。Squashfs 现在是最主流的。为什么?因为它压缩率高,而且支持分块压缩。我在一个项目中遇到过,一个 32MB 的固件,解压出来能到 120MB。你想想看,如果不用 Squashfs,这数据根本塞不进 Flash。
JFFS2 呢?它有个好处——可写。但代价是性能差。我曾经调试过一个工控设备,它的日志文件就写在 JFFS2 上,结果每次写日志,CPU 占用率就飙到 80%。后来发现是磨损均衡在作祟。
Cramfs 现在基本被淘汰了。它不支持大于 4GB 的文件,而且压缩率一般。但有些老设备还在用,比如一些 2000 年代初期的 IP Camera。如果你遇到 Cramfs,别慌,工具链还是支持的。
3.2 文件系统挂载与遍历
拿到固件后,怎么把文件系统“拆开”?
我一般分三步走:
- 识别文件系统类型——用
binwalk或者file命令看一眼。 - 提取文件系统——用
binwalk -e或者unsquashfs等专用工具。 - 挂载并遍历——如果提取失败,就手动挂载。
举个例子,假设你有一个固件 firmware.bin:
# 第一步:看看里面有什么
binwalk firmware.bin
# 输出大概长这样:
# DECIMAL HEXADECIMAL DESCRIPTION
# 0 0x0 u-boot image
# 131072 0x20000 Squashfs filesystem, little endian, version 4.0
# 第二步:直接提取
binwalk -e firmware.bin
# 第三步:如果提取失败,手动挂载
# 先找到 Squashfs 的偏移量(比如 0x20000)
dd if=firmware.bin of=squashfs.img bs=1 skip=131072
unsquashfs squashfs.img
我个人习惯,遇到 JFFS2 的时候,会用 jefferson 这个工具。它比 binwalk 对 JFFS2 的支持更好。有一次我遇到一个 JFFS2 镜像,binwalk 死活解不开,换了 jefferson 一次搞定。
unsquashfs 报错说“unknown compression”,很可能是固件用了 LZMA 压缩。试试 unsquashfs -d output_dir -comp lzma squashfs.img。
遍历文件系统的时候,我建议用 tree 命令。它能让你一眼看清目录结构。比如:
tree -L 3 extracted_fs/
输出大概长这样:
extracted_fs/
├── bin
│ ├── busybox
│ ├── sh
│ └── ...
├── etc
│ ├── passwd
│ ├── shadow
│ ├── config
│ │ ├── network
│ │ └── ...
│ └── ...
├── usr
│ ├── sbin
│ └── ...
└── var
└── ...
嗯,看到 etc/passwd 和 etc/shadow 了吗?这就是我们下一步要重点关注的东西。
3.3 关键文件识别:/etc/passwd、shadow、配置文件
文件系统挂载好之后,别急着到处翻。先找几个“命门”文件。我总结了三个必看:
- /etc/passwd——用户列表,有时候直接暴露明文密码。
- /etc/shadow——密码哈希,如果能破解,就等于拿到了 root 权限。
- 配置文件——比如
/etc/config/*、*.conf、*.ini,里面经常有硬编码的密钥、API Token、甚至后门账号。
举个例子,我曾经在一个路由器固件里看到这样的 /etc/passwd:
root:$1$abc123$xyz:0:0:root:/root:/bin/sh
admin:x:1000:1000:Admin:/home/admin:/bin/sh
guest:guest:1001:1001:Guest:/home/guest:/bin/sh
看到了吗?guest 用户的密码直接明文写在 passwd 文件里。这种低级错误,在 IoT 设备里其实不少见。
再看 /etc/shadow:
root:$1$abc123$xyz:18000:0:99999:7:::
admin:!:18000:0:99999:7:::
这里 admin 用户的密码字段是 !,表示账号被锁定。但 root 的哈希是 $1$ 开头的,这是 MD5 加密。用 John the Ripper 或者 hashcat,跑个字典,几分钟就能破解。
/etc/shadow 的权限设置成 644,甚至 777。这意味着任何用户都能读取密码哈希。我曾经在某个工控设备上见过这种情况,当时就觉得这设备基本等于裸奔。
配置文件呢?我建议重点关注这几个:
/etc/config/network——网络配置,可能暴露内网 IP、网关、甚至 VPN 密钥。/etc/config/wireless——WiFi 配置,SSID 和密码经常明文存储。/etc/init.d/*——启动脚本,里面可能藏着调试接口或者后门。*.conf或*.ini——各种服务的配置文件,比如 HTTP 服务器、FTP、Telnet。
我记得有一次,在一个 IP Camera 的固件里,发现 /etc/init.d/rcS 脚本里有一行:
telnetd -l /bin/sh -p 2323
嗯,这就是一个典型的调试后门。Telnet 服务默认开启,端口 2323,而且不需要认证。你想想看,如果这个设备暴露在公网上,后果是什么?
3.4 知识体系图
下面这张图,是我自己总结的固件文件系统分析流程。你可以把它当作一个检查清单:
这张图的核心逻辑就是:拿到固件 → 识别文件系统 → 挂载提取 → 找关键文件 → 开始挖洞。每一步都有对应的工具和技巧,后面我们会逐一展开。
- Squashfs 是最常见的,优先掌握
unsquashfs和binwalk。 - JFFS2 用
jefferson工具,Cramfs 用cramfsck。 - 关键文件就三个:
/etc/passwd、/etc/shadow、配置文件。 - 别忽略启动脚本,后门经常藏在那里。
好了,文件系统分析这块就聊到这儿。记住,这一步是固件漏洞挖掘的基石。地基打不牢,后面全是白费功夫。
公众号:蓝海资料掘金营,微信deep3321