随着信息技术和智能制造技术的发展,越来越多的工控厂商如西门子、ABB、研华等在内的各类工业控制设备或系统暴露在互联网的网络空间中,易被黑客利用其设备漏洞进行攻击,引发严重后果。
为了对接入互联网内的工控设备或系统进行快速搜索监测,掌握其设备的种类、规模及地理分布,迫切需要采用相关技术对联网工控系统或设备进行识别。
由于联网工控设备和系统在网络上具有其相应的特定属性:主要包括使用的IP地址,相应的端口和基于TCP/IP协议的特定工业通信控制协议,所以目前识别联网工业控制系统或设备的通用方法是:
首先明确联网设备所在IP地址段;
针对该IP地址段中的每一个IP及相关端口,依次根据各类联网工控系统和设备工控协议所对应的端口发起相应数据包,建立控制协议连接;
如主机不可到达或端口不开放则主机和端口不存活,需等待TIMEOUT(超时)时间,如主机可到达或端口开放,主机和端口存活,联网工控系统或设备返回数据包;
接收到返回数据包,解析其内容,根据内容中的关键报文与工控设备指纹库里的指纹进行匹配并进行工控系统或设备进行识别;
如没有接收到返回数据包,则依次使用下一工控协议,对IP和端口建立控制协议连接。
现有技术中采用IP和端口直接进行TCP的三次握手连接,成功则发送工控设备指纹探测数据包,失败则进入下一个IP+端口的设备探测,导致主机不可到达或端口未开放带来的TIMEOUT(超时)时间过长问题,同时没有构建完善的工控设备指纹库,导致不能快速准确识别工控设备的类型和型号等。
目前亟待解决的技术难题是:针对上述存在的问题,提供一种快速识别联网工控设备的方法。因此,本文以西门之PLC为例进行探讨Siemens PLC指纹识别方法。
开启西门子S7 PLC协议仿真软件
发现网段中开放102端口的ip
nmap -p102 -n 192.168.163.1/24 --open
如果是西门子PLC,可以进一步使用Nmap的s7-info.nse脚本进行指纹探测
还可以使用PLC采集软件进行连接,获取PLC详细指纹
使用Wireshark获取PLC指纹信息
方法:打开wireshark,筛选cotp,点击S7 PLC连接工具“连接”,此时Wireshark抓到一些数据包。
编号217号数据包:请求通讯;
编号220号数据包:配置通讯;
编号224号数据包:发送数据进行通讯;
编号226号数据包中可以看到PLC的CPU型号、序列号等指纹信息。
Python脚本提取指纹
讲以上请求报文复制为hex stream.
import socketfrom binascii import unhexlify,hexlifydef getSZL001c(Respons):
for i in range(int(len(Respons)/68)):
data = Respons[i*68+4:i*68+68].replace("00","")
try:
if unhexlify(data).decode("utf-8", "ignore") != "":
print (unhexlify(data).decode("utf-8", "ignore"))
except:
passdef getSZL0011(Respons):
for i in range(int(len(Respons)/56)):
data = Respons[i*56+4:i*56+56].replace("00","")
try:
if unhexlify(data).decode("utf-8", "ignore") != "":
print (unhexlify(data).decode("utf-8", "ignore"))
except:
passdef main():
sock = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect(("192.168.163.137",102))
sock.send(unhexlify("0300001611e00000000100c0010ac1020100c2020102"))
sock.recv(1024)
sock.send(unhexlify("0300001902f08032010000080000080000f0000001000101e0"))
sock.recv(1024)
sock.send(unhexlify("0300002102f080320700000a00000800080001120411440100ff090004001c0000"))
Respons = (hexlify(sock.recv(1024)).decode())[82:]
getSZL001c(Respons)
sock.send(unhexlify("0300002102f080320700000a00000800080001120411440100ff09000400110000"))
Respons = (hexlify(sock.recv(1024)).decode())[82:]
getSZL0011(Respons)
sock.close()if __name__ == '__main__':
main()
plcscan脚本探测
下载链接:https://github.com/yanlinlin82/plcscan
由于我的技术水平有限,所写文章难免有不足之处,恳请各位大佬批评和指正,今后还会继续分享有关工控安全技术文章。 在此,特别感谢烽台科技灯塔实验室举办的工业互联网安全知识分享讲座,跟着几位大佬学到了很多知识,PPT和现场实验演示都准备的很精心,让我收获颇丰,以后还会继续跟随大佬们的脚步努力学习,感谢!
http://www.xjishu.com/zhuanli/62/201611189629.html
http://plcscan.org/blog/2017/03/fingerprint-identification-technology-of-industrial-control-system/