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 密钥登录)。
验证方法与判定标准
- 解包验证:
squashfs-root目录存在且包含完整的etc/、usr/、www/目录结构,即判定 SquashFS 提取成功。 - JFFS2 验证:
jffs2-root目录中能读取到创建测试镜像时写入的etc/config/system文件且内容一致,即判定 jefferson 提取成功。 - 内容分析验证:成功定位到
uhttpd可执行文件及其配置文件,并能从配置中读出 HTTP 监听端口(默认 80)和网页根目录路径(默认/www)。
常见问题
- binwalk 无法识别文件系统:部分固件使用自定义头部或加密,需先运行
binwalk -A进行熵分析确认是否有加密;若为普通固件,尝试binwalk --dd='.*'强制提取。 - jefferson 报错:确认已安装
python3-pip及依赖cstruct,若仍失败可尝试pip3 install --upgrade jefferson。 - SquashFS 版本过新:老版本 binwalk 可能无法解包新版 SquashFS,升级 binwalk 至最新版即可。