可编程逻辑控制器(PLC)越来越多地连接和集成到工业物联网(IIoT)中,以实现更好的网络连接和更简化的控制流程。但事实上,这也给其带来了安全挑战,并使其面临各种针对此类设备所控制的物理过程的网络攻击。在这项工作中,我们调查了最新的S7 PLC是否在设计上易受攻击,是否可以被利用。与研究界中存在的典型控制逻辑注入攻击不同,该攻击要求对手在攻击过程中保持在线,本文介绍了一种新的漏洞利用策略,该策略旨允许攻击者既不连接到目标也未连接到目标所在网络中的情况下,仍然可以破坏PLC所控制的物理过程。攻击方法由两个步骤组成:1)一旦攻击者获得对暴露的PLC的访问权限,就用恶意的ToD(Time-of-Day)中断块篡改PLC;2)当攻击者断开与系统网络的连接时,在稍后的时间触发中断。
2022年,德国研究机构IHP的Wael Alsabbagh研究员发表了一篇文章,介绍针对当时较新固件版本v2.9.2的S7-1500PLC的ToD注入攻击,对文章了进行研究并分将精华部分享之,有误之处请指正。
0x01 概述和相关工作
最近针对ICS系统的威胁之一是控制逻辑注入攻击,这种攻击涉及通过使用其工程软件修改目标PLC上运行的原始控制逻辑,通常采用中间人方法,这类攻击中利用的主要漏洞是PLC协议中缺少身份验证措施。ICS供应商通过为其PLC提供密码来应对这种威胁,以保护控制逻辑免受未经授权的访问,即每当ICS系统操作员试图访PLC中运行的控制逻辑时,设备首先需要认证以允许他读/写代码。这通常是通过专有认证协议完成的。但是,这种解决方案并不能完全防止控制器受到损害。先前的学术成果已成功地绕过了身份验证,并访问了不同密码保护的PLC中的控制逻辑。上述论文的作者讨论了绕过身份验证的两种主要方法:一种是提取密码的哈希,然后将其推回PLC(称为重放攻击),另一种是使用“纯文本密码、编码文本密码”对的代表性列表对每个字节进行离线暴力破解。总的来说,仅通过密码验证来保护控制逻辑失败了,攻击者仍然能够访问PLC的程序并操纵由暴露的设备控制的物理进程。
控制逻辑注入攻击有两种类型:传统的控制逻辑注入攻击和固件注入攻击。然而,在真实的ICS环境中,感染PLC固件将是一项具有挑战性的任务,因为大多数PLC供应商通过加密方法(如数字签名)或仅允许通过本地访问(如SD卡和USB)进行固件更新来保护其PLC免受未经授权的固件更新。本文不涉及固件注入,只关注传统的控制逻辑注入攻击。在下文中,我们将现有的旨在破坏物理过程的注入攻击分为两类:
A、在线攻击物理过程
该组的攻击旨在通过使用其工程软件来修改原始控制逻辑程序。恶意代码成功注入后,受感染设备控制的物理进程立即受到影响。下图示意了攻击顺序:
最著名的此类攻击是2010年对伊朗核设施进行的一次攻击,名为“震网”(Stuxnet),目的是破坏铀浓缩工厂的离心机。Stuxnet攻击使用Windows PC攻击连接到变频驱动器的西门子S7-300和S7-400 PLC,它会感染PLC的控制逻辑,以监控所连接电机的频率,如果频率在一定范围内(即807 Hz和1210 Hz),则会发起攻击。2015年,克里克等人在不中断服务的情况下,将恶意软件注入SIMATIC PLC的控制逻辑。作者表明,只要代码由MC7字节码组成,有权访问PLC的攻击者就可以下载和上传代码。在后续工作中,Spenneberg等人介绍了一种PLC蠕虫,蠕虫在内部从一个PLC传播到其他目标PLC.在感染阶段,蠕虫会扫描网络以寻找新的目标PLC。另一论文中介绍了用梯形逻辑或兼容语言之一编写的梯形逻辑炸弹恶意软件,这种恶意软件由攻击者插入到PLC上的现有控制逻辑中。一组研究人员演示了对PLC控制逻辑的远程攻击。他们能够感染PLC,并将感染隐藏在控制中心的工程软件中。他们对施耐德电气Modicon M221及其供应商提供的工程软件SoMachine-Basic实施了攻击。Lei等人演示了一种攻击,它可以绕过西门子SIMATIC S7-1200 PLC使用的S7CommPlus协议的安全机制。作者首先使用Wireshark软件分析了TIA Portal软件与S7PLC之间的通信,然后使用反向调试软件WinDbg4破解了S7CommPlus协议的加密机制。之后,他们演示了两次攻击。首先,执行重放攻击以远程启动和停止PLC.在第二个攻击场景中,作者操纵受害者的输入和输出值,对受感染PLC控制的物理进程造成严重破坏。2021年,研究人员表明S7-300 PLC易受此类攻击,并证明利用PLC中运行的控制逻辑是可行的。在他们破坏了PLC的安全措施后,他们进行了一次成功的注入攻击,并通过使用一个假冒的PLC来模拟真正的受感染设备,从而使工程软件无法发现他们的攻击。Rogue7背后的研究能够创建一个仿冒的工程站,该工程站可以伪装成S7 PLC的TIA门户,并注入任何对攻击者有利的消息。通过了解加密消息是如何交换的,他们设法将代码隐藏在用户内存中,这对TIA门户工程来说是不可见的。
上面提到的所有攻击都是有限的,其要求攻击者能够连接到目标PLC,这增加了被ICS操作员事先发现或被安全措施检测到的可能性。
B、离线攻击物理过程
这一类中的攻击与前一类中提到的攻击非常相似,不同之处在于,攻击者的目标不是在获得对目标设备的访问后立即攻击物理进程。这意味着,一旦他获得了暴露PLC的访问权限,便可立即向PLC中注入恶意代码,然后关闭与目标的任何实时连接,将他的代码保留在PLC的内存中,处于空闲模式。之后,激活他的程序并在他希望的稍后时间甚至在没有连接到系统网络的情况下损害现场物理过程,如下示意图:
我们所知,只有少数讨论这一新威胁的学术成果发表。Serhane等人专注于梯形逻辑代码漏洞和不良代码实践,这些漏洞和不良代码实践可能成为错误的根本原因,并随后被攻击者利用。他们表示,攻击者可以生成不确定的波动输出变量,例如,执行两个计时器来控制相同的输出值可能会导致竞争条件。这种情况可能会对受控设备造成严重损坏,类似于Stuxnet作者指出的另一种情况是,高级的攻击者也可以绕过某些函数,手动将某些操作数设置为所需的值,并应用空分支或跳转。为了实现隐秘的修改,攻击者可以使用数组指令或用户定义的指令,来记录插入的关键参数和值。他们还讨论了攻击者可以通过跳转应用无限循环,并使用嵌套计时器和跳转仅在特定时间触发攻击。在我们的前一篇论文中,我们提出了一种新的方法,该方法基于向目标PLC注入时间中断代码,它在攻击者设置的时间中断控制逻辑的执行序列。我们的评估结果证明,即使与目标系统断开连接,攻击者也可以混淆物理过程。虽然我们的研究工作只在一台旧的S7-300 PLC上进行了测试,并且只是为了迫使PLC进入停止模式,但攻击是成功的,并设法中断了在修补的PLC中运行的原始控制逻辑代码的执行。这种攻击比在线攻击更严重,因为PLC在数小时、数天、数周、数月甚至数年内一直正确执行原始控制逻辑,而不会被中断,直到攻击者设定的那一刻攻击才会发生。揭露这种攻击的唯一现实方法是,ICS操作员从PLC请求程序,并将受感染设备中运行的在线代码与他在工程站上的离线代码进行比较。
0x02 S7 PLC
西门子生产SIMATIC S7系列中的多条PLC产品线,例如S7-300、S7-400、S7-1200和S7-1500。它们都具有相同的体系结构。下图描绘了S7 PLC的标准架构,其包括输入和输出模块、电源以及诸如随机存取存储器(RAM)和电可擦除可编程只读存储器(EEPROM)的存储器。称为操作系统(OS)的固件以及用户专用程序存储在EEPROM中。传感器、开关、继电器、阀门等输入输出设备与输入输出模块连接。
PLC连接到物理过程,输入设备将进程的当前状态提供给PLC,PLC通过其控制逻辑对其进行处理,并通过输出设备相应地控制物理过程。S7 PLC运行的控制逻辑被编程并编译为代码的较低表示,即分别为S7-300/S7-400或S7-1200/S7-1500 PLC的MC7或MC7+字节码。工程师站编译代码后,通过西门子S7-300/S7-400或S7-1200/S71500 PLC的S7Comm或S7CommPlus协议,将MC7/MC7+格式的代码块下载并安装到PLC中。然后,S7 PLC中的MC7/MC7+虚拟机将分配代码块,解释并执行字节码。
西门子PLC运行实时操作系统,启动周期时间监控,此后,OS循环通过如下图所示的四个步骤。在第一步中,CPU将输出的过程图像的值复制到输出模块;在第二步中,CPU读取输入模块的状态并更新输入值的过程图像。在第三步骤中,用户程序在持续时间为1ms(毫秒)的时间片中执行。每个时间片分为三个部分,依次执行:操作系统、用户程序和通信。时间片的数量取决于当前用户程序的复杂性和中断程序执行的事件。
在正常操作中,如果事件发生,则当前正在执行的块在命令边界处被中断,并且被分配给特定事件的不同组织块被调用。一旦执行了新的组织块,循环程序就在其被中断的点重新开始。这适用于未超过最大允许周期时间(默认为150 ms)的情况。换句话说,如果在主OB1中调用了太多的中断OB,则整个周期时间可能会比PLC硬件配置中设置的时间更长。超过最大允许执行周期会产生软件错误,并且PLC调用特定块来处理该错误,即OB80。有两种方法来处理此错误:1)如果OB80未加载到主程序中,则PLC转到停止模式;2)PLC执行OB80编程的指令,例如警报。
西门子为开发PLC程序的工程师提供其Total Integrated Automation(TIA)门户软件。它由两个主要部分组成。STEP 7作为PLC和WinCC的开发环境,用于配置人机界面(HMI)。工程师能够使用以下编程语言之一对PLC进行编程:梯形图(LAD)、功能块图(FBD)、结构化控制语言(SCL)和语句表(STL)。S7 PLC程序分为以下单元:组织块(OB)、功能(FC)、功能块(FB)、数据块(DB)、系统功能(SFC)、系统功能块(SFB)和系统数据块(SDB)。
OBs、FCs和FBs包含实际代码,而DBs为数据结构提供存储,SDB为当前PLC配置提供存储。前缀M(存储器)用于寻址内部数据存储器。一个简单的PLC程序至少包含一个名为OB1的组织块,相当于传统C程序中的main()函数。在更复杂的程序中,工程师可以通过使用函数和功能块来封装代码。唯一的区别是额外的DB作为调用FB的参数。SFC和SFB内置在PLC中。然而,操作系统循环地调用OB,并且通过该调用开始用户程序的循环执行。
时间(TOD)中断
根据中断的需要(例如每分钟、每小时、每天、每月、每年和月末),一天中的时间(TOD)中断在配置的时间执行一次或定期执行。CPU 1500提供具有编号OB10至0B17以及OB 123之后的共计的20个组织块用于处理TOD中断。
要启动TOD中断,用户必须首先设置启动时间,然后激活中断。他可以进行这两种活动。分别在块属性中自动配置,或同时配合系统功能;手动配置:激活块属性意味着时间中断自动启动。简要地说明了这两种方式:
1) 自动配置:用户使用事件类Time-of-Day添加组织块,并输入名称、编程语言和编号。他用中断发生时要执行的所需指令对OB10进行编程。
2) 手动配置:在这种方法中,用户使用系统功能块来设置、取消和激活时间中断。他通过使用系统功能块在主OB1中设置中断的必要参数,同时在OB10中对要执行的中断指令进行编程。
0x03 攻击执行
正如在任何典型的注入攻击中一样,我们在目标PLC的原始控制逻辑中植入我们的恶意代码,时间中断块OB10。CPU在每个单独的执行周期中检查是否满足中断的条件。这意味着,攻击者的中断块将始终被检查,但只有在CPU时钟的日期和时间与攻击者设置的日期和时间匹配时才会执行。因此,我们有两种情况:
1) CPU时钟的日期与OB10中设置的日期(攻击日期)匹配。CPU立即停止执行OB1,将断点的位置存储在专用寄存器中,并跳转到执行相应的中断块OB10的内容。
2) CPU时钟的日期与OB10中设置的日期不匹配。CPU在检查中断条件之后恢复执行OB1,而不激活中断并且不执行OB10中的指令。
我们在本文中提出的攻击方法由两个主要阶段组成:注入阶段(在线阶段)和攻击阶段(离线阶段)。
A、注入阶段
下图显示了此阶段的基本过程。我们的目标是向PLC注入我们在中断块OB10中编程的恶意指令。此阶段包括四个步骤:
a) 上传和下载用户程序。
b) 修改和更新控制逻辑程序。
c) 制作s7CommPlus下载消息。
d) 将攻击者的消息推送给受害者PLC.
为了篡改目标PLC,利用我们的MITM站,它有两个主要组件:
1) TIA门户:用于检索和修改PLC运行的当前控制逻辑程序。
2) PLCInjector:将攻击者的代码下载到PLC.在这项工作中,我们为此开发了一个基于Scapy的Python脚本。对于实际情况,攻击者在访问网络后可能会遇到两种情况。
场景1:非活动S7会话
在这种情况下,合法的TIA门户处于脱机状态,并且仅在需要上传过程时才与PLC通信。步骤1.上传下载用户程序:此步骤的目的是获取PLC运行的反编译的控制逻辑程序,以及TIA Portal发送的S7CommPlus消息,将原用户程序下载到PLC中。为了实现这些目标,我们首先打开攻击者的TIA门户,并直接与受害者PLC建立连接。这是可能的,因为S7-1500 PLC设计上存在安全漏洞。事实上,可编程逻辑控制器没有引入任何安全检查,以确保当前通信的TIA门户与其在早期会话中通信的TIA门户相同。为此,任何在其机器上提供TIA门户的外部对手都可以轻松地与S7 PLC通信,而无需任何努力。成功建立通信后,我们将控制逻辑程序上传到攻击者的TIA门户。然后,我们再次将其重新下载到PLC,并使用Wireshark软件嗅探攻击者的TIA门户和受害者PLC之间交换的整个S7CommPlus消息流。在此步骤结束时,攻击者在其TIA门户上安装了程序,并将所有捕获的下载消息保存在PCAP文件中以供将来使用。步骤2.修改和更新PLC的程序:在检索目标PLC运行的用户程序后,攻击者的TIA门户将以一种高级编程语言(如SCL)显示该程序。基于我们对PLC控制的物理过程的理解,我们配置并编程了我们的时间中断块OB10,以强制系统的某些输出在中断被激活时关闭,尽管我们的恶意代码与原始代码的不同之处仅在于一个额外的小尺寸块(OB10),但它足以混淆我们实验设置的物理过程。更新PLC中运行的程序的最简单方法是使用攻击者的TIA门户。当我们下载修改后的控制逻辑时,PLC成功更新了其程序。但是,ICS操作员可以很容易地通过从受感染的PLC上传程序来发现篡改,并且比较分别在其合法TIA门户和远程PLC上运行的离线和在线程序。步骤3.制作s7CommPlus下载消息:为了向合法用户隐藏我们的感染,我们首先记录了下载修改程序时攻击者的TIA门户和PLC之间交换的s7CommPlus消息。步骤4.将特制的消息推送到PLC:特制的S7CommPlus下载消息包含以下属性:攻击者程序的对象MAC和对象代码属性,以及用户程序的源代码属性。由于S7CommPlusv3在TIA门户和PLC之间交换共享会话密钥以防止执行重放攻击,因此我们首先需要将数据包与正确的密钥捆绑在一起,然后才能将精心编制的消息推送到PLC.然而,利用共享密钥(不在本文的范围内),一旦恶意密钥交换完成,我们就可以轻松地将密钥字节码与精心编制的消息捆绑在一起。考虑到对会话ID和完整性字段的适当修改,我们将最终的S7消息(攻击者的消息)存储在PCAP文件中,以便将其作为重放攻击推回到PLC。下述算法描述了PLCInjector工具的主要核心,该工具用于使用攻击者的篡改PLC程序:
PLCInjector工具有两个功能:第一个用于利用S7CommPlusV3使用的完整性保护会话密钥。在TIA Portal和S7-1500 PLC之间的每个会话中交换的会话密钥源自PLC的ServerSessionChallange的16个字节,确切地说是位于字节2和18之间的那些,与TIA Portal选择的随机24字节KDK的组合。然后,在SessionKey计算中使用指纹函数f()。第5行生成24字节随机量(M),并将其映射到作为预密钥贡献的椭圆曲线的域。根据随机点预密钥,我们使用密钥推导函数(KDF)来推导如下标识的3-16字节的量:密钥加密密钥(KEK)、校验和种子(CS)和校验和加密密钥(CEK)。在第7行中,CS生成组织为四个256字的4096个伪随机字节,即LUT.此LUT用于计算KDK和PLC_质询的校验和。从第8行到第13行描述了椭圆曲线密钥交换方法,类似于TIA Portal用于加密随机生成的预密钥的方法。之后,我们用随机选择的20个字节(在算法中贡献给X)来屏蔽椭圆曲线计算。第19行为加密的KDK提供认证的加密。这里,计算非加密校验和,然后由AES-ECP函数加密。最后,我们添加包括密钥指纹的2个报头字段,即,具有一些附加标志的相关密钥的8字节截断的SHA256散列(见第20行)。
在与受害者成功建立会话后,PLC与攻击者机器交换恶意生成的Session_Key以及当前通信会话。在下一步中,我们的工具将执行函数2,向攻击者发送精心编制的S7消息,其中包含恶意代码以及生成的Session_Key。我们的攻击工具也可以用于攻击所有共享相同固件的S7-1500 PLC.这是因为西门子设计了新的S7密钥交换机制,假设所有运行相同固件版本的设备也使用相同的公钥–私钥对机制。成功注入后,PLC更新其程序,处理攻击者程序的目标代码,同时将用户程序的源代码保存在其内存中。因此,每当用户从受感染的PLC上传程序时,TIA Portal都会调用、反编译并显示原始程序。这使得我们的注入隐藏在PLC内部,用户无法检测到在线和离线程序之间的任何差异。
场景2:活动的S7会话
在这种情况下,在篡改期间,合法的TIA门户和PLC之间有一个正在进行的活动S7会话。默认情况下,S7 PLC只允许一个活动的在线会话,因此攻击者无法与PLC通信。它将立即拒绝任何建立连接的尝试,因为它已经在与用户通信。在这种情况下,攻击者首先需要关闭当前合法用户和PLC之间的在线会话。通过启用TIA门户软件中的“在线”功能,用户可以与S7 PLC建立在线会话。然后他可以控制,监控,诊断,下载,上传远程启动和停止CPU。一旦用户与PLC建立了在线连接,双方(TIA门户和PLC)就开始定期在会话中交换特定消息。此消息称为S7-ACK,负责保持会话活动。TIA门户必须始终使用S7-ACK重放消息响应PLC发送的任何S7-ACK请求。因此,为了关闭当前的在线会话,我们运行我们的MITM站,它允许我们通过执行众所周知的ARP中毒方法来拦截和丢弃从TIA门户发送的所有数据包。如果PLC在发送确认请求后没有立即收到来自TIA门户的响应,它将关闭与已连接的TIA门户的连接,并且两者都将离线。值得一提的是,攻击者还可以使用不同的方式来关闭连接,例如端口窃取、使用“离线”数据包进行重放攻击等。在合法的TIA门户和受害者PLC都脱机后,攻击者可以使用自己的TIA门户轻松地与PLC建立新的会话。然后,他按照前面案例中解释的相同四个步骤修补受害者设备。对于这种情况,我们的攻击方法有局限性。合法的TIA门户被迫关闭与PLC的会话。这意味着,用户可以清楚地看到他失去了与远程设备的连接。
成功注入后,攻击者离线并关闭与目标PLC的当前通信会话。在下一个执行周期中,攻击者的程序将在PLC中执行。这意味着,恶意中断块OB10的中断条件将在每个执行周期中被检查。只要不满足中断条件,该块就保持在空闲模式,并隐藏在PLC的存储器中。一旦配置的攻击日期和时间与CPU的日期和时间匹配,中断代码将被激活,即主程序(OB1)的执行过程被暂停,CPU跳转到执行攻击者用来编写OB10的所有指令。在我们的应用示例中,我们对OB10进行了编程,当我们与目标网络完全断开连接时,强制某些电机在特定时间和日期关闭。攻击实验中所使用到的恶意OB10如下图所示:
0x04 总结
本文介绍了最新的SIMATIC PLC面临的新威胁。我们的攻击方法是基于一旦攻击者获得目标网络的访问权限,就注入攻击者的恶意代码,但稍后激活其注入程序,而无需在攻击时连接。我们的调查发现了S7-1500 PLC使用的新完整性方法中的一些设计漏洞。根据我们的发现,我们成功地进行了注入攻击,通过篡改测试PLC的TOD中断块(OB10)。这个块允许我们激活我们的程序,并随后影响物理过程,而不是攻击者连接PLC后便立即攻击。我们的实验结果表明,当PLC运行攻击者的程序时,原始的控制逻辑程序总是显示给用户。此外,我们的注入不会增加控制逻辑的执行次数。因此,当我们的注入处于空闲模式时,物理进程不会受到影响。
0x05 彩蛋
本文针对S7-1500 PLC v2.9.2固件所研究的注入攻击,实际上仍然是基于S7commPlus协议实现的,但西门子从TIA Portal V17开始已经启用更加安全的S7commPlus_TLS协议,且在对PLC进行配置时,默认选择的即这种安全通信协议,关于此协议,绿盟安全专家已在参考资料5中详述,除非人为特意选择使用传统的S7commPlus协议,如下图所示选择/配置:
不过即便是S7commPlus_TLS安全协议,仍然存在相应的漏洞,参考资料6中讲述了对该协议的fuzzing并且发现了多个漏洞。基于文章的思路,仍然可以对S7-1500(V2.9.4)PLC实施CPU启停攻击,如下视频所示:
参考资料
1. A New Injection Threat on S7-1500 PLCs – Disrupting the Physical Process Offline W. Alsabbagh, P. Langendörfer IEEE Open Journal of the Industrial Electronics Society 3, 146 (2022)
2.W. Alsabbagh and P. Langendörfer, “A stealth program injection attack
against S7-300 PLCs,” in Proc. 22nd IEEE Int. Conf. Ind. Technol.,
2021, pp. 986–993
3. W. Alsabbagh and P. Langendörfer, “Patch now and attack later—
exploiting S7 PLCs by time-of-day block,” in Proc. 4th IEEE Int. Conf.
Ind. Cyber-Phys. Syst., 2021, pp. 144–151
4. W. Alsabbagh and P. Langendörfer, “A control injection attack against
S7 PLCs—manipulating the decompiled code,” IECON 2021 Proc.
47th Annu. Conf. IEEE Ind. Electron. Soc., Toronto, ON, Canada,
Oct., 2021, pp. 1-8
5. http://blog.nsfocus.net/s7-commplus/
6. https://www.freebuf.com/articles/ics-articles/352497.html
原文始发于微信公众号(博智非攻研究院):一种新的针对S7-1500 PLC注入攻击