驱动提取软件_深入分析施耐德工控软件代码执行漏洞

更多全球网络安全资讯尽在邑安全

简介

在本文中,我们将为读者详细介绍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) 的操作。

51b74beab4cdec5731eda865d77ed11e.png

图1 使用EcoStruxure Control Terminal Expert设计水流控制

在这里,所有的项目信息,包括各种设置和图形组件的信息,都会被保存到一个后缀为.VXDZ的EcoStruxure Control Terminal Expert项目文件中。实际上,.VXDZ项目文件就是一个存放各种文件的压缩目录,这些文件包含了程序还原项目所需的全部信息,以便工程师在以后可以继续工作。项目文件主要包括以下几种文件类型:

  • .db:SQLite3数据库文件,包括各种项目配置和设置。

  • .inf/.dat:JSON文件,用于存储数据和设置。例如,每个屏幕及其图形组件都是用JSON表示的。

eca234091e450f801a548acb4cbb5563.png

图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自行选用。

2ab52242d8807d6f5df6afa82bac8612.png

图3 驱动程序是帮助HMI与所需控制设备(PLC)进行通信的组件。每个供应商及其特定设备(生态系统、协议栈等)都会提供许多不同的驱动程序。

有关特定项目文件使用的驱动程序的所有信息都位于一个名为DriverConfig.db的SQLite3数据库文件中,我们可以在项目目录中找到这个文件。我们在项目中添加了一个新的驱动程序,并检查了DriverConfig.db文件,发现其中有三个数据表:

  • Driver_X:空表。

  • Driver_X_Configuration_X:关于驱动程序的详细信息,如设置和元数据。这其中包括将要加载的驱动程序/模块名称。

c34eac651e0a08b9160933269bd39d00.png

图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/IP+CIP协议与PLC进行通信。具体这里来说,需要加载驱动程序RockwellEIP.dll。为此,我们可以在该项目中的SQLite3数据库文件DriverConfig.db中的Driver_0_Configuation_0表的ModuleName列(字段)中加以指定。

f81f0a289788a7fcc2a9c5b7652b5c8e.png

图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。

cf2132eb1d762d1c1f21e69da13e5931.png

图6 我们将ModuleName字段改为../../../../claroty.dll,并使用procmon来监控系统。

然而,我们的攻击要想成功,必须满足下面两个条件:

  1. 如果一个名为driver.xml的文件没有出现在将要加载的DLL旁边,那么该DLL将不会被加载。

  2. 加载的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软件加载了我们所控制的项目文件中提供的数据库,并在没有对数据进行适当安全过滤的情况下查询表格。

什么是PRAGMA?

PRAGMA语句是一个依赖于具体实现的SQL扩展。它可以用来修改SQLite库的操作,或者查询SQLite库的内部(非表)数据。例如,pragma database_list命令将返回当前连接数据库的列表。

而SELECT file FROM pragma_database_list命令则会产生当前加载数据库的完整路径。

dbb4c5e7721818f3c6b37c2288d905c5.png

图7 显示当前加载的数据库的完整路径

这意味着我们可以在实时加载数据库之后生成数据库的完整路径。同样,这也是在将数据库保存到新建的、具有随机路径的临时目录之后完成的。现在,我们只需要一种方法来获取该查询的结果,并将其插入到软件即将查询的ModuleName属性中即可。

什么是视图?

为了达到上述目的,我们使用了数据库的一个不太常用的功能:视图。在数据库中,视图是一个存储查询的结果集。换句话说,视图就像一个动态创建的表,它是在客户端查询时实时生成的。当客户端查询视图时,数据库会查询为视图定义的实际表,并根据视图的设置对生成的数据进行重组,最后将完整的结果反馈给客户端——整个过程对客户端而言是透明的。从客户端的角度来看,似乎正在查询数据库中找到的常规表。

97acf509827055fdbeaf6c84430de402.png

图8 数据库视图和我们实时影响查询的抽象方案

在我们的案例中,客户端是EcoStruxure Operator Terminal Expert软件,它查询驱动程序数据库以获取ModuleName属性,从而可以加载驱动程序DLL。我们的计划是在数据库被提取到临时位置后,实时修改ModuleName属性,最终让ModuleName保存我们数据库的实际路径。

1+2=RCE:组合两个漏洞,实现代码执行攻击

在项目文件中,我们需要准备一个名为ClarotyModule的目录,其中含有如下所示的两个文件:

  • Driver.xml

  • ClarotyModule.dll

我们将按照以下步骤准备DriverConfig.db:

  1. 我们将原来的Driver_0_Configuration_0表重命名为Driver_0_Configuration_0_ORIG。

  2. 我们将创建一个名为Driver_0_Configuration_0的VIEW表。

当客户端查询“原来的”表Driver_0_Configuration_0时,实际上会查询我们新建的VIEW表。在查询到ModuleName字段后,我们将VIEW表的内部处理设置为返回SELECT file FROM pragma_database_list的结果,并对其进行必要的修改,以构成正确的目录遍历语法。通过这种方式,我们可以在文件夹结构中向上、向下导航,直到抵达当前的临时目录中,也就是我们的payload DLL所在的位置。

7320c7bc1d4b3569864be2116f7f9037.png

图9 精心构造一个驱动数据库,使其实时包含我们DLL的路径。

最后,我们把所有的部分重新打包成一个VXDZ项目文件。当受害者双击该文件时,我们的DLL将被加载,之后,我们的代码也将被执行。

47310fb8b6708e073338f508194e58a7.png

图10 POC运行时,会打开项目文件,并执行相应的代码

小结

在本文中,我们为读者详细介绍了如何利用EcoStruxure Operator Terminal Expert读取给定项目文件的方式,通过执行一些SQL backflips操作,诱导软件加载我们提供的DLL,从而在打开项目文件时发动任意代码执行攻击。施耐德电气公司已经修复了这些漏洞,并将其分配了相应的编号:CVE-2020-7494与CVE-2020-7496。

转自先知社区

欢迎收藏并分享朋友圈,让五邑人网络更安全

fac23bc039f6ced75514477405a077e4.png

欢迎扫描关注我们,及时了解最新安全动态、学习最潮流的安全姿势!

推荐文章

1

新永恒之蓝?微软SMBv3高危漏洞(CVE-2020-0796)分析复现

2

重大漏洞预警:ubuntu最新版本存在本地提权漏洞(已有EXP) 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/260204.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ubuntu 网卡突然无法连接

今天要用到VM BT的Namp扫描服务器端口,发现桥接后无法使用。ifconfig 只看到 lo地址,看不到以太网网卡地址使用lspci 查看是否安装了以太网网卡驱动lscpi | grep Ethernet02:01.0 Ethernet controller: Advanced Micro Devices [AMD] 79c970 [PCnet32 LA…

atitit.表单验证 的dsl 本质跟 easyui ligerui比较

atitit.表单验证的dsl 本质跟 easyui ligerui比较 1. DSL 声明验证 1 2. 自定义规则 1 3. 正则表达式验证,可以扩展实现 2 4. 犯错误消息提示,generic canBeEmpty is good 3 5. Prevent the form to submit when invalid 3 6. 为空则不验证,不为空则验证&#xff0…

StartActivityForResult

StartActivity 用startActivityForResult(intent, requestcode);启动子功能模块activity onActivityResult(int requestCode, int resultCode, Intent data)对子activity返回进行判断处理 public class StartActivity extends Activity implements OnClickListener {private Bu…

micropython 串口写文件_MicroPython通过2G模块串口收发短信

集成2G通信、定位模组,赋予物联网特性。本例使用M6220,它是一款基于eSIM技术的2G模组,支持GSM/GPRS,提供GPS北斗双模定位功能,并具备一定的数据处理能力,其2G工作频段有GSM850、GSM900、DCS1800和PCS1900&a…

洛谷P1130 红牌

题目描述 某地临时居民想获得长期居住权就必须申请拿到红牌。获得红牌的过程是相当复杂 ,一共包括N个步骤。每一步骤都由政府的某个工作人员负责检查你所提交的材料是否符合条件。为了加快进程,每一步政府都派了M个工作人员来检查材料。不幸的是&#xf…

GPS坐标换算

30.8872 》——>300.8872*60 53.232 ——>530.232*60 13.9230: 53 13.92"30: 53 13.92"》3053/6013.92/360030.887199同经度两点之间距离dla30.887m * [差值/(1/3600)] 30.887m * 差值 *3600 111193.2m * 差值 同纬度两点之间距离dlo30.887m * [差值/(1…

企业级应用框架(五)IOC容器在框架中的应用

前言 在上一篇我大致的介绍了这个系列所涉及到的知识点,在本篇我打算把IOC这一块单独提取出来讲,因为IOC容器在解除框架层与层之间的耦合有着不可磨灭的作用。当然在本系列前面的三篇中我也提供了一种基于反射的解耦方式,但是始终不是很优雅&…

后端开发需要学什么_都2020年了,还在纠结学什么语言?| 后端篇

几个礼拜前,一个学弟问我:“Ray,我打算之后要找工作了,不过现在自己没有特别深入的语言,最近想找一门好好学一下,你觉得学什么语言好呀?”我表示:“这个要看你求职方向、个人喜好、市…

python扫描ip的端口打开情况

我们的韩国bss系统上线之后,要求对主机的端口、资源使用进行统计,端口每个主机去看,太费劲了,所以,就写了这样一个小程序,不是很完美但是,可以用啊!哈哈哈,别喷&#xff…

flash java 通信,Flash到JavaScript的通信实例

从HTML可以发送数据到Flash,反过来也可以. 这个例子演示了如何应用Flash的Fscommand来发送数据到Javascript.简要步骤:Flash中新建一个文件,保存为flash_to_javascript.fla创建一个文本域,设置成输入文本(Input Text),选择"border"以便我们能看到他,指定他的变量为in…

10个非常有用的CSS hack和技术

转自&#xff1a;http://www.qianduan.net/10-useful-css-hacks-and-technique.html 1 – 跨浏览器的inline-block <style>li {width: 200px;min-height: 250px;border: 1px solid #000;display: -moz-inline-stack;display: inline-block;margin: 5px;zoom: 1;*display:…

Java的递归算法

递归算法设计的基本思想是&#xff1a;对于一个复杂的问题&#xff0c;把原问题分解为若干个相对简单类同的子问题&#xff0c;继续下去直到子问题简单到可以直接求解&#xff0c;也就是说到了递推的出口&#xff0c;这样原问题就有递推得解。 关键要抓住的是&#xff1a; &…

python list遍历定位元素_python for循环,第二遍定位不到元素?

ycyzharry: 也不行&#xff0c;我的代码import unittestimport timeimport xlrdfrom selenium import webdriverimport seleniumdef open_excel(filefile.xls):try:data xlrd.open_workbook(file)return dataexcept Exception as e:print(str(e))def excel_table_byindex(file…

发现Java程序中的Bug

昨天在CSDN上阅读 "Java中十个常见的违规编码"这篇文章时&#xff0c;无意中找到了3个 "发现Java程序中的Bug"工具。 文章地址&#xff1a;http://www.csdn.net/article/2012-09-11/2809829-common-code-violations-in-java其中&#xff0c; FindBugs™ - …

原生php登录注册,原生php登陆注册

本以为一个登陆注册功能十来分钟就写好了&#xff0c;没想到thinkPHP用久了&#xff0c;原生的php不会写了最开始我直接写了类和方法&#xff0c;在前台传递参数给类的login方法(action"index.php/login"),尝试几次发现无法访问&#xff0c;这才意识到&#xff0c;这…

SpringMVC REST 风格静态资源访问配置

1 在web.xml中使用默认servlet处理静态资源&#xff0c;缺点是如果静态资源过多&#xff0c;则配置量会比较大&#xff0c;一旦有遗漏&#xff0c;则会造成资源无法正常显示或404错误。 <!-- 静态资源访问控制 --><servlet-mapping><servlet-name>default<…

生成对象

var c[name,age,city]; var d[xiaogang,12,anhui]; var a{}; for(var i0;i<3;i){a[c[i]]d[i]; } console.log(a); //返回 {name: "xiaogang", age: "12", city: "anhui"} 转载于:https://www.cnblogs.com/xiaozhumaopao/p/6046823.html

3.寄存器(内存访问)

CPU中&#xff0c;用16位来存储一个字。高8位存放高位字节&#xff0c;低8位存放低位字节。内存存储中&#xff0c;内存单元是字节单元&#xff08;1单元1字节&#xff09;&#xff0c;则一个字要用两个地址连续的内存单元存放。内存存储中&#xff0c;高位字节&#xff0c;和低…

shiro前后端分离_为什么要前后端分离?前后端分离的优点是什么?

随着互联网的高速发展以及IT开发技术的升级&#xff0c;前后端分离已成为互联网项目开发的业界标准使用方式。在实际工作中&#xff0c;前后端的接口联调对接工作量占HTML5大前端人员日常工作的30%-50%&#xff0c;甚至会更高。接下来千锋小编分享的广州HTML5大前端学习就给大家…

POJ 2152 Fire

算是我的第一个树形DP 的题&#xff1a; 题目意思&#xff1a;N个城市形成树状结构。现在建立一些消防站在某些城市&#xff1b;每个城市有两个树形cost&#xff08;在这个城市建立消防站的花费&#xff09;&#xff0c;limit &#xff1b; 我们要是每个城镇都是安全的&#xf…