OPC是OLE for Process Control的简写,即用于过程控制的OLE(OLE即面向对象的链接和嵌入),是一个诞生于1996年的工业标准。由OPC Foundation(OPC基金会)维护。OPC基金会现有200多家会员单位,包括各大主要的自动化、仪器仪表、过程控制系统的公司和企业,研究机构等。
OPC DA(数据访问)是最常见的标准,它描述了一组与 PLC、DCS、HMI、CNC 和其他设备进行实时数据交换的功能。
OPC HDA(历史数据访问)提供对已保存数据和历史的访问。
OPC AE(警报和事件)为各种事件提供按需通知功能:紧急情况、操作员操作、信息消息等。
OPC Batch提供工艺过程的步骤和配方控制功能。
OPC DX (Data exchange)提供通过以太网在
OPC 服务器之间组织数据交换的功能。该标准的主要目的是为来自不同制造商的设备和程序之间的数据交换创建网关。
OPC 安全定义了组织客户端对OPC 服务器数据的访问权限的功能。
OPC XML-DA(XML数据访问)提供了一种灵活的、规则驱动的格式,用于通过 XML、SOAP和 HTTP 交换数据。OPC 复杂数据是一组针对 OPC DA 和 XML-DA 的附加规范,允许服务器处理复杂数据类型,例如二进制结构和 XML 文档。
OPC 命令是一组编程接口,允许 OPC 客户端和服务器识别、发送和控制在控制器或 I/O 模块中执行的命令。
OPC UA(统一架构)是不基于 Microsoft COM 技术的最新规范,它提供了跨平台兼容性。
OPC UA .NET Standard Stack是OPC Foundation(OPC基金会)官方维护的OPC UA协议栈的参考实现。该协议栈以.NET语言开发,包含了可移植的OPC UA协议栈和核心库(包含客户端、服务端、配置、复杂类型支持库等),服务端和客户端的参考实现以及客户端和服务端的X.509证书认证等实现。OPC UA协议是工业控制领域中的一种十分流行的通讯协议。
此漏洞存在于OPC UA 1.04.368 之前,修复于1.04.368.58后的版本。根据官方的漏洞公告,远程攻击者可能使得OPC服务器触发一个栈溢出异常:
根据漏洞相关信息,修复主要是在递归调用前对browsePath进行校验:
按照OPC标准的定义,TranslateBrowsePathsToNodeIds函数的参数形式为:
名称 |
类型 |
描述 |
RequestHeader |
RequestHeader |
请求头 |
BrowsePath[] |
BrowsePath |
浏览路径列表 |
startingNode |
NodeId |
浏览路径的起始节点 |
relativePath |
RelativePath |
从起始节点进一步跟踪的路径 |
RelativePath结构如下:
名称 |
类型 |
描述 |
referenceTypeId |
NodeId |
当前节点的引用类型 |
isInverse |
Boolean |
是否是反向 |
includeSubtypes |
Boolean |
|
targetName |
QualifiedName |
目标节点的BrowseName |
例如,对于一个“NodeB“ 的startingNode 是”Node A“, relativePath定义为:
TargetName = “Node B”
IsInverse = False
referenceTypeId = HasComponent
TargetName = “Node C”
referenceTypeId = HasComponent
重复这个过程就能构造出一个很长的链条,导致服务器在递归调用的时候耗尽堆栈。值得一提的是实际构造这个链条的时候需要保证RelativePath始终指向有效的节点,因此startingNode和target就需要仔细选择才能触发递归调用。漏洞演示如下:
1.https://files.opcfoundation.org/SecurityBulletins/OPC%20Foundation%20Security%20Bulletin%20CVE-2022-29866.pdf
原文始发于微信公众号(博智非攻研究院):【漏洞复现】OPC UA 栈耗尽拒绝服务漏洞