恶意固件样本分析:固件提取、逆向工程与动静分析
各位同学,欢迎来到第三章。前两章我们搭好了沙箱环境,也聊了固件安全的基础威胁模型。从这章开始,咱们要真正动手了——面对一个恶意固件样本,你第一步该做什么?
说白了,就是三件事:把固件从硬件里弄出来、看懂它里面是什么、判断它到底干了什么坏事。我做了这么多年固件分析,见过太多人一上来就反汇编,结果发现固件根本提错了,白忙活一整天。所以,顺序很重要。
核心思路:固件分析不是一锤子买卖。提取→逆向→分析,每一步都可能让你回头修正前面的判断。保持迭代心态。
3.1 固件提取技术:把固件从硬件里「请」出来
固件提取是分析的基础。你拿不到固件,后面全是空谈。提取方式分三大类,我按实战中遇到的频率排序讲。
3.1.1 物理提取:直接读芯片
最直接的方法。把Flash芯片吹下来,用编程器读。适合SPI Flash、NAND、NOR等常见存储芯片。
- SPI Flash编程器:CH341A、FT2232H,便宜好用。我习惯用树莓派的GPIO直接怼SPI,速度更快。
- NAND读取:注意坏块管理。我曾经因为没处理坏块表,读出来的固件校验一直不过,折腾了两天。
- JTAG/SWD:如果芯片没锁,直接通过调试接口dump内存。适合MCU类固件。
避坑指南:我曾经遇到过芯片有「读保护」Level 1/2。这时候别硬来,先查芯片手册,看看有没有后门或漏洞可以利用。比如STM32的读保护,某些老版本可以通过电压毛刺绕过。
3.1.2 逻辑提取:通过软件接口获取
如果设备还能跑,通过UART、USB、网络等接口把固件拉出来。常见手法:
- U-Boot救砖:很多嵌入式设备启动时按任意键进U-Boot,然后
tftp或loadb把固件传出来。 - 固件更新包:从官网下载的.bin/.hex文件,或者OTA抓包。但要注意,更新包可能被加密或签名。
- 漏洞利用:通过命令注入、缓冲区溢出等漏洞,在设备上执行
cat /dev/mtdblock0之类的命令。
⚠️ 注意:逻辑提取依赖设备正常运行。如果设备已经被恶意固件搞瘫痪了,这条路走不通。我建议先试逻辑提取,不行再上物理提取。
3.1.3 高级提取:对付加密和压缩
现在很多固件出厂就加密或压缩了。提取只是第一步,你还得解包。
| 技术 | 适用场景 | 常用工具 |
|---|---|---|
| binwalk | 自动识别文件系统、压缩算法 | binwalk -Me firmware.bin |
| 固件加密分析 | 识别AES、RSA等加密特征 | findcrypt、哈希匹配 |
| LZMA/gzip解压 | 常见压缩固件 | 7z、dd + unlzma |
| 自定义格式 | 厂商魔改的固件头 | 010 Editor + 模板 |
我个人习惯:拿到固件先跑 binwalk -Me,看看能不能自动解出文件系统。如果不行,再用 hexdump 看头部特征。你想想看,很多厂商只是把标准Linux内核+根文件系统打包一下,binwalk基本都能搞定。
3.2 固件逆向工程基础:从二进制到逻辑
固件提出来了,接下来就是逆向。这一步的核心是:搞清楚固件里有哪些模块,它们怎么交互的。
3.2.1 识别CPU架构和操作系统
不同架构的指令集完全不同。ARM、MIPS、x86、RISC-V……你得先知道目标是什么。
- 看入口点:ARM的Reset Vector通常在0x0或0x8000附近;MIPS的入口一般在0x80001000附近。
- 用工具自动识别:
file命令、binwalk的架构检测、readelf(如果有ELF头)。 - 字符串搜索:搜 "Linux version"、"U-Boot"、"VxWorks" 等关键字。
实战技巧:我遇到过固件头被故意抹掉的情况。这时候可以看中断向量表——ARM的异常向量表有固定模式(0xEA000000等),一眼就能认出来。
3.2.2 文件系统提取与分析
大多数固件包含一个完整的文件系统。常见的有:
- SquashFS:只读压缩文件系统,Linux嵌入式最爱。用
unsquashfs解压。 - JFFS2/UBIFS:针对NAND Flash的日志型文件系统。需要
jefferson或ubi_reader。 - CPIO:initramfs常用。直接用
cpio -idmv解。 - 自定义格式:有些厂商自己魔改的文件系统。这时候得手动分析超级块结构。
举个例子,解压SquashFS的命令:
# 先用binwalk找到偏移
binwalk firmware.bin | grep SquashFS
# 假设偏移是0x123456,大小是0x800000
dd if=firmware.bin bs=1 skip=$((0x123456)) count=$((0x800000)) of=rootfs.squashfs
unsquashfs rootfs.squashfs
3.2.3 关键二进制文件逆向
文件系统解开后,重点关注这些文件:
- /bin/、/sbin/下的主程序:比如httpd、telnetd、upnp服务。
- /etc/init.d/下的启动脚本:看恶意固件改了哪些启动项。
- /lib/下的动态库:特别是被hook的系统调用。
- /dev/下的特殊设备:有些恶意固件会创建隐藏字符设备。
用IDA Pro或Ghidra打开主程序,先看字符串窗口。我习惯搜 "password"、"backdoor"、"debug"、"shell" 这些关键词。你想想看,恶意固件作者也是人,他们也会偷懒,字符串往往暴露一切。
3.3 静态分析与动态分析:双管齐下
逆向工程让你理解了固件的结构,但真正判断它是不是恶意,还得靠分析。静态分析和动态分析是两条腿,缺一不可。
3.3.1 静态分析:不动手,先看代码
静态分析就是不运行固件,直接看二进制代码。好处是安全,不会触发恶意行为。坏处是可能漏掉加壳或混淆的逻辑。
- 特征匹配:用YARA规则扫描固件,匹配已知恶意特征。我维护了一个固件专用的YARA规则库,覆盖了常见的后门、挖矿、DDoS模块。
- 控制流分析:在IDA/Ghidra里看函数调用图。重点关注网络接收、系统命令执行、文件读写等敏感函数。
- 数据流分析:追踪用户输入到敏感函数的路径。比如recv()的数据直接传给system(),这基本就是命令注入。
- 加密算法识别:用findcrypt插件找硬编码的密钥或S盒。
我的习惯:静态分析时先跑一遍自动化脚本。我会用 cwe_checker 扫描常见漏洞模式,再用 firmwalker 检查敏感文件。自动化筛一遍,人工再聚焦可疑点。
3.3.2 动态分析:让固件跑起来
动态分析就是在沙箱里执行固件(或固件中的某个程序),观察它的行为。这是验证静态分析结论的关键一步。
动态分析的核心手段:
| 技术 | 监控内容 | 常用工具 |
|---|---|---|
| 系统调用跟踪 | 文件、网络、进程操作 | strace、ltrace、sysdig |
| 网络流量分析 | C2通信、DNS查询、数据外传 | tcpdump、Wireshark、FakeNet |
| 内存快照 | 运行时数据、解密后的payload | avocado、QEMU + GDB |
| API Hook | 拦截特定函数调用 | Frida、LD_PRELOAD |
举个例子,用QEMU模拟运行一个MIPS架构的恶意固件程序:
# 安装QEMU用户态模拟
sudo apt install qemu-user-static
# 运行MIPS程序,用strace跟踪
qemu-mips-static -L ./squashfs-root/ ./squashfs-root/bin/httpd &
strace -p $(pidof qemu-mips-static) -e trace=network,file,process
⚠️ 安全警告:动态分析必须在隔离的沙箱环境中进行。我曾经见过一个固件样本,它检测到自己在QEMU里就跑,但一旦发现是真实网络,立刻开始扫描内网。所以,网络隔离是底线。
3.3.3 动静结合:交叉验证
静态分析告诉你「可能有什么」,动态分析告诉你「实际做了什么」。两者结合才能下结论。
我常用的工作流:
- 静态扫描,列出所有可疑文件和函数。
- 在沙箱里运行关键程序,抓系统调用和网络包。
- 对比静态分析的结果和动态行为。如果静态说某个函数是加密函数,但动态发现它在连接外部IP,那就有问题了。
- 根据动态结果,回头细化静态分析。比如动态发现了一个隐藏的配置文件路径,再回固件里找这个文件。
核心原则:不要相信任何单一分析结果。静态可能漏掉加壳代码,动态可能被反沙箱技术欺骗。只有交叉验证过的结论,才值得写进报告。