第三章:固件获取方法

做固件逆向,第一步就是拿到固件。没有固件,后面全是空谈。

我经常被新手问:「固件到底怎么搞?」其实方法就那几种。我这些年做过的项目,从PLC到工业机器人,从RTU到智能仪表,固件获取无非是这四条路:官网下载、编程器读取、Bootloader提取、漏洞Dump。

今天我把这四种方法掰开揉碎了讲。每个方法都有它的适用场景,也有它的坑。你跟着我走一遍,以后遇到任何设备,心里就有底了。

3.1 从官网下载

这是最省事的方法。很多厂商会提供固件更新包,直接去官网下载就行。

我个人的习惯是:先搜官网,再搜论坛,最后才考虑拆设备。为什么?因为省时间。你想想看,一个固件包可能就几MB到几十MB,下载下来直接就能分析,何必去拆机焊线?

但这里有个问题——不是所有厂商都大方。有些厂商把固件藏得很深,需要注册账号、填写设备序列号、甚至签NDA才能拿到。还有些厂商只提供增量更新包,你得先有基础版本才能用。

我的经验: 西门子、罗克韦尔这类大厂,固件下载相对规范。但一些国产小厂,官网可能连个下载链接都没有。这时候就别死磕了,换下一种方法。

下载固件时要注意版本号。我建议你下载多个版本,尤其是老版本。为什么?因为老版本往往有更多漏洞,分析起来更容易。我曾经为了找一个PLC的固件漏洞,专门去Wayback Machine上翻了三年前的版本。

3.2 使用编程器读取Flash

官网找不到?那就拆机。这是最硬核的方法,也是我最常用的方法。

工控设备里最常见的存储芯片是SPI Flash和Parallel NOR Flash。SPI Flash多见于中低端设备,比如一些国产PLC、RTU。Parallel NOR Flash则常见于高端设备,比如西门子S7系列。

具体操作步骤:

  1. 拆机——找到电路板上的Flash芯片。通常标有「Winbond」「Macronix」「Spansion」等字样。
  2. 确认型号——用手机拍下芯片上的丝印,去查数据手册。注意引脚间距,常见的是SOIC-8或SOIC-16封装。
  3. 连接编程器——我推荐用CH341A或TL866系列。便宜好用,支持芯片多。
  4. 读取固件——设置好芯片型号,点击读取。保存为.bin文件。
注意: 有些设备会开启读保护。你读出来的数据全是0xFF或0x00,那就是被锁了。这时候需要先解锁,或者换其他方法。

我曾经遇到过一台施耐德的PLC,Flash芯片是MX25L25635F。读出来一看,前64KB全是0xFF。我当时就意识到——这是Bootloader区域被加密了。后来我用了漏洞Dump的方法才拿到完整固件。

编程器读取的优点是:只要硬件没坏,一定能读到数据。缺点是:需要拆机,可能破坏保修,而且有些设备有防拆设计。

3.3 通过Bootloader提取

很多工控设备都有Bootloader,用于固件升级。如果你能进入Bootloader模式,就可以通过串口或网口把固件导出来。

Bootloader提取的原理很简单:设备启动时,Bootloader会等待用户输入命令。如果你能在超时之前发送正确的指令,就能进入维护模式。

常见的Bootloader有:

Bootloader类型 常见设备 进入方式
U-Boot 基于ARM的工控板 上电时按任意键
RedBoot 一些老式PLC 串口发送Ctrl+C
厂商自研Bootloader 各品牌定制设备 特定引脚拉高/拉低

具体怎么操作?以U-Boot为例:

# 连接串口,设置波特率115200
# 上电后迅速按任意键
# 进入U-Boot命令行后,执行:
U-Boot> md.b 0x80000000 0x100000  # 读取内存
U-Boot> sf read 0x80000000 0x0 0x100000  # 读取SPI Flash
U-Boot> tftp 0x80000000 firmware.bin  # 上传到TFTP服务器

我个人觉得,Bootloader提取是最优雅的方法。不需要拆机,不需要编程器,只要一根串口线就行。但前提是——你得知道怎么进入Bootloader。

避坑指南: 我曾经遇到一台设备,Bootloader的串口波特率不是标准的115200,而是57600。我折腾了两个小时才发现。所以,如果你连不上,试试不同的波特率。

3.4 利用漏洞Dump固件

这是最「黑客」的方法。当以上三种方法都行不通时,就该用漏洞了。

常见的漏洞类型:

  • 命令注入——Web界面或串口命令行存在注入点,可以执行系统命令
  • 缓冲区溢出——利用溢出漏洞劫持程序流程,读取内存
  • 未授权访问——某些调试接口没有鉴权,可以直接读取Flash
  • 固件解密漏洞——加密固件存在密钥泄露或算法缺陷

举个例子,我曾经分析过一台国产RTU。它的Web界面有个「固件升级」功能,上传固件后设备会重启。我注意到它会把上传的固件先保存到/tmp目录,然后再写入Flash。

于是我想:能不能在写入之前把固件读出来?

我构造了一个特殊的请求:

POST /upload HTTP/1.1
Content-Type: multipart/form-data

--boundary
Content-Disposition: form-data; name="firmware"; filename="test.bin"

[恶意固件包,包含读取/tmp目录的命令]
--boundary--

结果呢?设备没有做输入校验,我上传的「固件」被当成了脚本执行。我成功读取了/tmp目录下的原始固件包。

重要提醒: 利用漏洞Dump固件,必须在合法授权下进行。未经授权的渗透测试是违法的。我做的所有项目都有厂商的书面授权。

漏洞Dump的优点是:不需要物理接触设备(如果是远程漏洞),也不需要拆机。缺点是:需要一定的漏洞挖掘能力,而且不是每个设备都有漏洞。

3.5 四种方法对比

说了这么多,我帮你总结一下:

方法 难度 成本 成功率 适用场景
官网下载 ★☆☆☆☆ 0元 30% 大厂设备、有公开固件
编程器读取 ★★★☆☆ 50-200元 90% 能拆机、Flash未加密
Bootloader提取 ★★☆☆☆ 10元(串口线) 60% 有串口、Bootloader未锁定
漏洞Dump ★★★★☆ 0元(时间成本高) 40% 其他方法都失效时

我的建议是:按顺序尝试。先官网,再Bootloader,再编程器,最后漏洞。别一上来就拆机,也别一上来就挖漏洞。效率第一。

3.6 本章知识体系

下面这张图,是我自己画的固件获取方法决策流程。你照着走,基本不会错。

固件获取方法决策流程 开始获取固件 官网有固件? 官网下载 有Bootloader? Bootloader提取 能拆机? 编程器读取 漏洞Dump

这张图我用了很多年。每次拿到新设备,我就按这个流程走一遍。90%的设备都能搞定。

好了,固件获取的方法就讲到这里。记住:拿到固件只是第一步,后面还有固件分析、漏洞挖掘、逆向工程等着你。但这一步走扎实了,后面的路就好走了。

核心要点:
  • 先易后难:官网 → Bootloader → 编程器 → 漏洞
  • 多版本下载:老版本往往有更多分析价值
  • 注意读保护:编程器读取前先确认Flash是否加密
  • 合法授权:漏洞利用必须在授权范围内

公众号:蓝海资料掘金营,微信deep3321