2. 固件解包基础

任务目标

给定一个路由器固件镜像文件,使用binwalk自动识别并提取其中嵌入的文件系统(如SquashFS、CramFS、JFFS2),最终获得完整的根文件系统目录结构,为后续固件逆向分析提供基础。

环境准备

  • 操作系统:Ubuntu 22.04 LTS(或Kali Linux)
  • 安装工具:sudo apt-get install binwalk(binwalk v2.3.3+)
  • 如需解压SquashFS,安装:sudo apt-get install squashfs-tools
  • 测试固件:从路由器厂商官网下载固件,或使用公开的测试固件(如D-Link DIR-850L固件,约10MB)

核心实现

binwalk提供两种解包方式:binwalk -e自动提取模式(调用外部解压工具递归解包),以及binwalk --dd手动提取指定类型文件。以下脚本封装了完整的固件解包流程,包含文件系统类型识别、自动提取和结果验证:

#!/bin/bash
# firmware_extract.sh - 固件自动解包脚本
# 用法: ./firmware_extract.sh <固件文件路径>

set -e

FIRMWARE="$1"
if [ -z "$FIRMWARE" ] || [ ! -f "$FIRMWARE" ]; then
    echo "错误: 请提供有效的固件文件路径"
    exit 1
fi

OUTPUT_DIR="firmware_extracted_$(date +%Y%m%d_%H%M%S)"
mkdir -p "$OUTPUT_DIR"

echo "[1/4] 扫描固件中的文件签名..."
binwalk "$FIRMWARE" | tee "$OUTPUT_DIR/binwalk_scan.txt"

echo "[2/4] 自动提取所有可识别文件..."
# -e: 自动提取; -M: 递归扫描提取出的文件; -d: 指定输出目录
binwalk -e -M -d "$OUTPUT_DIR" "$FIRMWARE" 2>&1 | tail -20

echo "[3/4] 定位文件系统目录..."
# 查找binwalk提取出的文件系统根目录(通常包含bin/, etc/, usr/等目录)
FS_ROOT=$(find "$OUTPUT_DIR" -type d -name "squashfs-root" -o -type d -name "rootfs" | head -1)

if [ -z "$FS_ROOT" ]; then
    # 若未找到标准目录名,尝试查找包含典型Linux目录结构的目录
    FS_ROOT=$(find "$OUTPUT_DIR" -type d -exec test -d "{}/bin" \; -exec test -d "{}/etc" \; -print | head -1)
fi

if [ -z "$FS_ROOT" ]; then
    echo "[!] 警告: 未自动识别到文件系统根目录,尝试手动提取..."
    # 从扫描结果中查找SquashFS/CramFS偏移量
    OFFSET=$(grep -E "Squashfs|Cramfs|JFFS2" "$OUTPUT_DIR/binwalk_scan.txt" | head -1 | awk '{print $1}')
    if [ -n "$OFFSET" ]; then
        echo "    在偏移量 0x$OFFSET 处发现文件系统,手动提取..."
        dd if="$FIRMWARE" of="$OUTPUT_DIR/fs_image.bin" bs=1 skip=$((16#$OFFSET)) 2>/dev/null
        cd "$OUTPUT_DIR"
        binwalk -e fs_image.bin
        cd ..
        FS_ROOT=$(find "$OUTPUT_DIR" -type d -name "squashfs-root" | head -1)
    fi
fi

if [ -n "$FS_ROOT" ]; then
    echo "[4/4] 解包成功!文件系统位于: $FS_ROOT"
    echo "关键目录内容预览:"
    ls -la "$FS_ROOT/etc" 2>/dev/null | head -10
    echo ""
    echo "文件系统总大小: $(du -sh "$FS_ROOT" | cut -f1)"
else
    echo "[4/4] 解包失败,请检查固件格式或手动分析binwalk扫描结果"
    exit 1
fi

运行与验证

  1. 保存脚本并添加执行权限:chmod +x firmware_extract.sh
  2. 运行解包:./firmware_extract.sh firmware.bin
  3. 验证通过条件:
  • 脚本输出包含解包成功字样
  • binwalk_scan.txt中显示SquashFS或CramFS等文件系统签名
  • 提取出的文件系统目录中包含/bin、/etc、/usr等标准Linux目录
  • 可查看关键配置文件,如cat <FS_ROOT>/etc/passwd能正常输出内容

常见问题

  • binwalk未识别文件系统:部分固件使用自定义加密或头部混淆,需先用binwalk -A尝试熵分析,或使用binwalk -X指定文件类型
  • 解压后文件系统不完整:某些固件包含多个文件系统分区,需检查binwalk扫描结果中是否有多个SquashFS签名,分别提取
  • 权限错误:解包过程需要写权限,建议在用户目录下操作而非系统目录

预期输出示例(基于D-Link DIR-850L固件):扫描结果中偏移量0x1A0000处发现Squashfs filesystem, little endian, version 4.0,提取后得到squashfs-root目录,其中包含bin/、etc/、lib/、usr/等标准目录,/etc/passwd文件可正常读取。