-
安全产品
-
-
-
OPC UA协议漏洞影响大量工业环境
发布时间:
2022-09-08
来源:
作者:
访问量:
46
JFrog安全研究团队在今年四月份参加了专注于ICS的Pwn2Own黑客竞赛,并在比赛期间披露了两个漏洞,涉及基于Unified Automation C++的OPC UA服务器SDK。
研究人员利用释放后使用(UAF)漏洞在OPC UA C++服务器上进行了DoS攻击,以及利用堆栈溢出漏洞(CVE-2022-29866)在OPC UA.NET服务器上进行了DoS攻击。
工业控制系统中的拒绝服务(DoS)漏洞可允许攻击者破坏关键操作。例如在用于运动控制的控制器上,利用拒绝服务漏洞可能会中断工厂的生产线,或由于运动部件之间的错位而造成物理损坏。
除了在Pwn2Own比赛期间披露的这两个漏洞之外,JFrog研究人员还向Unified Automation披露了另外八个漏洞,这些漏洞均已在SDK 1.7.7版本中修复。
近日研究人员披露了其中两个漏洞的详细信息,一个是信息泄露,另一个是堆溢出,攻击者可以在UA的C++ OPC演示服务器上实现远程代码执行。C++ OPC演示服务器是一个OPC UA服务器,可以展示OPC UA的能力。
虽然这两个漏洞都会影响UA的OPC UA堆栈,但为了利用这两个漏洞,用户必须通过高权限进行身份验证。在演示服务器中,普通用户和管理员用户的用户名和密码都被硬编码到二进制文件中,在利用漏洞时利用了二进制文件。
一、什么是OPC UA?
OPC UA是一种协议,允许工业设备和端点客户端以安全可靠的方式发送和接收数据。该协议的最大优势在于其统一的API,允许端点客户端使用单一标准API访问由各种工业设备收集的数据,而不是为每个工业设备学习和实现特定的API。
包括OPC UA客户端或OPC UA服务器或在内的任何设备都可以由不同的OPC UA兼容设备替换,甚至来自不同的制造商,并且通信将持续进行,而无需任何进一步的重大更改。
OPC UA被西门子、博世、罗克韦尔自动化、ABB等主要ICS供应商广泛使用。
二、OPC UA.NET堆溢出漏洞
研究人员在黑客竞赛中使用的OPC UA服务器之一是OPC UA.NET标准服务器,是OPC基金会提供的C#中OPC UA服务器的实现。研究人员能够通过导致拒绝服务的堆栈溢出漏洞使服务器崩溃。
据GitHub称,该服务器目前被286个其他存储库使用,包括微软的工业IoT存储库,该存储库可在现场发现工业资产并自动将其注册到云中。
处理TranslateBrowsePathsToNodeId请求的代码中有一个递归。由于超出最大递归限制后发生堆栈溢出异常,递归可能会导致服务器崩溃。try..catch无法捕获此异常。1.4.368.58之前的所有版本都会受到影响。
该漏洞编号为CVE-2022-29866,CVSS得分为7.5分,是高危漏洞,威胁行为者可利用恶意客户端在公开HTTPS端点的服务器中触发堆栈溢出异常。
三、OPC UA服务器UAF漏洞
研究人员在竞赛中使用的OPC UA服务器之一是Unified Automation的OPC UA C++演示服务器,这是一个由Unified Automation提供的用C++实现的OPC UA服务器,作为OPC UA服务器实现的参考。研究人员能够使用导致拒绝服务(DoS)的释放后使用(UAF)漏洞使服务器崩溃。
在Unified Automation的C++演示服务器中存在一个释放后使用(UAF)漏洞,可能导致拒绝服务,并可能导致远程代码执行。该UAF漏洞是由于调用C++演示服务器导出给用户的两个特定方法时缺少同步原语造成的。
OPC UA允许服务器以与RPC类似的方式,通过发送调用消息来导出可由客户端调用的方法。导出的方法可以异步调用。在OPC UA C++演示服务器中,存在可能导致UAF的竞争条件,从而导致多种影响,包括拒绝服务。
研究人员分享了利用该漏洞导致远程代码执行的策略,然而该方法并不足够稳定。首先生成另一个线程,尝试以相同大小的m_pDynamicNode进行分配,以便从分配器中“抓取”释放的m_pDynamicNode的对象。
随后在堆中喷洒一个虚假的vtable,vtable包含一个堆栈迁移小工具,可以更好的控制最终ROP链的执行。可以利用C++服务器,使用输入编写任意大小的字符串数组,这些字符串中的每一个都可以用作带有小工具的虚假vtable。最后使用ROP链弹出shell。
四、越界读取信息泄露漏洞
Unified Automation基于C++的OPC UA客户端服务器SDK中的UaUniString::UaUniString()函数容易受到越界读取漏洞的影响,可允许远程身份验证的攻击者泄露技术数据信息。
OPC UA协议允许读取和写入节点(nodes),节点是OPC UA协议中的基本数据容器类型。每个节点都有与其关联的类型,例如字符串、整数、双精度、联合等。可以使用协议的读和写请求对节点进行读写。例如UA C++演示服务器允许读取和写入字符串和字符串数组。
UaUniString::UaUniString是一个构造函数,用于将驻留在other参数中的UTF-8字符串转换为将保存在UaUniString对象中的UTF-16字符串。该UaUniString::UaUniString函数容易受到越界读取漏洞的攻击。
该函数在第一个for循环通过iWLen变量计算字符串的长度。当循环到达一个特殊字符时,例如0xE0,会将用于索引other(i变量)的变量增加一个以上,而不检查此操作是否会跳过other空终止符,因此导致iWLen大于原始字符串的长度。
长度计算后,函数根据iWLen为转换后的字符串分配一个新的UTF-16数组。之后,第二个for循环复制具有之前计算的长度的字符串,会将0x80下的任何字符复制到新缓冲区中,除了一些特殊字符将返回为。
因为新的字符串缓冲区将被写入iLen,可能超出范围,所以新字符串将包含“泄露”的数据,特别是堆内存继承了原始字符串。
通过在OPC UA协议中对字符串节点的读取请求中使用index_range参数,服务器调用该函数并将数据返回给客户端。
由于可以写入演示服务器中的任意节点,例如Unified Automation的OPC UA服务器开发,因此可以触发漏洞,并获得返回的越界内存。
为了在演示服务器之外利用该漏洞,只要服务器导出一个可以读写的字符串,就可以利用该漏洞。
五、PubSub堆溢出漏洞
Unified Automation基于C++的PubSub堆栈中的replaceArgEscapes()函数容易受到越界写入漏洞的影响,经过身份验证的远程攻击者可导致拒绝服务,或在某些情况下实现远程代码执行。
UaString::arg()函数将格式字符串作为输入,并返回一个新字符串,其中字符串中每个%1序列都替换为提供的参数。例如“%1.%2”.arg(s1).arg(s2),如果s1本身包含%1,那么下一个arg()调用将粘贴s2最初s1应该放置的位置。
UaString::arg()调用findArgEscapes(ArgEscapeData *d, const UaString *s),将d->occurences设置为格式字符串中最低参数id的数量,即%1%1%2函数将仅计算“%1”出现的次数,因此设置d->occurences为2。该函数还设置d->escape_len字符串中所有参数的累积长度,因此%1%1的长度为4。
稍后UaString::arg()将调用replaceArgEscapes()以用给定的参数字符串替换最低的参数id。replaceArgEscapes()将分配一个足够大的缓冲区,以包含替换后的字符串。
然而这段代码中存在整数溢出。该代码计算所需的分配大小,并将结果分配给一个无符号整数。当参数太大时,此计算可能会导致整数溢出。
例如如果格式字符串包含0x10000次重复%1,arg_size(替换数据的大小)为0x10001字节长,field_width为1,则d->occurrences为0x10000,fmt_string_size为0x20000,d->escape_len也为0x20000。这些数字的结果为0x10001*0x10000+0=0x10000,这将导致分配的缓冲区大小小于预期。
稍后,replaceArgEscapes()将格式字符串复制到分配的缓冲区,对于每个参数槽(“%1”),将写入参数字符串。这将导致堆越界写入,并可被用于远程代码执行。
UA的OPC服务器支持PubSub协议,该协议通过MQTT或UADP协议发布数据。在OPC服务器中具有管理员权限的用户可以将PubSub配置上传到服务器,以定义从中获取数据的数据集。实现身份验证方法留给最终用户,因此任何身份验证方法都是可能的。
在演示服务器中,验证方法是简单的明文比较,然而这种身份验证方法并不安全,因为攻击者可以通过使用计时攻击来暴力破解密码。
作为PubSub配置解析的一部分,OpcUa::DataSetReaderType::setMirror()如果定义了镜像读取器数据集,即复制另一个读取器数据集的数据集,则将调用该函数。该setMirror()函数将UaString::arg()多次调用,以便为数据集的新生成字段设置名称。
六、缓解措施
● 建议采取以下防御措施,将利用这些漏洞的风险降至最低:
● 利用天地和兴漏洞扫描管理系统HX-IVSS全面精准地检测信息系统中存在的各种脆弱性问题,包括各种安全漏洞、安全配置问题、不合规行为等,在信息系统受到危害之前为管理员提供专业、有效的漏洞分析和修补建议。并结合可信的漏洞管理流程对漏洞进行预警、扫描、修复、审计,防患于未然。
● 尽量减少所有控制系统设备及系统暴露在网络上,并确保无法从互联网访问;
● 在防火墙后定位控制系统网络和远程设备,并与业务网络隔离;
● 当需要远程访问时,使用安全方法,例如使用VPN。
参考链接:
【1】https://jfrog.com/blog/satisfying-our-way-into-remote-code-execution-in-the-opc-ua-industrial-stack/
【2】https://jfrog.com/blog/crashing-industrial-control-systems-at-pwn2own-miami-2022/
【3】https://www.zerodayinitiative.com/blog/2022/4/14/pwn2own-miami-2022-results
【4】https://research.jfrog.com/vulnerabilities/
上一条:
下一条:
相关资讯
关注我们