3、固件逆向分析基础:binwalk工具使用、固件解包与文件系统挂载、字符串分析
固件逆向分析,说白了就是跟二进制文件打交道。你拿到一个.bin文件,不知道里面是什么,不知道文件系统怎么挂的,甚至不知道它是不是加密了。这时候,binwalk就是你的第一把刀。
我个人习惯,拿到固件第一件事不是直接跑binwalk,而是先看一眼文件头。用hexdump -C firmware.bin | head -n 20扫一下,看看有没有明显的魔数。比如看到7f 45 4c 46,那就是ELF;看到1f 8b 08,那就是gzip压缩。这一步能帮你快速判断固件有没有被简单混淆。
-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 字符串分析:从垃圾中找金子
字符串分析,听起来简单,但做得好的人不多。你想想看,一个固件里可能有几万条字符串,怎么找到有用的?
我的流程是这样的:
- 提取所有字符串:
strings -n 6 firmware.bin > strings.txt。长度设为6,过滤太短的噪音。 - 按关键词过滤:
grep -iE '(password|admin|key|secret|token|debug|test)' strings.txt。这是找硬编码凭据。 - 找路径和命令:
grep -E '(/dev/|/proc/|/sys/|/tmp/|/etc/|/usr/)' strings.txt。这是找文件系统路径。 - 找IP和URL:
grep -E '([0-9]{1,3}\.){3}[0-9]{1,3}|http|https|ftp' strings.txt。这是找后门地址。 - 找函数名和库:
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 知识体系总览
下面这张图,是我自己总结的固件逆向分析流程。你照着这个思路走,基本不会漏东西。
这张图把流程分成了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、解包、挂载、字符串分析,这四个技能是固件逆向的基石。你多练几次,自然就熟了。