漏洞

工业协议


    工业协议被设计成轻量级的并提供控制器和终端之间合理的确定性通信。安全作为协议设计后才考虑到甚至一点儿都没有考虑。简单的串行协议例如Modbus和DNP3是可以通过IP头进行封装,然后通过因特网发送。

    显著的修改工厂的运行过程并不需要破坏组件,只需要构造一个满足工业协议的IP数据包然后将其发送给控制器即可。在标准的PLC中,并不存在基于白名单的IP地址和端口安全,因此它会接收任何满足IP数据包格式的数据包并根据数据包中的请求信息来执行实际控制过程。

工业协议目前存在的主要缺陷:

(1)不支持加密
(2)硬件上缺乏对加解密的支持
(3)多数协议仅仅是对串行帧的简单封装

主要的工业协议有:

(1)Modbus/TCP

a)端口号:TCP 502

b)在1970年代的Modbus/RTU协议基础上进行了细微的改变

(2)Ethernet/IP

a) 端口号:TCP 44818

b) 类似于SNMP协议

c) 与串口设备完全兼容

(3)Profi NET

Modbus通信包篡改


Modbus TCP的协议构成如下图所示,协议是没有加密的。协议头采用了TCP标准协议头,目的端口号固定为502。

 

 

Modbus Data的构成格式如下所示,通常操作码用来表示具体操作。(某知名厂商的设备中曾出现过操作码的漏洞。)

如下为操作码表示的含义,如下,其中ox05用来写操作。

如何通过利用协议,通过伪造的数据包使得如下的泵运行?

只需要向PLC发送如下类似的数据包,其中操作码定义为0×05,其中数据区的构成中第三个字节用来表示打开还是关闭,0xFF表示运行,0×00表示停止。因此按此数据构成,发送相应的数据包,可能最终会实现泵的启动和停止。

组态工程篡改


模型如下所示:

如下为用来进行保护操作的逻辑。逻辑的含义是如果在没有过载(罐中的水满了)的情况下,操作员操作HMI点击正转或者反转都是可以进行的,如果在过载的情况下,操作员的操作将不会被执行,从而起到保护的作用。

 用C++代码表示这段逻辑如下:

void SafeLogic()
{
   if (overload == false)
   {
            if (userClick == FORWARD)
            {
                     if (currentRunStatus != REVERSE)
                     {
                               SetPumpRun(FORWARD);
                     }
            }
            else if (userClick == REVERSE)
            {
                     if (currentRunStatus != FORWARD)
                     {
                               SetPumpRun(REVERSE);
                     }
            }
   }
}

如果入侵了工程师站,通过修改保护逻辑,可以将保护逻辑变成完全相反的结果。

修改后的保护逻辑如下,保护逻辑完全失效:

用C++代码表示这段逻辑如下:

void SafeLogic()
{
   if (userClick == FORWARD)
   {
            SetPumpRun(FORWARD);
   }
   else if (userClick == REVERSE)
   {
            SetPumpRun(REVERSE);
   }
}

    在保护逻辑失效后,如何让操作员无法发现呢?有两种办法,来实现,一种是通过篡改HMI和应用服务器,另一种为修改PLC对上层监控的应答。

(1)篡改HMI及应用服务器

    篡改HMI及应用服务器的核心思想如下,当HMI通过发送数据包来获取底层PLC的运行状态信息时,让其处理逻辑跳转到篡改后的运行逻辑中,该逻辑会发给HMI假的数据,从而HMI无法知道底层PLC的实际情况。当HMI向应用服务器读取数据时,可以使应用服务器向HMI反馈假的数据。缺点就是,需要将所有的HMI都篡改,只要有一个没有被篡改,那么通过这个没有篡改的HMI,操作员就能发现问题。

(2)篡改PLC

    PLC采用类Linux的操作系统,其网络通信模块通常是采用linux的TCP/IP协议栈,可以通过篡改数据包甚至是协议栈的方式实现最终目的。

调试用服务程序


    在设备层,厂商会在设备中会安装调试用的服务程序,服务程序可以完全访问物理内存。例如在一个VxWorks中,这些服务可以帮助开发者进行调试和帮助厂商在现场解决客户的问题。正如厂商支持其员工访问这些服务,恶意软件也可以访问这些服务。这些调试用服务程序支持直接内存访问,对于控制器来说,这些内存的每一个比特都与真实世界中的设备相对应。随意的修改内存可能会导致灾难性的后果。涉及过程控制的三个主要内存区域如下:

(1)输入表

        输入表由储控制器的输入信号填充。每一个输入信号对应了输入表中一块内存。控制器通过这一区域的内存来了解真实个流程处理状态。

(2)逻辑内存

        这一内存区域存储了真实的逻辑代码,这些代码可以被编译执行或者解释执行,取决于不同类型的控制器。调整这一部分内存会导致不可预料的后果,因为这就像修改了可执行程序的二进制码。

(3) 输出表

        输出表由逻辑值填充,这些逻辑值是通过一次扫描周期会运行每个梯形图得到的。一旦一次周期完成了,输出表就被写入到输出卡中,这些输出卡可以将信号发送给物理设备。如果修改这一部分内存将会直接影响到处理流程,因为在输出表中的每一个比特都对应了设备。

补救办法


网络级

    针对网络攻击,可以通过移除公众可以远程访问的设备,为这些设备定制私有化的网络。正确的网络架构可以防止针对关键系统的未授权访问。管理者进行网络流量控制和采用安全设备防火墙和入侵检测系统来设置规则并记录网络通信的历史数据。

值得关注的是通过无线设备来访问远程系统时,应该采用调频扩频(FHSS)技术。另外,网络通信应该尽可能加密。

主机级

    在SCADA系统中保护主机不受攻击,与在公司中的情况是类似的,除了个别需要关注的。通常情况下,控制系统因为技术原因或者原有系统的关系,无法升级到最新的安全和Bug补丁。由于控制系统的性质,主机通常只执行一些固定的活动,并不像通用的PC那样使用,因此,控制系统主机采用白名单技术是一个很好的备选方案。(译注:据说,Mcafee公司在开发这方面的白名单产品。)

    防病毒产品是很重要的,仅仅是为了防止旧的威胁和恶意USB设备与主机的接触。然而在控制网络上,更新是一个挑战,因为互联网访问是受限制的。(译注:据说,有些工控厂商会定期去现场为客户升级病毒库,来避免通过互联网的方式升级病毒库。)

控制器级

    大多数针对控制器攻击的补救措施,只是用与设备制造商。可以进行命令级别的过滤,例如采用设备级别的防火墙来过滤有效命令,可以过滤出哪些命令能够发送给诸如PLC这样的设备。

    设备制造商可以通过移除固件映像中不必要和不安全的协议来减少攻击面,硬编码的凭证例如服务级别的账户和秘钥也应该去除或者安全存放。(译注:今年某国际工控厂商爆出了这方面的漏洞)。固件映像本身也应该被加密。供应商可以做的最重要的事情是测试自己产品的安全问题和审计代码。

相关阅读:

2013黑帽大会:失控 – 针对工业SCADA系统的漏洞利用(一)

2013黑帽大会:失控 – 针对工业SCADA系统的漏洞利用(二)

备注


翻译过程中,添加了部分自己了解的信息。原文和视频中可能没有出现。文中的C++伪代码为译者添加的。

原文视频地址:

http://www.cimation.com/blog/bid/186526/Out-of-Control-VIDEO-Cimation-Demonstrates-SCADA-Vulnerabilities

原文地址:

https://media.blackhat.com/us-13/US-13-Forner-Out-of-Control-Demonstrating-SCADA-Slides.pdf

源链接

Hacking more

...