3. 固件解包与文件系统提取

任务说明

本案例目标是从一个固件镜像中识别并提取其文件系统(以SquashFS为例),最终挂载或解压以查看内部文件。你将学习如何通过文件特征判断文件系统类型,并使用工具完成提取与内容访问。

环境准备

需要Linux环境(推荐Ubuntu/Debian),并安装以下工具:

sudo apt-get update
sudo apt-get install -y binwalk squashfs-tools

binwalk用于固件结构扫描,squashfs-tools提供unsquashfs用于解压SquashFS镜像。

固件样本准备

为便于演示,我们构造一个最小但真实的SquashFS固件镜像作为输入。以下命令创建一个包含若干文件的SquashFS镜像:

mkdir -p rootfs/{etc,usr/bin,var/log}
echo "version=1.0" > rootfs/etc/version.conf
echo "#!/bin/sh" > rootfs/usr/bin/hello.sh
echo 'echo "Hello from firmware"' >> rootfs/usr/bin/hello.sh
chmod +x rootfs/usr/bin/hello.sh
echo "boot log" > rootfs/var/log/messages
mksquashfs rootfs firmware.squashfs -noappend -comp xz

执行后得到firmware.squashfs,即待分析的固件文件。

固件解包与文件系统提取

使用binwalk扫描固件,识别文件系统偏移量,然后提取并解压:

binwalk firmware.squashfs

预期输出(示例):

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             SquashFS filesystem, little endian, version 4.0, compression:xz, size: 4096 bytes, 4 inodes, blocksize: 131072 bytes, created: ...

由于本例中SquashFS从偏移0开始,可直接解压:

unsquashfs -d extracted_rootfs firmware.squashfs

若文件系统不在偏移0处(例如前面有引导头),需先使用dd按偏移切割:

dd if=firmware.bin of=rootfs.squashfs bs=1 skip=<偏移量> status=progress
unsquashfs -d extracted_rootfs rootfs.squashfs

验证方法与判定标准

解压完成后,检查提取出的文件是否完整且内容正确:

ls -la extracted_rootfs/
cat extracted_rootfs/etc/version.conf
cat extracted_rootfs/usr/bin/hello.sh

判定通过条件:

  1. extracted_rootfs目录下存在etc/version.conf、usr/bin/hello.sh、var/log/messages三个文件;
  2. cat extracted_rootfs/etc/version.conf输出version=1.0;
  3. cat extracted_rootfs/usr/bin/hello.sh内容与构造时一致。

若需挂载查看(需root权限),可执行:

sudo mount -t squashfs -o loop firmware.squashfs /mnt/fw
ls /mnt/fw
sudo umount /mnt/fw

常见问题

  • binwalk未识别文件系统:确认固件确实包含SquashFS;若为CramFS,使用fsck.cramfs或cramfsck工具提取。
  • unsquashfs报错“Unknown compression”:安装squashfs-tools后仍缺压缩库,执行sudo apt-get install -y liblz4-tool zstd补齐。
  • 偏移量不为0:binwalk输出中SquashFS描述行的DECIMAL列即为偏移量,用dd切割后再解压。