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

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

简介

在本文中,我们将为读者详细介绍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,一经查实,立即删除!

相关文章

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…

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

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

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

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

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; &…

发现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™ - …

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

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

hdu--1075--字典树||map

做这题的时候 我完全没想到 字典树 就直接用map来做了 - 我是有 多不 敏感啊~~ 然后去 discuss 一看 很多都是说 字典树的问题.... 字典树 给我感觉 它的各个操作的意思都很清晰明了 直接手写 不那么容易啊。。 晚些 时候 试下来写------用map写是真心方便 只要注意下那么\n的吸…

php的类装载的步骤,设计PHP自动类装载功能

在使用面向对象方法做PHP开发时&#xff0c;可能会经常使用到各个路径中的类文件&#xff0c;这就需要大量的 include 或 require&#xff0c;而 PHP 提供了一个比较快捷的方式&#xff0c;就是利用函数 __autoload 可以编程实现动态的类装载功能&#xff0c;这样就不需要手动的…

网站首页幻灯片

Js页面: View Code /** * 大眼睛广告轮播 */ var indexEye {autoTime: 0,init: function () {var eyeObj $("#dyj_pics a:eq(0) img:eq(0)");eyeObj.attr("src", eyeObj.attr("data-imgSrc"));eyeObj.load(function () {indexEye.autoTime se…

Qt之QAbstractItemView视图项拖拽(二)

一、需求说明 上一篇文章Qt之QAbstractItemView视图项拖拽(一)讲述了实现QAbstractItemView视图项拖拽的一种方式&#xff0c;是基于QDrag实现的&#xff0c;这个类是qt自己封装好了的&#xff0c;所以可定制性也就没有了那么强&#xff0c;最明显的是&#xff0c;这个类在执…

电脑控制苹果手机_必备神器,电脑控制手机

序一款电脑端的神器&#xff0c;它可以任意的操纵你的手机。****QtScrcpy可以通过USB(或通过TCP/IP)连接Android设备&#xff0c;并进行显示和控制。不需要root权限。单个应用程序最多支持16个安卓设备同时连接。同时支持GNU/Linux&#xff0c;Windows和MacOS三大主流桌面平台。…

生活大爆炸版石头剪刀布

题目描述 Description石头剪刀布是常见的猜拳游戏&#xff1a;石头胜剪刀&#xff0c;剪刀胜布&#xff0c;布胜石头。如果两个人出拳一样&#xff0c;则不分胜负。在《生活大爆炸》第二季第8集中出现了一种石头剪刀布的升级版游戏。升级版游戏在传统的石头剪刀布游戏的基础上&…

jquery事件 on(),live(),delegate(),blind()

jQuery推出on()的目的有2个&#xff0c;一是为了统一接口&#xff0c;二是为了提高性能&#xff0c; 所以从现在开始用on()替换bind(), live(), delegate吧。 尤其是不要再用live()了&#xff0c;因为它已经处于不推荐使用列表了[1.7已经被删除]。 如果只绑定一次事件&#xff…

用python庆祝生日_生日到底该过阴历还是阳历好呢?不是迷信,都怪我们大意!...

过生日到底该过阴历还是阳历&#xff1f;答案说出来你可能都不信在我们国家&#xff0c;过生日有两种不同的方式&#xff0c;因为有两种不同的日子的计算方式&#xff0c;分为阴历和阳历。一般来说&#xff0c;在农村和一些比较落后的地方&#xff0c;人们习惯于用阴历来计算生…

WSS3.0自带数据库可以使用SQL 2005 Server Management Studio来管理

默认情况下&#xff0c;安装完WSS3.0后&#xff0c;会自动安装一个自带的SQL Server 2005 Embedded Edition数据库&#xff0c;但是此数据库却没有管理工具,不像安装SQL 2005其它版本会有管理工具。如果你要管理数据库&#xff0c;这时怎么办呢。经过俺试了一上午了&#xff0c…

CPU的高速缓存存储器知识整理

基于缓存的存储器层次结构 基于缓存的存储器层次结构行之有效&#xff0c;是因为较慢的存储设备比较快的存储设备更便宜&#xff0c;还因为程序往往展示局部性&#xff1a; 时间局部性&#xff1a;被引用过一次的存储器的位置很可能在不远的将来被再次引用。 空间局部性&#x…

uniapp光标自动定义到文本框_word技巧自动生成毕业论文目录

一篇word文档&#xff0c;内容有大的章&#xff0c;小的节。如何把章节抽出来生成目录&#xff1f;WORD →点击需要插入的地方 → 插入菜单 → 索引和目录 → 目录 → 确定。1 创建标题目录Word 一般是利用标题或者大纲级别来创建目录的。因此&#xff0c;在创建目录之前&#…

JSTL

2019独角兽企业重金招聘Python工程师标准>>> 说明 JSTL 是 JAVA 中的一个定制标记库集。实现了JSP页面中代码的复用&#xff0c;增加了JSP页面的可读性&#xff0c;方便查看和参与开发 使用 1.下载地址 http://archive.apache.org/dist/jakarta/taglibs/standard/bi…

自然语言0_nltk中文使用和学习资料汇总

sklearn实战-乳腺癌细胞数据挖掘&#xff08;博主亲自录制视频教程&#xff09; https://study.163.com/course/introduction.htm?courseId1005269003&utm_campaigncommission&utm_sourcecp-400000000398149&utm_mediumshare http://blog.csdn.net/huyoo/article/…