来自于工控通信协议的威胁
工控通信协议作为工控设备与应用、设备与设备之间沟通的一种重要语言。工控系统中如果需要实现远程数据监控(SCADA)就一定离不开通讯协议,SCADA系统中会使用经由双方约定的协议直接与下层设备或数据采集转换器进行数据通信。随着时代的发展,厂级监控的实时性、可靠性需求增高,工业通信总线通讯速率的不断提升,从RS232/485到工业以太网再到工业实时以太网,工控网络中大量引入了以太网,并且使用TCP/IP或ISO标准封装后进行传输,因为一般的工控协议都经历了长时间的演变与积累,协议在设计之初都没有考虑加密、认证等在当今看来保障用户安全的必要认证条件,如第一个现场总线协议Modbus由莫迪康与1979年提出,所以我们常见的工控网络协议的安全性一直都不高。加上工控协议的特性是面向命令、面向功能、轮询应答式,攻击者只需要掌握协议构造方式,并接入到了工控网络中,便可以通过协议对目标设备的任意数据进行篡改。
如何解决来自工控通信协议的威胁
一般常见工控协议中包含了大量的命令字,如读取、写入数据等,然而其中一部分高级或协议约定的自定义功能往往会给用户安全带来更多的威胁,如Modbus协议的从机诊断命令将会造成从机设备切换到侦听模式、CIP协议某些命令字还能导致设备直接重启、S7协议的STOP CPU功能将会导致PLC程序运行停止,在大多数的情况下用户在上位机进行组态时仅会使用协议的某些读取数据功能和固定范围、固定地址的写数据功能,而协议栈上更多的功能则不会应用于系统集成中。如果对协议字段的掌握和对协议命令字的掌握,便可以很灵活的将可能给用户带来风险和威胁的一些隐藏功能,单独使用应用层防火墙对报文进行深度过滤,或者使用IDS进行报警提醒,如下便总结了2个协议中常见的威胁样例以及报警规则的应用方式。
工控通信协议威胁常见样例
Modbus
严重等级 | 威胁行为描述 | 潜在危害 |
高 | 主站下发08号功能码 | 可能导致设备进入Standby状态 |
高 | 主站下发90(5A)号功能码-stop(Schneider) | 导致PLC CPU进入STOP停机状态 |
高 | 主站下发90(5A)号功能码-download(Schneider) | PLC的内部程序可能正在被替换程 |
中 | 主站下发90(5A)号功能码-upload(Schneider) | 设备将工程上传至主站可能造成信息泄露 |
中 | 主站一次下发modbus报文超过260个字节 | 超出modbus tcp协议标准组包长度,可能导致设备拒绝服务 |
低 | 主站下发43(2B)号功能码 | 导致设备及其固件版本信息泄露 |
西门子S7协议
严重等级 | 威胁行为描述 | 潜在危害 |
高 | 主站下发STOP/RUN命令 | 导致设备进入停机状态/导致设备被启机初始化 |
高 | 主站下发download block命令 | PLC的内部程序可能正在被替换程 |
高 | 主站下发delet block命令 | PLC的内部程序块可能正在被删除 |
中 | 主站下发错误的密码请求 | 正在未授权访问 |
低 | 主站下发read szl请求 | 正在尝试获取设备模块信息、固件信息 |
解决与实践
如果了解了工控网络通信协议其中的威胁对正常运行所带来的潜在危害,我们其实可以很好的使用与创建规则进行拦截与报警,例如可以非常方便的基于Snort构建报警规则,如下为部分Snort规则的样例。
# # # $Id: myicsrules.rules,v 0.1, #---------- # myicsrules RULES # ICS protocal/ICS Software communication identification/Filter # Siemens S7 TCP 102 # Modbus TCP 502 # # # # # #---------- # Siemens S7 Filter rules #---------- #设置S7 PLC内部时钟的时间 alert tcp any any -> any 102 (msg:"Request Time functions Set clock";content:"|03 00|";offset:0;depth:2;content:"|32 07 00|";offset:7;depth:3;content:"|00 01 12 04 11 47 02 00|";offset:17;depth:8;sid:8999907;) #设置与S7 PLC会话的密码 alert tcp any any -> any 102 (msg:"Request Security functions Set PLC session password";content:"|03 00|";offset:0;depth:2;content:"|00 01 12 04 11 45 01 00|";offset:17;depth:8;sid:8999908;) #设置S7 PLC的CPU到STOP状态 alert tcp any any -> any 102 (msg:"Request CPU functions Set PLC CPU STOP";content:"|29 00 00 00 00 00 09 50 5f 50 52 4f 47 52 41 4d|";sid:8999909;) #暖启动S7 PLC的CPU到RUN状态 alert tcp any any -> any 102 (msg:"Request CPU functions Set PLC CPU Hot Restart";content:"|28 00 00 00 00 00 00 fd 00 00 09 50 5f 50 52 4f|";sid:8999910;) #冷启动S7 PLC的CPU到RUN状态 alert tcp any any -> any 102 (msg:"Request CPU functions Set PLC CPU Cold Restart";content:"|28 00 00 00 00 00 00 fd 00 02 43 20 09 50 5f 50 52 4f 47 52 41 4d|";sid:8999911;) #正在写S7 PLC内部的内存变量 alert tcp any any -> any 102 (msg:"Write Var";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|05|";offset:17;depth:1;sid:8999912;) #正在请求下载程序块 alert tcp any any -> any 102 (msg:"Request download";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|1a|";offset:17;depth:1;sid:8999913;) #开始请求下载程序块 alert tcp any any -> any 102 (msg:"Download block";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|1b|";offset:17;depth:1;sid:8999914;) #程序块下载结束 alert tcp any any -> any 102 (msg:"Download ended";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|1c|";offset:17;depth:1;sid:8999915;) #正在请求上载程序块 alert tcp any any -> any 102 (msg:"Start upload";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|1d|";offset:17;depth:1;sid:8999916;) #开始上载程序块 alert tcp any any -> any 102 (msg:"Upload";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|1e|";offset:17;depth:1;sid:8999917;) #结束上载程序块 alert tcp any any -> any 102 (msg:"End upload";content:"|03 00|";offset:0;depth:2;content:"|32 01|";offset:7;depth:2;content:"|1f|";offset:17;depth:1;sid:8999918;) #删除S7 PLC内部程序块操作 alert tcp any any -> any 102 (msg:"Delet block";content:"|03 00|";offset:0;depth:2content:"|05 5f 44 45 4c 45|";sid:8999919;) # #---------- # Modbus Filter rules #---------- #正在写单线圈寄存器 alert tcp any any -> any 502 (msg:"Modbus TCP/Write Single Coil";content:"|00 00|";offset:2; depth:2; content:"|05|";offset:7;depth:1;sid:8999100;) #正在写单个保持寄存器 alert tcp any any -> any 502 (msg:"Modbus TCP/Write Single Register";content:"|00 00|";offset:2; depth:2; content:"|06|";offset:7;depth:1;sid:8999101;) #正在读从站状态 alert tcp any any -> any 502 (msg:"Modbus TCP/Read Exception Status";content:"|00 00|";offset:2; depth:2; content:"|07|";offset:7;depth:1;sid:8999102;) #诊断设备命令 alert tcp any any -> any 502 (msg:"Modbus TCP/Diagnostics Device";content:"|00 00|";offset:2; depth:2; content:"|08|";offset:7;depth:1;sid:8999103;) #正在写多个线圈寄存器 alert tcp any any -> any 502 (msg:"Modbus TCP/Write Multiple Coils";content:"|00 00|";offset:2; depth:2; content:"|0f|";offset:7;depth:1;sid:8999104;) #正在写多个保持寄存器 alert tcp any any -> any 502 (msg:"Modbus TCP/Write Multiple registers";content:"|00 00|";offset:2; depth:2; content:"|10|";offset:7;depth:1;sid:8999105;) #正在写文件参数 alert tcp any any -> any 502 (msg:"Modbus TCP/Write File Record";content:"|00 00|";offset:2; depth:2; content:"|15|";offset:7;depth:1;sid:8999106;) #屏蔽写寄存器 alert tcp any any -> any 502 (msg:"Modbus TCP/Mask Write Register";content:"|00 00|";offset:2; depth:2; content:"|16|";offset:7;depth:1;sid:8999107;) #读写多个寄存器 lert tcp any any -> any 502 (msg:"Modbus TCP/Read/Write Multiple registers";content:"|00 00|";offset:2; depth:2; content:"|17|";offset:7;depth:1;sid:8999108;) #正在枚举设备信息 alert tcp any any -> any 502 (msg:"Modbus TCP/Read Device Identification";content:"|00 00|";offset:2; depth:2; content:"|2B|";offset:7;depth:1;sid:8999109;) #正在枚举施耐德昆腾PLC的内存串号 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software Request Memory Card ID";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|00 06 06|";offset:8;depth:3;sid:8999110;) #正在枚举施耐德昆腾PLC的CPU模块信息 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software Request CPU Module info";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|00 02|";offset:8;depth:2;dsize:10;sid:8999111;) #正在枚举施耐德昆腾PLC内部的工程名称 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software Request Project Project file name";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|f6 00|";offset:17;depth:2;sid:8999112;) #正在枚举施耐德昆腾PLC内部的工程上次修改时间 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software Request Project Information(Revision and Last Modified)";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|03 00|";offset:17;depth:2;sid:8999113;) #正在将施耐德昆腾PLC的CPU设置到STOP状态 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software Set PLC CPU STOP";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|40|";offset:9;depth:1;sid:8999114;) #正在将施耐德昆腾PLC的CPU设置到RUN状态 alert tcp any any -> any 502 (msg:"Schneider PLC(Quantumn) uses function code 90 for communications the Unity pro software Set PLC CPU Restart";content:"|00 00|";offset:2;depth:2;content:"|5a|";offset:7;depth:1;content:"|41|";offset:9;depth:1;sid:8999115;)
更多规则
Quickdraw SCADA IDS(Digitalbond)