写在前面前面我们分享了工控安全相关的很多东西:西门子S7、OPC等工业协议分析与工业漏洞挖掘西门子、施耐德、罗克韦尔PLC程序设计漏洞探秘西门子S7 1200/1500通信协议分析与漏洞攻击实验工控系统PLC被攻击的种类与过程讲解(以西门子、施耐德PLC为例)西门子S7-1200伪造以太网Mac进行PLC网络攻击实验今天来聊一聊针对西门子S7-300控制器的远程攻击工具~
1. 简介
工业控制系统(ICS)中的可编程逻辑控制器(PLC)直接连接到物理过程,如生产线、电网和其他关键工厂。它们配备了控制逻辑,定义了如何控制和监测过程的行为。因此,它们的安全性、耐用性和可预测的响应时间是主要的设计问题。不幸的是,大多数工业控制器的设计并不具有抵御网络攻击的能力。这意味着,如果PLC被破坏,那么由PLC控制的物理过程也会被破坏,这可能导致灾难性的事件。原则上,对手首先要渗透到ICS网络中,与目标设备进行通信,或者获得PLC的物理访问权,以便对目标进行攻击。控制逻辑定义了PLC如何控制一个物理过程,但不幸的是,它很容易被恶意修改,因为PLC要么不支持控制逻辑的数字签名,要么ICS操作员不使用/配置它们。这种恶意修改的一个很好的例子是Stuxnet[1]。这个恶意软件的目标是专门与变频器连接的西门子S7-300 PLC[2]。它感染了PLC的控制逻辑,以监测所连接电机的频率,只有当频率在某个正常范围内(即807赫兹和1210赫兹),才会发起攻击。该攻击包括通过周期性地改变电机速度,从1410赫兹到2赫兹到1064赫兹,然后再重复,从而破坏电机的正常运行。
我们研究了对手如何根据不同的现有漏洞来利用暴露的PLC。我们使用我们的IHPAttack工具进行了这项工作中提出的所有攻击方案,该工具发起了一系列的攻击,旨在对控制过程造成物理伤害。我们的前两次攻击采用侦查的方式来发现工业网络上的可攻击PLC,同时也收集关于目标软件块的关键数据。然后,我们展示了如何在目标有密码保护的情况下绕过认证。之后,我们根据在TIA门户和PLC之间捕获的旧数据包进行了三种重放攻击方案:(设置一个新的)/(更新当前的)密码,清除软件块,以及打开/关闭设备。这些攻击使用户无法到达PLC,造成拒绝服务的情况以及硬件/软件错误。我们还表明,一旦我们绕过了身份验证,例如,我们设法上传了目标设备运行的机器字节码,然后通过将字节码映射到相应的STL指令来检索源码,之后我们修改了当前的机器代码,再将受感染的代码推回到PLC中。
本文的贡献是设计了一个新的攻击链来利用S7-300 PLCs。我们使用以前的方法以及增加新的方法来研究不同情况下对PLC的影响。在第3节给出的工业应用实例中,我们成功地对真实的ICS硬件/软件进行了攻击。本文的其余部分组织如下。我们在第2节开始介绍我们的相关工作,然后在第3节描述我们的实验装置,并在第4节说明攻击的细节。在第5节中,我们提出了一些可能的缓解方案来保护我们的系统,并在第6节中总结了本文。
2. 相关工作
控制逻辑漏洞的信息来自几个来源:ICSCERT[10],国家漏洞数据库(NVD)[13],以及漏洞数据库[14]创建的进攻性安全。然而,研究人员在执行不同的攻击场景中发现了各种类型的漏洞,例如,ICSA-11-223-01A[15]允许对手在一系列西门子控制器中编程和配置控制逻辑程序。这个漏洞是由于可能暴露了用于限制未经授权访问西门子控制器的产品密码而造成的。基于这个漏洞,以前的一些工作,如[3, 16-18]成功地绕过了西门子PLC的认证。我们的工作提出了一种基于Scapy库的S7认证绕过方法,正如我们在后面的§4.3节中所展示的。CVE-2019-10,929[19]也表明,处于中间人位置的对手能够修改在102/TCP端口上交换到SIMATIC控制器的网络流量。这是由用于完整性保护的计算中的某些属性造成的。如果控制逻辑程序通过这个端口进行通信,就有可能在不被注意的情况下隐蔽地改变代码。我们在本文中还表明,攻击者有能力检索、修改和注入自己的代码到PLC中。Beresford在2011年美国黑帽大会上介绍了一个被引用最多的SCADA攻击描述[3]。他演示了如何从远程内存转储中提取凭证。此外,他还展示了如何通过回复攻击来启动和停止PLC。我们的工作不同的是,我们提出了针对PLC的更复杂的攻击,即改变逻辑程序,删除软件块,最终导致严重的损害。
Langner所做的一项工作"14个字节的定时炸弹"[4]描述了如何将流氓逻辑代码注入PLC。Meixell和Forner[5]在2013年美国黑帽大会上提出了另一个与Langner的攻击类似的攻击。作者提出了利用PLC的不同方法,介绍了如何去除逻辑代码的安全检查。McLaughlin[6]发表了一篇PLC恶意软件论文,提出了一个动态有效载荷生成的基本机制。他的方法是基于符号执行,恢复了布尔从PLC逻辑代码中获取逻辑。由此,他试图确定PLC的不安全状态,并生成代码来触发这些状态之一。McLaughlin发表了一篇后续论文[7],该论文以一种通过模型检查的方式将代码自动映射到预定义的模型中的方式扩展了他之前的方法。通过他的模型,他可以指定一个期望的行为并自动生成攻击代码。我们还在一个实验中证明,攻击者也可能在映射代码的基础上夺走控制权,而且不需要向原始机器代码添加任何外部指令或函数。2019年,一组研究人员提出了一个对PLC控制逻辑的自主全攻击链[8]。他们在目标PLC中自动引入了一个恶意的逻辑。他们的工具只针对施耐德电气推出的M221 PLC。
我们的工具不仅引入了注入式攻击,还引入了其他类型,针对控制逻辑和软件块。2015年,一个名为PLCinject的工具在美国黑帽大会上亮相[9]。作者开发了一个在PLC中运行的原型端口扫描器和代理,以便将攻击者的代码注入到PLC的现有逻辑代码中。他们分析并观察了时间效应,发现增强的代码与非增强的代码是可以区分的。相比之下,我们不仅提出了一个网络扫描器,而且还提出了一个扫描深入的方法来收集非常关键的数据。此外,我们设法在没有任何外部功能的情况下修改用户程序。在[11]中介绍了一个用梯形逻辑或兼容语言之一编写的梯形逻辑炸弹恶意软件。这种恶意软件是由攻击者插入到PLC的现有控制逻辑中。这种情况下,攻击者需要熟悉PLC的编程语言。我们表明,攻击者仍然可以在事先不了解用户程序或代码编写语言的情况下破坏PLC。最近的一项工作提出了一个名为ICSREF的逆向工程攻击[20],它可以自动生成针对目标系统的恶意有效载荷,并且不需要像我们的[12]那样对ICS有任何预先的了解。我们展示了针对工业系统的共模故障攻击,该系统由用于恢复的冗余模块组成。这些模块通常用于核电站环境中。作者使用DLL劫持来拦截和修改工程站和PLC之间发送的命令-37数据包,并可能导致所有模块失效。
3. 实验设置
在这一节中,我们描述了我们的实验装置,从要控制的过程开始,介绍了之后使用的设备。
3.1 要控制的物理过程
在我们的实验中,我们使用了以下应用实例(2-PLCs.application)。有两个装满水的水族箱,水被从一个抽到另一个,直到一个达到一定水位后,泵的方向就会倒转,见图1。两个PLC通过S7通信连接,并通过网络交换数据来控制每个水族箱的水位。在这个设置中,控制过程是循环运行的,具体如下。
图1 控制过程应用实例
– PLC.1(S7 315-2DP)读取来自传感器1、2、3和4的输入信号(见图1)。安装在两个水族箱上的两个上部传感器(编号1、3)在水族箱充满水时向PLC.1报告,而两个下部传感器(编号2、4)在水族箱空时向PLC.1报告。
– 之后,PLC.1通过使用IE-CP(CP 343-1 Lean)的S7通信将传感器的读数发送到PLC.2(S7 315-2PN/DP)。
– 然后,PLC.2根据从PLC1接收到的传感器读数,开启/关闭泵的电源。
3.2 硬件设备
合法用户 - 这是一个使用TIA Portal软件连接到PLC/CP的设备。这里,我们使用15.2版本1和Windows 72作为操作系统。攻击者机器–它是一个在没有适当凭证的情况下偷偷地连接到系统的设备。在我们的实验中,攻击者使用操作系统LINUX Ubuntu 18.04.1 LTS3运行在一台笔记本电脑上。PLCs S7-300 -如前所述,我们在实验中使用西门子产品,特别是300系列的CPU。这项工作中使用的PLC是S7 315-2 PN/DP。5和S7 315-2 DP。CP 343-1 Lean -是一个工业以太网通信处理器(CP)。除了与其他以太网站进行通信外,该CP还可以连接外部I/O模块,即PROFINET IO控制器或IO设备。四个电容式接近传感器 -在我们的测试平台上,这是四个来自Sick的传感器,型号为CQ35-25NPPKC1。8感应范围为25毫米,电气线路为直流四线制。两台泵–这里,两台来自Aqua Medic的DC-Runner 1.19带有透明的泵壳,0-10v连接,用于外部控制,最大抽水输出1200 I/h,最大抽水高度:1.5米。3.3 攻击者模型和攻击面
关于我们考虑的攻击类型,我们假设攻击者已经进入网络,并且能够使用我们的工具通过S7 315-2PN/DP CPU的102号端口向PLC发送数据包。我们还假设攻击者没有安装TIA Portal软件,也没有事先了解PLC控制的实际过程、PLC的连接方式、PLC使用的通信协议、或每个PLC上运行的逻辑程序。在这项工作中,攻击面是设备设计和软件实现的结合;更确切地说,它是网络堆栈、PLC特定协议和PLC操作系统的实现。
4. 攻击细节,实施和报告
由于现有报告的漏洞,攻击者可能会进行一些针对工业环境的攻击。在这一节中,我们详细介绍了IHPAttack工具允许对章节中给出的示例应用程序进行攻击的情况。在这项工作中,我们利用著名的库,如Scapy10和Pythonsnap711以及互联网上公开的信息。
4.1 侦察攻击
攻击者的早期目标是发现本地交换网络,以获得网络中可攻击的PLC的概况。为了收集我们系统中可用设备的数据,我们使用了一个基于PROFINET DCP识别-响应数据包的名为PNIO Scanner的功能。从技术上讲,这个函数向发起的接口(在我们的例子中是eno1)发送一个DCP识别请求,并等待所有发现的设备(PLC、IE CP…等)的回答。然后,它在预定的5秒时间间隔内嗅探响应,最后将嗅探的所有结果保存在一个python字典中,以便进一步使用。执行我们的PNIO扫描器功能的输出结果如图2所示,可以分解为以下步骤。
获取本地IP、端口和子网计算子网的IP地址设置TCP连接发送DCP身份请求接收DCP响应在Python响应文件中保存响应停止扫描并断开TCP连接图2 执行PNIO扫描器功能的输出4.2 深入扫描PLC
攻击者成功扫描后,目标的所有IP和MAC地址都已知道。下一步是获得目标设备的洞察力。因此,攻击者开始收集控制器的软件块的数据,使用查询和运行脚本来找出哪些PLC拥有的软件块、软件程序运行的复杂性、逻辑程序的大小等。在这项工作中,我们的工具中使用了一个名为Inner Scanner的专用函数来收集目标的关键数据。我们在算法1中介绍了这个函数的python核心。图3显示了我们函数的执行情况。攻击者得到了PLC的软件块的总列表,块的数量,每个块的大小,等等。这个阶段有助于攻击者从软件角度获得对目标PLC的足够深入的了解,然后利用这些收集到的数据进行进一步的攻击,目标是PLC的软件块,正如我们在接下来的小节中所展示的。请注意,知道机器代码(OB)的大小并保持受感染代码的大小与原始代码相同,可能会使任何潜在的攻击难以被发现。
PLC拥有的软件块、软件程序运行的复杂性、逻辑程序的大小等。在这项工作中,我们的工具中使用了一个名为Inner Scanner的专用函数来收集目标的关键数据。我们在算法1中介绍了这个函数的python核心。图3显示了我们函数的执行情况。攻击者得到了PLC的软件块的总列表,块的数量,每个块的大小,等等。这个阶段有助于攻击者从软件角度获得对目标PLC的足够深入的了解,然后利用这些收集到的数据进行进一步的攻击,目标是PLC的软件块,正如我们在接下来的小节中所展示的。请注意,知道机器代码(OB)的大小并保持受感染代码的大小与原始代码相同,可能会使任何潜在的攻击难以被发现。
图3 执行扫描器的输出结果4.3 认证绕过攻击
西门子PLC可能有密码保护,以防止未经授权的访问和篡改逻辑程序的运行。因此,如果不知道PLC的8个字符的密码,用户是不允许从控制器读/写的。然而,我们有两种可能性来绕过密码。一是通过提取密码的哈希值,然后把它推回给PLC;二是通过使用一个有代表性的(纯文本密码,编码文本密码)对的列表来离线破解每个字节。在这项工作中,我们使用算法中所示的函数。来检查目标PLC是否有密码保护,然后使用我们创建的列表 "s7_pass "来强制连接到PLC。一个有趣的事实是,我们成功地连接到了PLC,并禁用了密码保护,从而能够在进一步的攻击中使用Snap7库,而无需认证。
由于泄露了受保护控制器的密码,可以对暴露的PLC进行一些具体的攻击,从简单的重放到更复杂的攻击。在下文中,我们展示了潜在的攻击方案,一旦对手到达PLC,他可能会执行这些方案来控制该设备。
4.4 回放攻击
对PLC的典型重放攻击包括记录与工作站软件发送的某个合法命令/功能有关的数据包序列,然后在以后未经授权将这些捕获的数据包推回目标设备。这显然可能对任何工业系统造成重大损害,如果攻击者设法访问PLC并执行以下任何一种重放攻击。算法。3显示了我们的python脚本的核心,使用Scapy功能运行重放攻击,在每次攻击中替换相应的捕获数据包。
4.4.1 设置PLC的密码
PLC的密码通常只能通过工程站的配置软件来设置和更新。此外,在更新当前密码的情况下,必须先提供旧的密码,才能成功应用任何更改。但由于PLC访问控制的漏洞,我们可以在PLC没有密码保护的情况下设置新的密码,或者在有密码保护的情况下更新当前密码。从技术上讲,当密码写在PLC上时,它实际上被嵌入到SDB块中。准确地说,是在图4所示的块号0000中。因此,在执行任何功能或命令之前,加载过程首先检查SDB中的这个块,看是否已经设置了密码。我们这里有两种情况。
图4 S7-300 PLC内存结构
– 第一次设置一个新的密码。在这种情况下,我们记录了TIA Portal软件和PLC之间的旧流量会话中使用的密码设置数据包序列,然后我们在加载过程中重放捕获的数据包。对于这种攻击,我们首先需要过滤记录的数据包,只保留负责覆盖0000块的数据包,而忽略其余的数据包,以避免改变当前配置。
– 用一个新的密码更新旧的密码。如果内存块0000已经包含一个密码,我们的实验表明,我们实际上无法像第一种情况那样通过重放记录的数据包来覆盖它。这是由于每当我们试图覆盖SDB时,PLC会不断发送FIN数据包。为了克服这个问题,我们首先清除了0000块的内容,然后重放了与前一个场景(设置新密码)中使用的数据包相同。由于没有合法的命令可以直接清理0000块,我们基本上使用一连串的数据包来删除不同的块,并修改它们以满足我们的需要(删除0000块)。基于这种方法,我们成功地更新了密码,即使不知道旧的密码。这就防止了工程软件对PLC的访问。
表1 通过清除某些PLC的软件块所取得的影响
4.4.2 清楚PLC的内存块
更新密码时的关键是清除SDB块中0000块的内容。这个概念也可以推广到清除其他内存块。这种攻击对工业系统有很大的危害,因为攻击者可以利用PythonSnap7库提供的一些功能来清除不同的内存块,例如OB、FB、DB等。表1列出了分别清除我们目标的每个块所产生的影响。
4.4.3 启动/停止PLC
这是一个非常典型的针对PLC的重放攻击,十年前就已经公布了[3]。然而,我们的工具能够在执行启动/停止CPU命令时,根据已经捕获的PLC和TIA Portal之间的数据包来打开/关闭S7-300 PLC。启动/停止设备的相应数据包如下。
CPU_Start_payload = “0300002502f080321000005000014000028000000000000fd0000 09505f50524f4752414d”CPU_Stop_payload = "0300002102f08032010000060000000002900000009505f5 0524f4752414d"124.5 控制劫持攻击
S7-300 PLC通信协议中缺乏认证措施,可能会使这种控制器也受到其他类型的威胁,即控制劫持攻击。这种攻击的定义是:当对手把目标放在运行在PLC中的逻辑程序上时。试图修改原始机器代码(如改变输入/输出的当前状态),或在原始代码中加入自己的恶意代码,即在用户程序中注入一个函数或指令,并在正常执行过程中执行。这种情况会对目标系统造成严重的物理伤害。
任何下载到西门子PLC的控制逻辑程序通常被分为几个块。对攻击者来说,一个有趣的事实是,运行的代码在执行前不会被设备检查。这意味着,如果攻击者设法下载他的受感染的代码,CPU无论如何都会执行这段代码,而没有部署任何检查机制来检查这段代码是恶意的还是合法的。这使得攻击者可以利用这个漏洞来利用控制逻辑程序。从技术上讲,对于一个简单的程序(如我们的),在CPU中执行的整个机器代码都存储在组织块(OB1)中。在这项工作中,我们提出了我们的工具在窃取字节码、将字节码版本映射到源码版本、修改一对指令、最后将受感染的代码推回给目标时经历的四个阶段,具体如下。
第一阶段:上传字节码 最早的步骤是向PLC请求机器码。通过使用Pythonsnap7库中的 "full_upload (type, block number) "函数,这一步很容易完成。请注意,如果PLC有防止读/写的密码保护,在没有验证用户密码的情况下,PLC会拒绝上传自己的代码。但事实上,对手可以通过在执行该函数前删除密码来克服这一挑战,例如清除0000块。对于我们的例子应用,我们通过将上述函数的参数替换为相应的区块名称和编号,即我们将参数分别设置在OB和1上,成功地将我们的单块程序内容上传到攻击者的机器上。我们在图5中显示了在我们被攻击的PLC上执行这个函数的输出,并且只针对一个区块程序(OB1)。
图5 在我们测试的PLC中执行的字节代码
第二阶段:将字节码映射到STL源代码在下一步,我们应该确定PLC中运行的用户程序的字节码集和相应的STL指令集。为了达到这个目的,我们使用了类似于[21]中提出的离线划分方法,逐一提取我们程序中使用的所有指令,具体方法如下。我们打开TIA Portal软件,用某个代码对我们的目标PLC进行编程,有10次相同的指令。这里,我们使用了对程序没有影响的指令NOP 0。之后,我们将PLC的字节代码上传到攻击者机器上。如图6a所示,这个上传的代码包含了10条NOP 0指令的表示。我们可以确定,每条NOP 0指令在字节码中被表示为OxF000。之后,我们在TIA Portal软件中打开了正常的程序(在我们的例子应用中使用),并在前后插入了NOP 0每条指令,然后将新程序下载到PLC。我们最后将新的字节代码上传到攻击者机器上,并识别出代表每条指令的每个十六进制字节,如图6b所示。在提取了所有指令与相应的Hex-Byte后,我们创建了一个小型的Mapping数据库:HexByte到其相应的STL指令,并使用该映射数据库将原始机器字节码在线转换为其STL源代码。然而,尽管我们的映射数据库只限于我们程序中使用的指令,但这种方法可以发展到将任何逻辑控制程序的所有Hex-字节映射到其STL指令。图7展示了在线映射过程,它将代码块(OB1)的内容作为输入,利用创建的映射数据库来检索STL逻辑程序。
图6 NOP划分方法的例子
图7 机器字节码到STL源代码的映射过程
第三阶段:修改控制逻辑在成功绘制了控制逻辑图后,攻击者现在对PLC中运行的控制过程有了足够的了解,破坏系统所需的一切就像用新指令替换一个或多个指令一样简单。在我们的案例中,我们的程序有两个输出(2个泵),通过修改泵读取的任何输入状态,将破坏物理过程并使系统不正确地工作,例如,在我们的例子应用中,交换低传感器开关在高位传感器开关%I4.4(正常-打开)和%I4.3(正常-关闭)的情况下,由于泵1在水达到所需的水平之前就关闭和打开,将混淆过程。这将导致实际工业系统中的物理损坏。请注意,在这种情况下,被感染的代码大小与原来的一样(130KB),因为我们只是交换了指令,没有增加任何新的指令。我们发现在执行攻击者代码时,这种攻击方案不会导致代码大小和周期时间的增加。
第四阶段:下载修改后的代码攻击者需要做的最后一步是用上一步创建的受感染的代码替换原始代码。至于上传操作,反之,我们能够从攻击者那里下载受感染的代码通过使用Pyhton-Snap7库中的 "Cli_download (type, block number) "函数,攻击者可以跳过前三个阶段,直接用完全新的机器代码来取代原来的机器代码,甚至不知道PLC运行的程序。攻击者可能会跳过前三个阶段,只用一个全新的机器代码来取代原来的机器代码,即使不知道PLC运行的程序。这只是在IT主管部门没有实施安全手段的情况下才成立的。然而,我们的方法可以应对这种保护机制。图8显示了由Wireshark捕获的原始和受感染的字节代码。
图8 修改PLC的字节代码5. 可能缓解的方案
我们的攻击表明,S7-300 PLC容易受到不同种类的威胁,因此为了保证工业系统的安全,保护PLC免受网络攻击,我们提出了一些可能的解决方案,以减轻上述攻击的影响。在[22]中提出的PLC防护装置可能是一个可能的解决方案。它拦截并调查任何针对可编程控制器的流量。为了推断出异常情况,通过执行功能代码比较和汇编匹配技术,将打算执行的代码与各种安全基线标本进行比较。这允许操作者批准或拒绝转移,使用一个受信任的设备,该设备明显难以被攻击者颠覆。另一个可能的解决方案可能是[23]中提出的解决方案。它是一种基于运行时行为的针对PLC有效载荷攻击的检测机制。这使得操作者可以监控PLC固件。在ICS中实施这样的方法,可以识别各种各样的PLC有效载荷攻击,从而有效地检测出任何可能的针对PLC运行的攻击。西门子还提供一种名为SCALANCE的特殊硬件模块,以确保工业控制系统的安全。这个模块使用网络分段机制来发布访问认证,只允许在定义的参与者之间进行数据通信。因此,如果我们把这个模块放在PLC和其他设备之间,它就会减轻任何潜在网络攻击的影响。然而,出于预算和实际的考虑,这种方法还没有在ICS中广泛部署。
6. 结论和未来工作
在本文中,我们的IHP-Attack工具显示,攻击者能够以不同的方式入侵S7-300控制器。从扫描网络开始,查找是否有任何可用的控制器,然后收集关于目标PLC的软件块的关键数据。尽管西门子用8个字符的密码保护他们的设备,但攻击者可以绕过认证,甚至在不知道旧密码的情况下改变密码,阻止合法用户进入PLC。我们还表明,一旦攻击者到达PLC,他就能够进行一系列的攻击,例如重放和控制劫持。我们的实验证明,我们基于S7-300控制器的工业系统需要抵御各种网络攻击。因此,实施安全手段是非常必要的。出于这个原因,我们提出了一些可能的缓解方案,以面对潜在的网络犯罪活动。在未来,我们的目标是通过增加一些功能来发展我们的工具,例如,普及我们的编译方法以检索PLC运行的任何用户程序的源代码,检索密码的纯文本,并针对现代SIMATIC控制器,如S7-1200和S7-1500。这些新的控制器比S7-300/S7-400更强大,并且使用S7Comm Plus协议,该协议具有反重放机制,以及更多的保护手段来检测不同的网络攻击,这将是我们未来的挑战。