3、固件逆向分析基础:binwalk工具使用、固件解包与文件系统挂载、字符串分析

固件逆向分析,说白了就是跟二进制文件打交道。你拿到一个.bin文件,不知道里面是什么,不知道文件系统怎么挂的,甚至不知道它是不是加密了。这时候,binwalk就是你的第一把刀。

我个人习惯,拿到固件第一件事不是直接跑binwalk,而是先看一眼文件头。用hexdump -C firmware.bin | head -n 20扫一下,看看有没有明显的魔数。比如看到7f 45 4c 46,那就是ELF;看到1f 8b 08,那就是gzip压缩。这一步能帮你快速判断固件有没有被简单混淆。

小技巧: 很多厂商会在固件头部加一段自定义的引导头,真正的文件系统从偏移0x100或0x200才开始。binwalk的-R选项可以帮你扫描自定义特征码,别只依赖默认签名库。

3.1 binwalk 核心用法

binwalk的用法其实不复杂,但有几个参数我几乎每次都用。先列个表,你对照着看:

命令 作用 我常用的场景
binwalk firmware.bin 扫描固件中的已知文件签名 快速了解固件里有什么
binwalk -Me firmware.bin 递归提取所有文件 一键解包,省事
binwalk -D 'png:image:raw' firmware.bin 按类型提取特定文件 只提取图片或特定数据块
binwalk -R 'YOUR_MAGIC' firmware.bin 扫描自定义特征码 对付非标准固件头
binwalk -W firmware.bin 显示文件熵值 判断是否加密或压缩

嗯,这里要注意:-Me虽然方便,但有时候会提取出大量碎片文件。我建议先跑一次binwalk看看扫描结果,确认文件系统偏移和大小后,再用dd手动切出来。这样更可控。

避坑指南: 我曾经遇到一个固件,binwalk扫描出来一堆东西,但提取后全是乱码。后来发现厂商在文件系统前插了一段随机填充数据,binwalk的偏移计算被干扰了。解决办法是用binwalk -E看熵值图,找到真正的数据起始点。

3.2 固件解包与文件系统挂载

固件解包,核心就是识别文件系统类型。最常见的几种:

  • SquashFS:Linux嵌入式设备的老大哥,压缩率高,只读。魔数hsqs或sqsh。
  • JFFS2:早期Flash文件系统,支持磨损均衡。魔数19 85。
  • CramFS:更老,现在少见。魔数0x28cd3d45。
  • UBIFS:NAND Flash的现代选择。魔数UBI#。

解包SquashFS,我一般用unsquashfs。命令很简单:

# 先找到SquashFS的偏移,比如0x100000
dd if=firmware.bin bs=1 skip=$((0x100000)) of=rootfs.squashfs
unsquashfs rootfs.squashfs

但有时候binwalk已经帮你提取好了,直接进_firmware.bin.extracted目录找就行。

挂载文件系统,我建议用mount配合loop设备。比如挂载一个JFFS2镜像:

modprobe mtdblock
modprobe jffs2
dd if=firmware.bin bs=1 skip=$((0x200000)) of=jffs2.img
mount -t jffs2 -o loop jffs2.img /mnt/firmware

为什么会这样?因为JFFS2需要MTD层模拟,直接挂载会报错。嗯,这个坑我踩过好几次。

警告: 挂载文件系统前,先确认固件来源。有些固件包含恶意代码,挂载后自动执行。我建议在隔离环境或只读挂载下操作,加-o ro参数。

3.3 字符串分析:从垃圾中找金子

字符串分析,听起来简单,但做得好的人不多。你想想看,一个固件里可能有几万条字符串,怎么找到有用的?

我的流程是这样的:

  1. 提取所有字符串:strings -n 6 firmware.bin > strings.txt。长度设为6,过滤太短的噪音。
  2. 按关键词过滤:grep -iE '(password|admin|key|secret|token|debug|test)' strings.txt。这是找硬编码凭据。
  3. 找路径和命令:grep -E '(/dev/|/proc/|/sys/|/tmp/|/etc/|/usr/)' strings.txt。这是找文件系统路径。
  4. 找IP和URL:grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}|http|https|ftp' strings.txt。这是找后门地址。
  5. 找函数名和库:grep -E '(printf|malloc|free|strcpy|system|exec|fork)' strings.txt。这是找潜在漏洞函数。

我个人习惯,把结果按偏移排序,然后对照binwalk的扫描结果看。比如某个字符串出现在0x400000附近,而binwalk显示那里是SquashFS,那这个字符串大概率是文件系统里的配置文件内容。

进阶技巧: 用strings -t x firmware.bin可以显示每个字符串的偏移地址。配合hexdump或xxd,能快速定位到二进制中的具体位置,方便后续patch。

3.4 知识体系总览

下面这张图,是我自己总结的固件逆向分析流程。你照着这个思路走,基本不会漏东西。

固件逆向分析流程 固件逆向分析核心流程 1. 固件获取与识别 2. binwalk 初步扫描 熵值分析 (-W) 签名扫描 (默认) 3. 固件解包与提取 4. 文件系统挂载 5. 字符串分析与审计 关键:硬编码凭据、路径、IP、函数

这张图把流程分成了5个阶段。你从固件获取开始,经过binwalk扫描、解包、挂载,最后到字符串分析。每一步都有对应的工具和技巧。我个人建议,新手先按这个流程走一遍,熟悉之后再根据实际情况调整。

3.5 实战中的坑与对策

最后,分享几个我实际项目中遇到的坑:

  • 固件被多次压缩:有些固件会套娃式压缩,比如gzip里面包了一个lzma。binwalk有时候只解第一层。我习惯用binwalk -Me递归解,然后手动检查每一层。
  • 文件系统校验和:解包后修改文件,重新打包时设备不启动。这是因为SquashFS有校验和。用unsquashfs解包,修改后用mksquashfs重新打包,注意保持原参数。
  • 字符串被加密或编码:有些厂商会把关键字符串做简单XOR或Base64编码。我遇到过一次,所有IP地址都是XOR 0x55后的结果。用strings看不到,但用hexdump配合xxd手动分析才发现。
再次提醒: 字符串分析时,别只盯着password和admin。有时候真正的后门藏在debug、test、factory这些词里。我曾经在一个路由器的固件里找到factory_reset_passwd,结果那个密码就是设备的超级管理员密码。

好了,这一章的内容就这些。binwalk、解包、挂载、字符串分析,这四个技能是固件逆向的基石。你多练几次,自然就熟了。