2. 固件解包与重打包
任务目标
使用 binwalk 解包一个 IoT 固件镜像,定位并修改其中的一个文件(如 Web 服务配置或启动脚本),随后使用 binwalk 的 -e 配合手动重打包或 firmware-mod-kit 完成固件重组,最后通过校验文件哈希与文件系统挂载测试验证固件完整性。
环境与依赖
- 操作系统:Ubuntu 22.04+(或 Kali Linux)
- 工具:
binwalk、sasquatch(SquashFS 解包)、mksquashfs、cpio、file、sha256sum - 安装命令:
sudo apt install binwalk mksquashfs cpio;SquashFS 工具链若缺失,需从 sasquatch 源码编译
固件准备
本案例使用一个合成的演示固件 demo_router.bin(约 2MB),其内部包含一个 SquashFS 文件系统和一个内核镜像。若你手头有真实固件,可直接替换路径;以下步骤对大多数基于 SquashFS 的固件同样适用。
关键完整代码
以下脚本完成解包、修改、重打包与验证的完整闭环:
#!/bin/bash
# firmware_repack_demo.sh
set -euo pipefail
FW="demo_router.bin"
EXTRACT_DIR="fw_extracted"
ROOTFS_DIR="rootfs"
MODIFIED_FILE="etc/config/product_info"
NEW_VALUE="product_name=DemoRouter-Pro"
# 1. 解包固件
rm -rf "$EXTRACT_DIR" "$ROOTFS_DIR"
binwalk -e "$FW" -C "$EXTRACT_DIR" > /dev/null
# 定位 SquashFS 根目录(自动探测)
ROOTFS_SRC=$(find "$EXTRACT_DIR" -type d -name "squashfs-root" | head -1)
if [ -z "$ROOTFS_SRC" ]; then
echo "错误:未找到 SquashFS 根目录"
exit 1
fi
cp -r "$ROOTFS_SRC" "$ROOTFS_DIR"
# 2. 修改目标文件(追加一行配置)
echo "$NEW_VALUE" >> "$ROOTFS_DIR/$MODIFIED_FILE"
echo "已修改: $MODIFIED_FILE"
# 3. 重打包为新的 SquashFS 镜像
mksquashfs "$ROOTFS_DIR" new_rootfs.squashfs -comp xz -b 131072 > /dev/null
# 4. 重建完整固件(保留原内核与头部)
# 提取原固件中 SquashFS 的偏移量
FW_OFFSET=$(binwalk "$FW" | grep "SquashFS" | awk '{print $1}')
if [ -z "$FW_OFFSET" ]; then
echo "错误:无法定位 SquashFS 偏移"
exit 1
fi
FW_OFFSET_DEC=$((16#${FW_OFFSET//:/}))
# 拆分:头部(含内核) + 新文件系统
head -c "$FW_OFFSET_DEC" "$FW" > fw_header.bin
cat fw_header.bin new_rootfs.squashfs > repacked_fw.bin
# 5. 验证完整性
echo "=== 验证 ==="
echo "原固件 SHA256:"
sha256sum "$FW" | awk '{print $1}'
echo "重打包固件 SHA256:"
sha256sum repacked_fw.bin | awk '{print $1}'
# 重新解包验证修改是否生效
binwalk -e repacked_fw.bin -C verify_extract > /dev/null
VERIFY_ROOT=$(find verify_extract -type d -name "squashfs-root" | head -1)
if grep -q "$NEW_VALUE" "$VERIFY_ROOT/$MODIFIED_FILE"; then
echo "✅ 验证通过:修改内容已存在于重打包固件中"
else
echo "❌ 验证失败:修改内容未生效"
exit 1
fi
# 清理临时文件
rm -rf verify_extract fw_header.bin new_rootfs.squashfs
echo "完成"
运行方式
- 将上述脚本保存为
firmware_repack_demo.sh,并放置与demo_router.bin同目录。 - 赋予执行权限并运行:
chmod +x firmware_repack_demo.sh && ./firmware_repack_demo.sh
验证方法与判定标准
- 解包成功标志:脚本执行后,
fw_extracted/目录下出现squashfs-root文件夹,且内部包含etc/、bin/等标准 Linux 目录结构。 - 修改生效标志:脚本输出
✅ 验证通过,表示重打包后的固件中确实包含新增的配置行。 - 完整性判定:重打包固件可被
binwalk正常识别并解包,且文件系统可挂载(可选执行mount -o loop repacked_fw.bin /mnt/test检查)。 - 哈希差异说明:由于文件内容已改变,重打包固件的 SHA256 必然与原固件不同,这是预期行为;完整性验证的核心是文件系统结构可解析、修改内容可检索。
常见问题
- SquashFS 版本不兼容:若
binwalk -e解包失败,尝试binwalk -e -M或手动指定偏移dd if=demo_router.bin of=root.squashfs bs=1 skip=$((16#偏移量))后用unsquashfs解包。 - 固件包含多个文件系统:部分固件含 CramFS、JFFS2 等,需根据
binwalk输出选择目标文件系统;本案例仅针对 SquashFS。 - 头部校验:某些引导程序会校验固件头部的 CRC 或长度字段,此时需额外修改头部校验值,本案例演示固件未启用该校验。