请求做女朋友的网站源码,免费发布招聘信息,开封景区网站建设项目方案,爱链接更多全球网络安全资讯尽在邑安全简介在本文中#xff0c;我们将为读者详细介绍Claroty Research团队的Amir Preminger和Sharon Brizinov是如何组合利用两个漏洞#xff0c;来触发施耐德工控软件EcoStruxure Operator Terminal Expert的代码执行漏洞#xff0c;从而在首届举办… 更多全球网络安全资讯尽在邑安全简介在本文中我们将为读者详细介绍Claroty Research团队的Amir Preminger和Sharon Brizinov是如何组合利用两个漏洞来触发施耐德工控软件EcoStruxure Operator Terminal Expert的代码执行漏洞从而在首届举办的Pwn2Own迈阿密大赛上赢得了2.5万美元奖金。这里所述的漏洞存在于施耐德电气公司的EcoStruxure Operator Terminal Expert软件的V3.1.100.267(SP 1)和之前版本(以前称为Vijeo XD)中。实际上攻击者只要引诱受害者打开(双击)EcoStruxure Operator Terminal Expert软件的项目文件就能够利用默认配置发动相应的漏洞。这时将触发应用程序上下文中的代码执行漏洞。总的来说要想成功利用这个代码执行漏洞需要组合利用下文描述的两个已知的漏洞。在本文中我们先按照漏洞被发现的顺序来描述其详细信息然后给出组合运用这些漏洞并实现命令执行攻击所需的具体步骤。下面我们先给出相应的演示视频的地址https://youtu.be/SAmhljE9ZlE。漏洞详情EcoStruxure Control Terminal Expert是一个软件环境用于设计人机界面(HMI)设备的图形用户界面。这些用户界面用于控制工业部署中可编程逻辑控制器 (PLC) 的操作。图1 使用EcoStruxure Control Terminal Expert设计水流控制在这里所有的项目信息包括各种设置和图形组件的信息都会被保存到一个后缀为.VXDZ的EcoStruxure Control Terminal Expert项目文件中。实际上.VXDZ项目文件就是一个存放各种文件的压缩目录这些文件包含了程序还原项目所需的全部信息以便工程师在以后可以继续工作。项目文件主要包括以下几种文件类型.dbSQLite3数据库文件包括各种项目配置和设置。.inf/.datJSON文件用于存储数据和设置。例如每个屏幕及其图形组件都是用JSON表示的。图2 项目目录当工程师打开项目文件时压缩后的目录会被解压到一个临时目录下路径如下所示C:\users\USER\AppData\Local\EcoStruxure\Temp\Schneider\CURRENT_VERSION_FULL\GUID\ProjectFiles为了便于后面进行参考我们将路径中与环境有关的组件用红色进行了相应的标记。另外橙色显示的是GUID它是在每次打开一个项目时随机生成的即使这个项目之前已经打开过亦是如此。这意味着这个路径无法提前预测因为它取决于当前登录的用户、当前具体的版本名以及一次性随机生成的GUID。例如下面就是我们打开一个项目文件时生成的一个有效的路径C:\Users\Administrator\AppData\Local\EcoStruxure\Temp \Schneider\Imagine3.1ServicePack\A1A98F0B-9487-41B3-84A2-2195ECAA11F5\ProjectFiles此外由于所使用的.NET zip库能够防止路径遍历企图因此只能提取随机生成的目录。高级功能与任何安全研究一样我们需要尽量熟悉目标产品并寻找那些可能没有被厂商深入检查过的复杂/先进功能。在把玩一阵EcoStruxure Control Terminal Expert后我们发现了一个名为“Drivers”的功能。由于HMI是智能屏幕呈现的数据是从工厂内的现场控制器收集的所以必须具备查询功能才能从PLC中获取数据。为了达到这个目的施耐德提供了这样一种机制即在项目中添加一个特定厂商的驱动程序该驱动程序能够查询PLC以获取所需数据。我们知道PLC有许多不同的型号并且每个PLC都是通过自己的协议进行通信的。正因为如此施耐德提供了许多的驱动程序工程师可以根据他们需要集成的PLC自行选用。图3 驱动程序是帮助HMI与所需控制设备(PLC)进行通信的组件。每个供应商及其特定设备(生态系统、协议栈等)都会提供许多不同的驱动程序。有关特定项目文件使用的驱动程序的所有信息都位于一个名为DriverConfig.db的SQLite3数据库文件中我们可以在项目目录中找到这个文件。我们在项目中添加了一个新的驱动程序并检查了DriverConfig.db文件发现其中有三个数据表Driver_X空表。Driver_X_Configuration_X关于驱动程序的详细信息如设置和元数据。这其中包括将要加载的驱动程序/模块名称。图4 DriverConfig.db的内容Driver_X_Equipment_X关于HMI将与之通信的PLC的详细信息。其中会包括与PLC相关的信息如IP地址、型号、协议等。其中X代表驱动索引由于我们只添加了一个驱动所以在我们的例子中X为0。通过.NET反射器我们研究了相关的中间语言(IL)代码。我们发现ModuleName字段实际上就是驱动程序DLL它将从预定义的目录中进行加载并处理HMI和PLC之间的通信。例如如果我们有一个Rockwell Automation公司的PLC我们就需要加载Rockwell公司相应的驱动程序——它通过EtherNet/IPCIP协议与PLC进行通信。具体这里来说需要加载驱动程序RockwellEIP.dll。为此我们可以在该项目中的SQLite3数据库文件DriverConfig.db中的Driver_0_Configuation_0表的ModuleName列(字段)中加以指定。图5 打开DriverConfig.db数据库的SQLite3查看器。ModuleName字段是驱动DLL的名称它将被加载并处理HMI和PLC之间的通信。Bug No. 1通过路径遍历以获取DLL加载原语为了更好地理解如何从DriverConfig.db数据库中提取信息我们钻进了一个“兔子洞”DriverConfig.db的连接。我们可以看到这里的代码会查询并提取Driver_x_configuration_0表中的所有属性。然后它将一个新的Driver对象实例化并根据表中找到的相应值设置ModuleName字段。最后它使用 ModuleName字段指定的路径加载相应的驱动程序DLL文件。由于数据库(包括ModuleName字段)在我们的掌控之下我们可以提供一个带有一些 ../../../字符的自定义ModuleName以便从包含合法驱动程序的应用程序定义目录中导航出来。换句话说我们能够从系统中加载任意DLL。图6 我们将ModuleName字段改为../../../../claroty.dll并使用procmon来监控系统。然而我们的攻击要想成功必须满足下面两个条件如果一个名为driver.xml的文件没有出现在将要加载的DLL旁边那么该DLL将不会被加载。加载的DLL必须位于同名的目录中。例如如果我们将ModuleName改为Claroty软件将进入预定义的驱动程序目录C:\Program Files\Schneider Electric\EcoStruxure Operator Terminal Expert 3.1 Service Pack\Drivers\Drivers并寻找名为Claroty的目录然后在该目录中搜索Claroty.dll和Driver.xml。如果这两个文件都找到了就会加载里面的DLL在本例中就是C:\Program Files\Schneider Electric\EcoStruxure Operator Terminal Expert 3.1 Service Pack\Drivers\Drivers\Claroty\Claroty.dll。我们通过目录遍历实现了加载任意DLL的原语这真是太棒了。但是现在面临的问题是我们如何才能提供自己的DLL并使其运行呢好吧在一定程度上说我们还需要一个具有“任意文件写入”功能的原语。回想一下我们的项目文件实际上就是一个包含文件和目录的压缩容器。也就是说我们可以添加我们的文件和目录然后再重新打包项目文件。当软件打开项目文件并提取所有文件时我们添加的文件也会和其他文件一起被提取出来(并保存到临时目录中)。现在唯一的问题是我们如何才能提前知道我们的文件会被解压到哪里这样我们就可以在DriverConfig.db数据库下的ModuleName属性中设置相应的路径了。下面我们来总结一下我们可以利用目录遍历漏洞来跳出正常的驱动程序的目录同时我们也可以在我们的项目文件被提取的时候把一些文件和目录保存到硬盘上。但是这些文件会被提取到一个随机的临时目录我们无法提前预知因为GUID每次都是随机生成的。Bug No. 2未进行严格安全过滤导致敏感数据信息泄露我们对这些问题思考了很久后来终于想到了一个解决方案。这个解决方案来自于一个意想不到的领域SQLite的魔术我们使用SQL pragma和SQL views数据库功能实时生成提取目录的完整路径。因此我们可以让Terminal Expert软件直接找到我们的恶意DLL。我们之所以能够做到这一点是因为Terminal Expert软件加载了我们所控制的项目文件中提供的数据库并在没有对数据进行适当安全过滤的情况下查询表格。什么是PRAGMAPRAGMA语句是一个依赖于具体实现的SQL扩展。它可以用来修改SQLite库的操作或者查询SQLite库的内部(非表)数据。例如pragma database_list命令将返回当前连接数据库的列表。而SELECT file FROM pragma_database_list命令则会产生当前加载数据库的完整路径。图7 显示当前加载的数据库的完整路径这意味着我们可以在实时加载数据库之后生成数据库的完整路径。同样这也是在将数据库保存到新建的、具有随机路径的临时目录之后完成的。现在我们只需要一种方法来获取该查询的结果并将其插入到软件即将查询的ModuleName属性中即可。什么是视图为了达到上述目的我们使用了数据库的一个不太常用的功能视图。在数据库中视图是一个存储查询的结果集。换句话说视图就像一个动态创建的表它是在客户端查询时实时生成的。当客户端查询视图时数据库会查询为视图定义的实际表并根据视图的设置对生成的数据进行重组最后将完整的结果反馈给客户端——整个过程对客户端而言是透明的。从客户端的角度来看似乎正在查询数据库中找到的常规表。图8 数据库视图和我们实时影响查询的抽象方案在我们的案例中客户端是EcoStruxure Operator Terminal Expert软件它查询驱动程序数据库以获取ModuleName属性从而可以加载驱动程序DLL。我们的计划是在数据库被提取到临时位置后实时修改ModuleName属性最终让ModuleName保存我们数据库的实际路径。12RCE组合两个漏洞实现代码执行攻击在项目文件中我们需要准备一个名为ClarotyModule的目录其中含有如下所示的两个文件Driver.xmlClarotyModule.dll我们将按照以下步骤准备DriverConfig.db我们将原来的Driver_0_Configuration_0表重命名为Driver_0_Configuration_0_ORIG。我们将创建一个名为Driver_0_Configuration_0的VIEW表。当客户端查询“原来的”表Driver_0_Configuration_0时实际上会查询我们新建的VIEW表。在查询到ModuleName字段后我们将VIEW表的内部处理设置为返回SELECT file FROM pragma_database_list的结果并对其进行必要的修改以构成正确的目录遍历语法。通过这种方式我们可以在文件夹结构中向上、向下导航直到抵达当前的临时目录中也就是我们的payload DLL所在的位置。图9 精心构造一个驱动数据库使其实时包含我们DLL的路径。最后我们把所有的部分重新打包成一个VXDZ项目文件。当受害者双击该文件时我们的DLL将被加载之后我们的代码也将被执行。图10 POC运行时会打开项目文件并执行相应的代码小结在本文中我们为读者详细介绍了如何利用EcoStruxure Operator Terminal Expert读取给定项目文件的方式通过执行一些SQL backflips操作诱导软件加载我们提供的DLL从而在打开项目文件时发动任意代码执行攻击。施耐德电气公司已经修复了这些漏洞并将其分配了相应的编号CVE-2020-7494与CVE-2020-7496。转自先知社区欢迎收藏并分享朋友圈让五邑人网络更安全欢迎扫描关注我们及时了解最新安全动态、学习最潮流的安全姿势推荐文章1新永恒之蓝微软SMBv3高危漏洞(CVE-2020-0796)分析复现2重大漏洞预警ubuntu最新版本存在本地提权漏洞(已有EXP)