1. 固件文件类型识别

固件文件类型识别 学习卡片

任务目标

给定一个未知格式的固件文件(例如从路由器、IoT设备或开发板中提取的.bin文件),通过文件签名(magic bytes)和文件结构特征,识别其真实文件类型(如Uboot镜像、TRX、Squashfs文件系统、gzip压缩数据等),为后续固件解包与分析建立基础。

前置知识

固件文件通常不是单一文件,而是由引导加载程序(Bootloader)、内核、文件系统等多个部分拼接而成。识别文件类型的关键在于检查文件头部字节(magic bytes)以及文件内部的结构特征。本案例使用Linux标准工具file、binwalk和hexdump完成识别,不涉及自定义脚本。

环境准备

在Ubuntu/Debian系统上安装必要工具:

sudo apt update
sudo apt install file binwalk xxd

实现步骤

本案例使用一个合成的示例固件文件sample_fw.bin,该文件由gzip压缩的Squashfs文件系统构成,并在头部附加了64字节的Uboot头部信息。通过以下命令逐步识别其类型。

步骤1:创建示例固件文件

# 创建一个小的Squashfs文件系统(需要root权限)
mkdir -p rootfs_test
echo "hello firmware" > rootfs_test/hello.txt
sudo mksquashfs rootfs_test rootfs.squashfs -noappend -comp gzip

# 创建Uboot风格的头部(64字节,魔数为0x27051956)
dd if=/dev/zero of=uboot_header.bin bs=64 count=1
printf '\x27\x05\x19\x56' | dd of=uboot_header.bin conv=notrunc

# 拼接头部和文件系统
cat uboot_header.bin rootfs.squashfs > sample_fw.bin
rm -rf rootfs_test uboot_header.bin rootfs.squashfs

步骤2:使用file命令进行初步识别

file sample_fw.bin

预期输出:sample_fw.bin: data(因为file命令无法识别自定义的Uboot头部,会将其视为普通数据)。

步骤3:使用hexdump检查文件头部

xxd sample_fw.bin | head -5

预期输出(前16字节):

00000000: 2705 1956 0000 0000 0000 0000 0000 0000  '..V............
00000010: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000020: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000030: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000040: 6873 7173 0400 0000 8000 0000 0000 0000  hsqs............

观察要点:偏移0x00处魔数27 05 19 56为Uboot镜像头部标识;偏移0x40处出现hsqs字符串,这是Squashfs文件系统的魔数(对应ASCII字符"hsqs")。

步骤4:使用binwalk扫描固件内部结构

binwalk sample_fw.bin

预期输出:

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
0             0x0             U-Boot header, header size: 64 bytes, timestamp: 0x00000000, CRC: 0x00000000
64            0x40            Squashfs filesystem, little endian, version 4.0, compression:gzip, size: 4096 bytes, 1 inodes, blocksize: 131072 bytes, created: 2024-01-01 00:00:00

步骤5:提取并验证内部文件系统

# 使用dd跳过64字节头部,提取Squashfs部分
dd if=sample_fw.bin of=extracted.squashfs bs=1 skip=64

# 验证提取的文件系统
file extracted.squashfs
# 预期输出: extracted.squashfs: Squashfs filesystem, little endian, version 4.0, compression:gzip, size: 4096 bytes

# 挂载查看内容(需要root)
mkdir -p mnt_point
sudo mount -t squashfs extracted.squashfs mnt_point
ls mnt_point/
# 预期输出: hello.txt
cat mnt_point/hello.txt
# 预期输出: hello firmware
sudo umount mnt_point

验证判定标准

  • binwalk能正确识别出Uboot头部(偏移0)和Squashfs文件系统(偏移64)
  • 通过dd提取出的extracted.squashfs能被file命令正确识别为Squashfs文件系统
  • 挂载后能读取到hello.txt且内容为hello firmware,证明文件系统完整可用

常见问题

  • binwalk输出为空:固件可能经过加密或自定义封装,可尝试binwalk -E查看熵值判断是否加密
  • file命令识别为data:正常现象,固件常包含自定义头部,需结合binwalk和hexdump人工分析
  • 挂载失败:确认提取偏移量正确,且内核支持squashfs模块(modprobe squashfs)

本案例完成了从原始二进制文件到内部文件系统的完整识别与提取闭环,验证了固件分析中文件类型识别这一基础步骤的可行性与操作方法。