第78章 固件逆向(一):固件提取、binwalk使用、文件系统分析

固件逆向,说白了就是拆解嵌入式设备的“灵魂”。我做了这么多年逆向,最深的体会是:拿到一个硬件设备,第一步不是上示波器,而是先想办法把它的固件“请”出来。没有固件,后面的一切都是空谈。

这一章,咱们就聊聊固件提取的几种路子、binwalk这个神器的用法,以及怎么分析文件系统。嗯,这些都是基本功,但也是最容易踩坑的地方。

固件提取的几种姿势

固件提取,说白了就是想办法把设备里的二进制程序拷贝出来。方法有很多,我按常用程度排个序:

  1. 直接从官网下载——别笑,这是最省事的。很多厂商会提供固件更新包,直接下载解压就行。
  2. 从Flash芯片读取——用编程器或者JTAG/SWD接口,把Flash里的内容dump出来。
  3. 通过串口/UART获取——如果设备有调试串口,可以在启动时中断引导,进入uboot或bootloader的shell,然后用命令把固件导出来。
  4. OTA更新包抓取——抓包工具截获设备升级时的网络流量,从HTTP/FTP/TFTP等协议中提取固件。
  5. 拆解芯片直接读——遇到加密或者锁死的芯片,有时候得用热风枪吹下来,上编程器硬读。
我的习惯:先试官网下载,不行再上串口,最后才动烙铁。毕竟拆芯片有风险,搞不好板子就废了。

binwalk——固件分析的瑞士军刀

binwalk这个工具,我用了快十年了。它本质上是一个固件文件扫描器,能识别出固件里嵌入了哪些文件系统、压缩包、内核镜像等等。

基本用法很简单:

# 扫描固件,看看里面有什么
binwalk firmware.bin

# 提取所有识别到的文件
binwalk -e firmware.bin

# 只提取特定类型的文件(比如只提取文件系统)
binwalk -D 'squashfs:rootfs:squashfs' firmware.bin

# 显示详细的偏移量和签名信息
binwalk -Me firmware.bin

binwalk的工作原理,说白了就是靠“签名匹配”。它内置了上百种文件格式的魔数(Magic Number),比如SquashFS文件系统的签名是hsqs,JFFS2的签名是0x1985,等等。

重要:binwalk -e 提取出来的文件,默认放在 _firmware.bin.extracted 目录下。进去看看,你会发现一堆文件夹和文件,其中最重要的就是文件系统镜像。

文件系统分析——找到真正的“肉”

固件里最常见的文件系统类型有几种:

文件系统类型 常见场景 特点
SquashFS OpenWrt、路由器固件 只读、压缩率高、启动快
JFFS2 老款嵌入式设备 可读写、支持磨损均衡
UBIFS 较新的Linux设备 比JFFS2更高效、支持大容量
CramFS 非常老的设备 简单、但功能有限
initramfs/CPIO 临时根文件系统 内存中运行、用于早期引导

提取出文件系统之后,怎么挂载它?我一般这么干:

# 如果是SquashFS
unsquashfs rootfs.squashfs

# 如果是JFFS2(需要mtdblock设备)
modprobe mtdblock
modprobe jffs2
dd if=rootfs.jffs2 of=/tmp/jffs2.img
mount -t jffs2 /tmp/jffs2.img /mnt/jffs2

# 如果是UBIFS(需要ubi工具)
modprobe ubi
ubiformat /dev/mtd0 -f rootfs.ubi
ubiattach -m 0
mount -t ubifs ubi0:rootfs /mnt/ubifs

我曾经踩过的坑:有一次分析一个路由器固件,binwalk识别出了SquashFS,但unsquashfs报错说“文件系统损坏”。折腾了半天,后来发现是固件头部有自定义的校验字段,binwalk把偏移量算错了。解决办法是手动跳过头部,用dd命令截取真正的文件系统起始位置。

实战:从零开始分析一个路由器固件

咱们走一遍完整的流程。假设你手头有一个 router_fw.bin

# 第一步:扫描
binwalk router_fw.bin

# 输出大概长这样:
# DECIMAL       HEXADECIMAL     DESCRIPTION
# 0             0x0             uImage header, ...
# 64            0x40            LZMA compressed data
# 1310720       0x140000        SquashFS filesystem, little endian, ...

# 第二步:提取
binwalk -e router_fw.bin

# 第三步:进入提取目录
cd _router_fw.bin.extracted/

# 第四步:查看文件结构
ls -la
# 你会看到一堆文件,其中有个 140000.squashfs

# 第五步:解压文件系统
unsquashfs 140000.squashfs

# 第六步:进入解压后的目录,开始分析
cd squashfs-root/
ls -la
# 你会看到 /bin, /sbin, /etc, /usr 等标准Linux目录结构

到了这一步,固件逆向的“地基”就算打好了。接下来你可以分析二进制程序、找后门、挖漏洞,或者修改固件重新打包。

SVG:固件逆向核心流程

固件逆向核心流程 官网下载 Flash读取 串口/UART OTA抓包 binwalk 扫描与提取 SquashFS JFFS2 / UBIFS CPIO / CramFS 挂载文件系统 → 分析二进制 → 寻找漏洞/后门

避坑指南

做固件逆向这些年,我总结了几条血泪教训:

  • 不要迷信binwalk——它识别不出来不代表没有。有些固件用了自定义的魔数或者加密,binwalk会直接跳过。这时候得手动用hexdump或者strings去翻。
  • 注意字节序——ARM设备大多是Little Endian,MIPS设备可能是Big Endian。挂载文件系统时搞反了字节序,会报一堆莫名其妙的错误。
  • 文件系统可能被拆分——有些固件把文件系统分成多个块,分布在固件的不同位置。binwalk -e 可能只提取到一部分,需要手动拼接。
  • 别忘了检查固件头部——很多厂商会在固件头部加自定义结构,包含版本号、校验和、设备ID等信息。用hexdump -C看看前几百个字节,往往能发现线索。

一个小技巧:如果你不确定固件里有没有文件系统,先跑一下 strings firmware.bin | grep -i "squash\|jffs\|ubifs\|cramfs"。能匹配到的话,基本就稳了。

嗯,这一章的内容就到这里。固件提取和文件系统分析是逆向的起点,也是决定后续工作能否顺利的关键。多练几次,你就能摸清各种固件的“脾气”了。

公众号:蓝海资料掘金营,微信 deep3321