2. 固件解包与文件系统提取
任务目标
给定一个路由器固件镜像(router_fw.bin),使用 binwalk 识别并提取其中嵌入的文件系统(SquashFS),随后验证提取结果的文件类型与目录结构完整性。
环境与依赖
- 操作系统:Ubuntu 22.04 / Kali Linux(或任何支持 binwalk 的 Linux 发行版)
- 工具:
binwalk(v2.3.3+)、sasquatch(非标准 SquashFS 解包工具)、file、unsquashfs - 安装命令:
sudo apt update && sudo apt install -y binwalk file squashfs-tools # 若固件使用非标准 SquashFS(如 D-Link、TP-Link 部分型号),需额外安装: git clone https://github.com/devttys0/sasquatch.git && cd sasquatch && sudo ./build.sh
关键完整代码(解包与验证脚本)
#!/bin/bash
# firmware_extract.sh - 固件解包与文件系统提取验证
set -euo pipefail
FW_IMAGE="router_fw.bin"
EXTRACT_DIR="fw_extracted"
SQUASH_OFFSET=""
# 1. 扫描固件中的嵌入式文件签名
echo "[*] 扫描固件签名..."
binwalk "$FW_IMAGE" | tee binwalk_scan.txt
# 2. 自动提取所有可识别文件(含 SquashFS)
echo "[*] 使用 binwalk 自动提取..."
binwalk -e -M -C "$EXTRACT_DIR" "$FW_IMAGE"
# 3. 定位 SquashFS 文件系统偏移量(从扫描结果中解析)
SQUASH_OFFSET=$(grep -i "squashfs" binwalk_scan.txt | head -1 | awk '{print $1}')
if [ -z "$SQUASH_OFFSET" ]; then
echo "[!] 未检测到 SquashFS,尝试手动搜索..."
SQUASH_OFFSET=$(binwalk "$FW_IMAGE" | grep -i "filesystem" | head -1 | awk '{print $1}')
fi
if [ -z "$SQUASH_OFFSET" ]; then
echo "[!] 无法定位文件系统偏移量,退出"
exit 1
fi
echo "[*] SquashFS 偏移量: 0x${SQUASH_OFFSET}"
# 4. 从原始固件中切割出 SquashFS 镜像
dd if="$FW_IMAGE" of="squashfs_raw.img" bs=1 skip=$((16#$SQUASH_OFFSET)) 2>/dev/null
# 5. 使用 unsquashfs 或 sasquatch 解包
echo "[*] 尝试 unsquashfs 解包..."
if unsquashfs -d "$EXTRACT_DIR/rootfs" squashfs_raw.img 2>&1 | grep -q "ERROR"; then
echo "[*] unsquashfs 失败,尝试 sasquatch..."
sasquatch -d "$EXTRACT_DIR/rootfs" squashfs_raw.img
fi
# 6. 验证提取结果
echo ""
echo "[*] 验证文件系统类型:"
file "$EXTRACT_DIR/rootfs/bin/busybox" 2>/dev/null || file "$EXTRACT_DIR/rootfs/bin/sh"
echo ""
echo "[*] 验证关键目录结构:"
for dir in bin etc lib usr var home root tmp; do
if [ -d "$EXTRACT_DIR/rootfs/$dir" ]; then
echo " [✓] /$dir 存在"
else
echo " [✗] /$dir 缺失"
fi
done
echo ""
echo "[*] 验证关键文件:"
for f in etc/passwd etc/init.d/rcS bin/busybox; do
if [ -e "$EXTRACT_DIR/rootfs/$f" ]; then
echo " [✓] /$f 存在 ($(stat -c%s "$EXTRACT_DIR/rootfs/$f") bytes)"
else
echo " [✗] /$f 缺失"
fi
done
echo ""
echo "[*] 提取完成。根文件系统位于: $EXTRACT_DIR/rootfs/"
运行方式
chmod +x firmware_extract.sh
./firmware_extract.sh
验证方法与判定标准
脚本执行后,按以下标准判定是否成功:
- 签名识别:
binwalk_scan.txt中应包含SquashFS filesystem或filesystem条目,且偏移量非空。 - 解包结果:
fw_extracted/rootfs/目录存在且非空。 - 文件类型:
file命令输出显示 ELF 可执行文件(如bin/busybox为 ELF 32-bit ARM 或 MIPS 可执行文件),证明提取的是真实可执行文件系统而非空目录。 - 目录完整性:脚本输出中
/bin、/etc、/lib、/usr等关键目录均标记[✓]。 - 关键文件:
/etc/passwd、/etc/init.d/rcS、/bin/busybox均存在且大小非零。
若以上条件全部满足,则固件解包与文件系统提取成功,且完整性验证通过。
常见问题
- binwalk 未识别 SquashFS:部分厂商(如 D-Link)使用非标准 SquashFS 头,需安装
sasquatch后重新扫描。 - unsquashfs 报错:若报
ERROR: Superblock magic is wrong,说明偏移量不正确或文件系统被加密/压缩,改用sasquatch或手动检查偏移量。 - 提取后 busybox 无法执行:这是交叉编译固件的正常现象,需使用对应架构的
qemu-arm-static或qemu-mips-static进行 chroot 执行,不影响文件系统提取的完整性验证。