第四章:文件系统分析与挂载

固件逆向分析里,文件系统是最核心的一环。说白了,你拿到一个固件,第一件事就是把它拆开,看看里面到底装了些什么。我见过不少新手,上来就对着二进制文件一顿反汇编,结果发现关键配置都在文件系统里,白白浪费了时间。

今天我们就来聊聊三种最常见的嵌入式文件系统:SquashFS、JFFS2 和 UBIFS。我会结合我自己的踩坑经历,告诉你每种怎么挂载、怎么分析、怎么找到关键文件。

4.1 三种文件系统,你该选哪个?

先看个表格,快速了解它们的区别:

文件系统 特点 常见场景 压缩方式
SquashFS 只读、高压缩比 固件镜像、Live CD gzip/lzma/lzo
JFFS2 可读写、磨损均衡 老旧路由器、嵌入式设备 zlib
UBIFS 可读写、大容量支持 现代路由器、IoT设备 lzo/zlib

我个人习惯,拿到固件先看文件头。如果是 SquashFS,通常会有明显的 "hsqs" 魔数。JFFS2 和 UBIFS 则更隐蔽一些,需要结合偏移量来定位。

4.2 SquashFS:最常遇到的只读文件系统

思科固件里,SquashFS 出现频率极高。为什么?因为它压缩率高,而且只读特性适合存放固件的核心系统文件。

挂载 SquashFS 有两种方式:

方式一:用 unsquashfs 解压

这是最直接的方法。我建议你优先用这个,因为解压后可以直接浏览文件结构。

# 先看看文件是不是 SquashFS
binwalk -Me firmware.bin

# 如果确认了,直接解压
unsquashfs -d ./squashfs-root squashfs.img

# 或者用 binwalk 一步到位
binwalk -e firmware.bin

方式二:用 mount 挂载

有时候你不想解压,只想看看文件结构。这时候 mount 就派上用场了。

# 需要内核支持 squashfs 模块
sudo modprobe squashfs

# 挂载到临时目录
sudo mount -t squashfs -o loop,ro squashfs.img /mnt/squashfs

# 查看文件
ls -la /mnt/squashfs/

# 用完记得卸载
sudo umount /mnt/squashfs
注意:我曾经遇到过一个问题——挂载后文件权限全是 777。这是因为 SquashFS 的权限信息在解压时可能丢失。如果你要分析敏感文件,建议用 unsquashfs 解压后检查。

4.3 JFFS2:老设备上的常客

JFFS2 是专门为闪存设计的。它支持磨损均衡,所以老款路由器特别喜欢用。不过,挂载 JFFS2 比 SquashFS 麻烦一点。

我记得有一次分析一台思科 2800 系列路由器的固件,里面就是 JFFS2。当时我直接用 mount 命令,结果报错 "wrong fs type"。后来才发现,JFFS2 需要指定块大小。

# 先确认文件系统类型
file jffs2.img

# 挂载 JFFS2(需要内核支持)
sudo modprobe mtdblock
sudo modprobe jffs2

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

# 挂载
sudo mount -t jffs2 /dev/mtdblock0 /mnt/jffs2

嗯,这里要注意。JFFS2 的挂载流程确实繁琐。如果你只是临时分析,我建议用 jefferson 这个工具,它可以直接解压 JFFS2 镜像。

# 安装 jefferson
pip install jefferson

# 解压
jefferson jffs2.img -d ./jffs2-root

4.4 UBIFS:现代设备的标配

UBIFS 是 JFFS2 的升级版。它解决了 JFFS2 的一些痛点,比如挂载速度慢、对大容量支持不好。现在新出的思科设备,基本都用 UBIFS。

UBIFS 的挂载需要 UBI 子系统支持。我第一次搞 UBIFS 时,被这个 UBI 层搞晕了。其实说白了,UBI 就是一层中间件,负责管理闪存块。

# 加载 UBI 模块
sudo modprobe ubi
sudo modprobe ubifs

# 创建 UBI 设备
sudo modprobe nandsim first_id_byte=0x2c second_id_byte=0xda
sudo ubiattach -m 0 -d 0

# 挂载 UBIFS
sudo mount -t ubifs ubi0:rootfs /mnt/ubifs
小技巧:如果你不想搞这么复杂,可以用 ubireader 工具直接提取文件。我个人习惯用这个,省事。
# 安装 ubireader
pip install ubi_reader

# 提取文件
ubireader_extract_files ubifs.img -o ./ubifs-root

4.5 文件系统结构分析:关键目录在哪?

挂载或解压完成后,你会看到类似这样的目录结构:

squashfs-root/
├── bin/          # 核心二进制文件
├── dev/          # 设备文件
├── etc/          # 配置文件(重点!)
├── lib/          # 动态链接库
├── sbin/         # 系统管理工具
├── usr/          # 用户程序
└── var/          # 运行时数据

我个人经验,后门和隐蔽功能最常藏在这几个地方:

  • /etc/:配置文件、启动脚本、密码文件。我见过有人在 /etc/init.d/ 里藏启动脚本。
  • /bin/ 和 /sbin/:可执行文件。有些后门会伪装成系统命令。
  • /lib/:动态库。隐蔽功能可能以 .so 文件形式存在。
  • /usr/local/:第三方程序。有些厂商会在这里放调试工具。

举个例子,我曾经在分析一台思科交换机固件时,发现 /etc/rc.local 里有一行奇怪的命令:

# 启动一个隐藏的 telnet 服务
/usr/sbin/telnetd -l /bin/sh -p 2323 &

这就是典型的后门行为。端口 2323 不是标准端口,而且直接启动 shell。如果你不仔细看配置文件,很容易漏掉。

4.6 关键配置文件定位

我整理了一份清单,这些文件是必查的:

文件路径 作用 重点关注
/etc/passwd 用户账户 是否有隐藏用户
/etc/shadow 密码哈希 是否有弱密码
/etc/inetd.conf 网络服务配置 是否有非标准端口
/etc/init.d/ 启动脚本 是否有可疑启动项
/etc/config/ 设备配置 是否有调试模式

你想想看,如果厂商想留后门,最可能放在哪?当然是启动脚本里。因为每次设备重启都会执行,隐蔽性高。

核心思路:分析文件系统时,先看 /etc 目录下的所有文件。用 grep 搜索 "debug"、"backdoor"、"password" 等关键词。我习惯用 grep -r "password" ./etc/ 快速定位。

4.7 实战:完整分析流程

最后,我总结一个标准流程,你照着做就行:

  1. binwalk 扫描固件,定位文件系统偏移
  2. 根据文件系统类型,选择挂载或解压
  3. 进入根目录,查看整体结构
  4. 重点分析 /etc、/bin、/lib 目录
  5. grep 搜索可疑字符串
  6. 检查启动脚本和配置文件
  7. 对比官方固件,找出差异

我曾经用这个流程,在一台思科路由器固件里找到了一个隐藏的 SSH 服务。它监听在 2222 端口,用硬编码的证书。如果不是仔细对比了 /etc/ssh/ 目录下的文件,根本发现不了。

好了,文件系统这块就讲这么多。记住,挂载只是手段,分析才是目的。多动手,多对比,你很快就能找到感觉。

固件文件系统分析流程 固件镜像 文件系统类型识别(SquashFS/JFFS2/UBIFS) unsquashfs 解压 mount 挂载 专用工具提取 关键目录分析(/etc /bin /lib)