2. 固件解包与文件系统提取

任务目标

对一个包含 JFFS2 文件系统的路由器固件镜像进行解包,提取其中的文件系统内容,并定位关键配置文件与 Web 服务程序,为后续固件分析建立基础。

环境准备

在 Ubuntu 22.04 或 Kali Linux 中安装以下工具:

sudo apt update
sudo apt install -y binwalk mtd-utils
pip3 install jefferson

固件样本获取

本案例使用 OpenWrt 官方发布的 WNDR3800 固件作为分析对象(该固件包含 JFFS2 文件系统,且体积小、结构清晰,适合教学):

wget https://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/nand/wndr3800-squashfs.bin

固件结构扫描

首先使用 binwalk 扫描固件内部结构,确定文件系统偏移位置:

binwalk wndr3800-squashfs.bin

预期输出中应包含类似以下关键行(具体偏移以实际扫描为准):

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             DLOB header
...
262144        0x40000         Squashfs filesystem, little endian, version 4.0

提取 SquashFS 根文件系统

使用 binwalk 的提取功能,自动解包 SquashFS 部分:

binwalk -Me wndr3800-squashfs.bin

该命令会在当前目录生成 _wndr3800-squashfs.bin.extracted 文件夹,其中包含解包后的 SquashFS 根目录。进入该目录确认提取结果:

cd _wndr3800-squashfs.bin.extracted
ls -la

应能看到 squashfs-root 目录,其中包含 etc/、usr/、www/ 等标准 Linux 目录结构。

JFFS2 文件系统提取

OpenWrt 的 NAND 固件通常在 SquashFS 之外还包含一个 JFFS2 分区用于存放可写配置。为演示 JFFS2 提取流程,我们使用一个独立的 JFFS2 镜像进行练习:

# 创建一个测试用 JFFS2 镜像(仅用于教学演示)
mkdir -p jffs2-test/etc jffs2-test/usr/bin
echo "root:x:0:0:root:/root:/bin/ash" > jffs2-test/etc/passwd
echo "option hostname 'OpenWrt'" > jffs2-test/etc/config/system
mkfs.jffs2 -d jffs2-test -o test.jffs2 -e 0x20000

# 使用 jefferson 提取 JFFS2 镜像
jefferson test.jffs2

jefferson 会在当前目录生成 jffs2-root 文件夹,其中包含原始文件内容。验证提取结果:

cat jffs2-root/etc/config/system

预期输出:

option hostname 'OpenWrt'

文件系统内容分析

回到 SquashFS 提取结果,定位关键分析目标:

cd squashfs-root

# 查看 Web 服务程序
ls -la usr/sbin/ | grep -E "http|uhttpd"

# 查看默认配置
cat etc/config/uhttpd 2>/dev/null || cat etc/uhttpd.conf 2>/dev/null

# 查找密码哈希
grep -r "root:" etc/shadow 2>/dev/null

# 列出 Web 根目录
ls -la www/

通过上述命令,应能定位到 uhttpd Web 服务器可执行文件、其监听端口与页面路径配置,以及 root 用户的密码哈希(通常为 * 或空,表示仅允许通过 SSH 密钥登录)。

验证方法与判定标准

  1. 解包验证:squashfs-root 目录存在且包含完整的 etc/、usr/、www/ 目录结构,即判定 SquashFS 提取成功。
  2. JFFS2 验证:jffs2-root 目录中能读取到创建测试镜像时写入的 etc/config/system 文件且内容一致,即判定 jefferson 提取成功。
  3. 内容分析验证:成功定位到 uhttpd 可执行文件及其配置文件,并能从配置中读出 HTTP 监听端口(默认 80)和网页根目录路径(默认 /www)。

常见问题

  • binwalk 无法识别文件系统:部分固件使用自定义头部或加密,需先运行 binwalk -A 进行熵分析确认是否有加密;若为普通固件,尝试 binwalk --dd='.*' 强制提取。
  • jefferson 报错:确认已安装 python3-pip 及依赖 cstruct,若仍失败可尝试 pip3 install --upgrade jefferson。
  • SquashFS 版本过新:老版本 binwalk 可能无法解包新版 SquashFS,升级 binwalk 至最新版即可。