首页
社区
课程
招聘
[原创]艾默生DeltaV DCS控制器 固件安全分析研究
发表于: 1天前 684

[原创]艾默生DeltaV DCS控制器 固件安全分析研究

1天前
684

艾默生 DeltaV分布式控制系统(DCS)是全球流程工业(如石油化工、制药、电力等)中广泛使用的核心控制平台。作为整个生产过程的“大脑”,DeltaV系统中的控制器(如MD Plus系列)负责执行复杂的逻辑控制、数据采集与现场总线通信。由于其直接关系到关键基础设施的稳定运行,一旦控制器遭到恶意攻击或篡改,可能会导致严重的生产事故甚至环境灾难。
图片描述
近年来,随着工业网络与IT网络的深度融合,针对DCS系统的网络威胁日益增加。然而,由于DCS系统生态相对封闭,针对其底层固件的深度安全研究在公开领域并不多见。出于对关键基础设施安全的关注,笔者近期对艾默生 DeltaV控制器的固件进行了深度的逆向分析与安全研究。本文将以DeltaV MD Plus控制器为例,从固件获取、自定义格式解密、符号恢复以及安全面探索等角度,分享工控设备固件分析的研究思路与实操方法。

开展固件分析的第一步是获取目标固件。DeltaV系统采用中心化的固件分发架构,控制器的固件更新通常通过DeltaV工作站经以太网下发至现场控制器。

笔者通过对DeltaV工作站软件的安装目录进行梳理,在工程师站点的安装目录下发现了完整的固件文件集合。
图片描述
研究对象MD Plus控制器最核心的两个文件是 rev7-AppR.srec(应用层固件)和 rev7-OSR.srec(QNX IFS操作系统镜像)。值得注意的是,这些固件文件以明文形式直接存储于工作站的磁盘目录中,无需任何额外的认证或权限即可获取。这种在分发和存储链路中缺乏访问控制保护的设计,为后续的安全研究提供了直接的切入点。

获取到的固件文件采用了Motorola S-Record(SREC)格式,这是一种古老的ASCII编码二进制传输格式。首先编写Python脚本,将SREC文件中的地址、校验和等封装信息剥离,还原出了精确的10MB纯二进制镜像数据。
图片描述
如图所示,每一行代表一条记录,以第2行为例:起始的S3表示记录类型(32位地址数据记录);紧随其后的25为字节计数(十六进制0x25,表示后续内容的字节总数);00400000为32位目标地址,指示该段数据应烧录至内存的起始位置;中间长串的十六进制字符为实际的数据载荷;行末的B2为校验和,用于验证该行数据在传输过程中的完整性。通过解析SREC格式,剥离地址、类型和校验信息,即可还原出连续的二进制镜像文件。

对10MB的二进制镜像进行初步分析时,发现其中散布着大量可读的ASCII字符串(如“bootscript2”、“login”、“DvApp”等)。进一步观察发现,这些字符串总是出现在某个固定模式的8字节标记(Marker)之前,随后紧跟对应的数据内容。
图片描述
这表明整个镜像并非一个单一的文件,而是一个多条目打包容器。通过编写自动化扫描脚本,笔者成功识别并提取了镜像中的全部109个命名条目,涵盖了启动脚本、用户认证程序、网络工具以及最核心的主控应用程序 DvApp。其中,DvApp条目占据了约50%的空间(约5.2MB),包含了控制器的核心工业协议栈与业务逻辑。
图片描述

尝试使用 binwalk、file 等常规工具对 DvApp 数据进行分析,均无法识别其格式,且未发现任何标准压缩文件(如 ZIP、GZIP)的魔数签名。通过十六进制编辑器直接观察文件头部(如下图所示),我们发现前 16 字节具有明显的结构化特征,而非随机数据,这暗示了自定义封装协议的存在。
图片描述
具体解析这 16 字节头部数据(均为小端序):
偏移 0x00-0x03 (78 3A 86 00):解析值为 0x00863A78,即十进制的 8,796,792。这代表解压后的固件总大小。
偏移 0x04-0x05 (00 20):解析值为 0x2000,即 8,192。这代表每个压缩块解压后的固定输出大小。
偏移 0x06-0x07 (01 00):解析值为 1,标识压缩格式的版本号。
偏移 0x0A-0x0B (5E 0C):解析值为 0x0C5E(3166),这是链式结构的第一个跳转参数(w1)。

观察头部之后的数据,呈现出典型的高熵特征,符合强压缩数据的特征。通过对压缩数据流的比特流模式进行进一步的手动分析与交叉比对,确认其底层采用了 UCL NRV2B 轻量级压缩算法。然而,DeltaV 并未直接套用标准的 UPX 格式,而是基于上述 16 字节头部进行了完全自定义的分块封装(每块固定输出 8KB),这正是导致 binwalk 无法识别、UPX 无法解压等所有标准工具全部失效的根本原因。

为了还原数据,必须搞清楚其分块结构。通过对比压缩块末尾与下一个有效块开始之间的数据,发现每个块之间存在一个8字节的固定格式结构体,被命名为 Inter-Block Header(IB)。
如下图所示,IB的8字节结构为:
w1字段(示例值0x0C5E),表示从前一个IB到当前IB的距离
w2字段(示例值0X0BE9),表示从当前IB到下一个IB的距离
固定标记 00 20 00 20(0x0020 = 8192,确认每块解压输出大小)
图片描述

在5.2MB的数据流中搜索该固定模式,共定位到1,072个有效IB。
图片描述
这些IB通过特定的偏移字段形成了28条独立的链(段)。基于此规律,编写脚本可实现所有压缩块起始位置的精准定位。

在实现解压器时遇到了一个核心难题:部分压缩块在解压时,其LZ77匹配引用的回退距离超出了当前块已产生的输出数据量。经过深入分析发现,该固件的压缩字典窗口跨越了多个块的输出。


[内核课程]《Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。

收藏
免费 0
打赏
分享
最新回复 (1)
雪    币: 158
活跃值: (5136)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
学习!
1天前
0
游客
登录 | 注册 方可回帖
返回