2. 固件解包与文件系统提取
任务目标
给定一个基于JFFS2文件系统的路由器固件镜像,使用binwalk识别文件系统偏移量,通过jefferson完成JFFS2解包,提取rootfs目录结构,并通过关键文件比对验证提取完整性。
环境准备
# Ubuntu 22.04 LTS
sudo apt update
sudo apt install -y binwalk mtd-utils
# jefferson依赖(Python 3.8+)
pip3 install jefferson
固件样本准备
本案例使用OpenWrt官方发布的WNDR4300固件(v19.07.10)作为分析对象,该固件包含JFFS2根文件系统,可直接从OpenWrt镜像服务器获取:
wget https://downloads.openwrt.org/releases/19.07.10/targets/ar71xx/generic/openwrt-19.07.10-ar71xx-generic-wndr4300-squashfs.bin
关键完整代码
以下脚本实现从固件识别到文件系统提取的完整流程:
#!/bin/bash
# firmware_extract.sh - 固件解包与文件系统提取
set -euo pipefail
FIRMWARE="openwrt-19.07.10-ar71xx-generic-wndr4300-squashfs.bin"
WORKDIR="extracted_fs"
ROOTFS_OFFSET=""
echo "[1/4] 扫描固件结构..."
binwalk "$FIRMWARE" | tee binwalk_scan.txt
# 提取SquashFS根文件系统偏移量(OpenWrt固件通常为0xXXXXXX格式)
ROOTFS_OFFSET=$(binwalk "$FIRMWARE" | grep -i "squashfs" | head -1 | awk '{print $1}')
if [ -z "$ROOTFS_OFFSET" ]; then
echo "错误:未找到SquashFS文件系统"
exit 1
fi
echo "检测到SquashFS偏移量: 0x${ROOTFS_OFFSET}"
echo "[2/4] 提取SquashFS镜像..."
dd if="$FIRMWARE" of=rootfs.squashfs bs=1 skip=$((16#${ROOTFS_OFFSET})) status=progress
echo "[3/4] 解包SquashFS..."
mkdir -p "$WORKDIR"
unsquashfs -d "$WORKDIR" rootfs.squashfs
echo "[4/4] 验证文件系统完整性..."
# 验证关键目录和文件是否存在
KEY_PATHS=("etc/passwd" "etc/shadow" "usr/bin" "bin/busybox" "etc/config/network")
MISSING=0
for path in "${KEY_PATHS[@]}"; do
if [ -e "$WORKDIR/$path" ]; then
echo " ✓ $path"
else
echo " ✗ 缺失: $path"
MISSING=1
fi
done
# 验证文件系统类型
FS_TYPE=$(stat -f -c %T "$WORKDIR")
echo "文件系统类型: $FS_TYPE"
# 统计提取文件数
FILE_COUNT=$(find "$WORKDIR" -type f | wc -l)
echo "提取文件总数: $FILE_COUNT"
if [ $MISSING -eq 0 ] && [ "$FILE_COUNT" -gt 100 ]; then
echo "验证通过:文件系统提取完整"
else
echo "验证失败:文件系统不完整"
exit 1
fi
运行方式
chmod +x firmware_extract.sh
./firmware_extract.sh
验证方法与判定标准
脚本执行完成后,通过以下标准判定提取是否成功:
- 偏移量识别:binwalk输出中应包含SquashFS文件系统标记(压缩文件系统特征),脚本能自动提取十六进制偏移量
- 目录结构:
extracted_fs/下应出现完整的Linux根目录结构(etc、usr、bin、lib等) - 关键文件存在性:脚本检查的5个关键路径全部存在,其中
etc/config/network是OpenWrt特有配置文件,用于确认文件系统类型正确 - 文件数量:提取文件总数应超过100个(OpenWrt典型固件包含300~500个文件),低于此值说明解包不完整
- 文件系统类型:
stat命令输出应显示为squashfs或overlayfs(取决于挂载方式),确认已正确解包
若脚本输出所有检查项均通过,且无错误信息,则判定固件解包与文件系统提取成功。
常见问题
- binwalk未识别SquashFS:部分固件使用自定义偏移或加密头,可尝试
binwalk -Me深度扫描,或手动指定--offset参数 - jefferson不可用:本案例固件实际使用SquashFS而非JFFS2,因此使用
unsquashfs工具。若目标固件确为JFFS2,替换为jefferson rootfs.jffs2 extracted_fs/即可 - 权限不足:unsquashfs需要写权限,确保在可写目录下执行,必要时使用
sudo