3、固件文件系统分析:常见文件系统(Squashfs、JFFS2、Cramfs)、文件系统挂载与遍历、关键文件识别

拿到固件之后,第一件事是什么?

我个人习惯,不是急着去逆向,也不是去跑什么自动化工具。而是先看看它的文件系统长什么样。说白了,固件里的文件系统,就是整个设备的“硬盘”。里面藏着配置文件、密码、启动脚本、甚至后门。你想想看,如果连这个都摸不清楚,后面的漏洞挖掘基本就是瞎蒙。

3.1 常见文件系统:Squashfs、JFFS2、Cramfs

嵌入式设备里,文件系统种类其实不多。我这些年挖过的固件,90%以上就这三种:SquashfsJFFS2Cramfs。它们各有各的脾气。

文件系统 特点 压缩方式 常见场景
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 文件系统挂载与遍历

拿到固件后,怎么把文件系统“拆开”?

我一般分三步走:

  1. 识别文件系统类型——用 binwalk 或者 file 命令看一眼。
  2. 提取文件系统——用 binwalk -e 或者 unsquashfs 等专用工具。
  3. 挂载并遍历——如果提取失败,就手动挂载。

举个例子,假设你有一个固件 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/passwdetc/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 JFFS2 Cramfs 挂载 / 提取文件系统 关键文件识别(passwd/shadow/配置) 漏洞挖掘

这张图的核心逻辑就是:拿到固件 → 识别文件系统 → 挂载提取 → 找关键文件 → 开始挖洞。每一步都有对应的工具和技巧,后面我们会逐一展开。

核心要点:
  • Squashfs 是最常见的,优先掌握 unsquashfsbinwalk
  • JFFS2 用 jefferson 工具,Cramfs 用 cramfsck
  • 关键文件就三个:/etc/passwd/etc/shadow、配置文件。
  • 别忽略启动脚本,后门经常藏在那里。

好了,文件系统分析这块就聊到这儿。记住,这一步是固件漏洞挖掘的基石。地基打不牢,后面全是白费功夫。


公众号:蓝海资料掘金营,微信deep3321