固件二进制分析:CPU架构识别与关键信息提取

拿到一个固件,第一件事是什么?不是急着解包,也不是直接扔进反汇编器。我个人的习惯是——先搞清楚它跑在什么CPU上。ARM?MIPS?还是x86?这个判断错了,后面所有分析都会跑偏。

你想想看,不同架构的指令编码完全不同,反汇编工具也得选对应的插件。我在一次车机OTA固件分析中就吃过这个亏,一开始以为是ARM,结果折腾半天发现是MIPS,白白浪费了一整天。

CPU架构识别:三板斧

识别CPU架构,说白了就三种方法。我按实用程度排个序:

  1. 文件头魔法字节——最快,但有时不准
  2. 字符串特征——辅助判断,几乎不会错
  3. 指令模式匹配——最终确认,最可靠

常见固件架构的魔法字节

架构ELF魔数(十六进制)常见文件头标识
ARM (32-bit)0x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00ELF 32-bit LSB ARM
ARM (64-bit)0x7f 0x45 0x4c 0x46 0x02 0x01 0x01 0x00ELF 64-bit LSB ARM aarch64
MIPS (大端)0x7f 0x45 0x4c 0x46 0x01 0x02 0x01 0x00ELF 32-bit MSB MIPS
MIPS (小端)0x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00ELF 32-bit LSB MIPS
x860x7f 0x45 0x4c 0x46 0x01 0x01 0x01 0x00ELF 32-bit LSB Intel 80386
x86-640x7f 0x45 0x4c 0x46 0x02 0x01 0x01 0x00ELF 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更新不强制修改。

知识体系:固件二进制分析流程

下面这张图是我自己总结的分析流程,每次做固件逆向都按这个走:

固件二进制分析核心流程 固件镜像获取 CPU架构识别 字符串提取分析 文件系统解包 硬编码凭据搜索 反汇编与逆向分析 OTA漏洞挖掘 💡 关键点: 架构识别错误 → 反汇编结果全错 → 漏洞挖掘无从下手。所以第一步必须走稳。

实战案例:一个智能插座固件的分析

我记得有一次,朋友拿来一个智能插座的OTA固件,说升级后设备变砖了。我拿到固件后:

  1. 先看文件头:file firmware.bin 返回 "data",不是标准ELF。
  2. 提取字符串:strings firmware.bin | grep -i "arm" 找到了 "ARM926EJ-S" 字样。
  3. 确认架构:用binwalk扫描,发现是ARM Thumb指令的裸机镜像。
  4. 搜硬编码: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 的位置。所以,多换几种编码方式试试。

好了,这一章的内容就这些。记住:架构识别是地基,字符串是线索,硬编码是金矿。这三步走扎实了,后面的逆向分析才能顺风顺水。