固件二进制分析:CPU架构识别与关键信息提取
拿到一个固件,第一件事是什么?不是急着解包,也不是直接扔进反汇编器。我个人的习惯是——先搞清楚它跑在什么CPU上。ARM?MIPS?还是x86?这个判断错了,后面所有分析都会跑偏。
你想想看,不同架构的指令编码完全不同,反汇编工具也得选对应的插件。我在一次车机OTA固件分析中就吃过这个亏,一开始以为是ARM,结果折腾半天发现是MIPS,白白浪费了一整天。
CPU架构识别:三板斧
识别CPU架构,说白了就三种方法。我按实用程度排个序:
- 文件头魔法字节——最快,但有时不准
- 字符串特征——辅助判断,几乎不会错
- 指令模式匹配——最终确认,最可靠
常见固件架构的魔法字节
| 架构 | ELF魔数(十六进制) | 常见文件头标识 |
|---|---|---|
| ARM (32-bit) | 0x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00 | ELF 32-bit LSB ARM |
| ARM (64-bit) | 0x7f 0x45 0x4c 0x46 0x02 0x01 0x01 0x00 | ELF 64-bit LSB ARM aarch64 |
| MIPS (大端) | 0x7f 0x45 0x4c 0x46 0x01 0x02 0x01 0x00 | ELF 32-bit MSB MIPS |
| MIPS (小端) | 0x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00 | ELF 32-bit LSB MIPS |
| x86 | 0x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00 | ELF 32-bit LSB Intel 80386 |
| x86-64 | 0x7f 0x45 0x4c 0x46 0x02 0x01 0x01 0x00 | ELF 64-bit LSB x86-64 |
用file命令是最直接的。比如:
$ file firmware.bin
firmware.bin: ELF 32-bit LSB ARM, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.3
但注意,很多IoT固件是裸机镜像,没有ELF头。这时候就得靠字符串特征了。
字符串提取与分析
字符串是固件里的「活口」。设备型号、版本号、路径、错误信息……这些都能帮你快速定位固件的用途和架构。
我常用的命令:
$ strings firmware.bin | head -100
$ strings -n 6 firmware.bin | grep -i "arm\|mips\|x86\|linux"
-n 6的意思是只提取长度≥6的字符串,过滤掉太短的噪音。我曾经在一个路由器固件里,通过strings找到了隐藏的后门路径——/secret_debug_shell,嗯,厂商连路径名都懒得加密。
小技巧:用strings -e l可以提取16位Unicode字符串,很多嵌入式设备用UTF-16存中文字符串。
硬编码凭据搜索:挖洞的黄金地带
硬编码凭据,说白了就是厂商写在代码里的密码、密钥、Token。这是OTA漏洞的重灾区。我统计过,大概60%的IoT固件里能找到至少一个硬编码凭据。
搜索关键词清单:
- 密码相关:password, passwd, pwd, secret, passkey
- 密钥相关:key, private_key, aes_key, rsa_key, token
- 认证相关:auth, credential, login, admin
- 特殊模式:debug, test, factory, default
实战命令:
$ strings firmware.bin | grep -iE "(password|secret|key|token|auth)" | sort -u
注意:别只看明文。有些厂商会用Base64或简单异或编码。我曾经在某个智能门锁固件里,发现密码是Base64编码的"888888"——解码后就是出厂默认密码,而且OTA更新不强制修改。
知识体系:固件二进制分析流程
下面这张图是我自己总结的分析流程,每次做固件逆向都按这个走:
实战案例:一个智能插座固件的分析
我记得有一次,朋友拿来一个智能插座的OTA固件,说升级后设备变砖了。我拿到固件后:
- 先看文件头:
file firmware.bin返回 "data",不是标准ELF。 - 提取字符串:
strings firmware.bin | grep -i "arm"找到了 "ARM926EJ-S" 字样。 - 确认架构:用
binwalk扫描,发现是ARM Thumb指令的裸机镜像。 - 搜硬编码:
strings firmware.bin | grep -i "password"找到了 "admin:admin123"。
最后发现,变砖的原因是OTA升级包没有校验签名,攻击者可以替换固件。而那个硬编码密码,直接给了攻击者SSH访问权限。
核心工具清单
| 工具 | 用途 | 常用参数 |
|---|---|---|
file | 识别文件类型和架构 | file firmware.bin |
strings | 提取可打印字符串 | -n 6 -e l |
binwalk | 固件扫描与解包 | -Me firmware.bin |
hexdump | 查看十六进制头 | -C -n 64 firmware.bin |
grep | 关键词搜索 | -iE "(password|key)" |
避坑指南
我做固件分析这几年,踩过的坑不少。挑几个典型的说说:
- 别信文件后缀:.bin 可能是任何东西。我见过 .bin 其实是 ZIP 压缩包的。
- 注意字节序:MIPS 有大端和小端,ARM 也有 BE8/BE32。选错反汇编器会出乱码。
- 字符串可能被混淆:有些厂商会把关键字符串做 XOR 或 ROT13 编码。别以为搜不到就是没有。
- 硬编码不只在二进制里:配置文件、脚本、HTML 里也可能藏着密码。我曾在某个设备的 web 页面源码里找到后台密码。
曾经有一次,我在分析一个摄像头固件时,strings 搜 "password" 什么都没找到。后来用 strings -e l 才发现,密码是用 UTF-16 存的,而且就在固件偏移 0x2A3F0 的位置。所以,多换几种编码方式试试。
好了,这一章的内容就这些。记住:架构识别是地基,字符串是线索,硬编码是金矿。这三步走扎实了,后面的逆向分析才能顺风顺水。