首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >工控渗透框架:PLC密码检测

工控渗透框架:PLC密码检测

作者头像
FB客服
发布2023-04-26 21:42:23
发布2023-04-26 21:42:23
85200
代码可运行
举报
文章被收录于专栏:FreeBufFreeBuf
运行总次数:0
代码可运行

前言

上一篇《信息收集篇》中我们讲了如何使用ISF框架发现工控设备,那么有些小伙伴就会问了,发现工控设备之后能做些什么呢?答案是很多,比如:查看设备有没有密码保护?有密码保护能不能破解?破解后都能做些什么等等问题。为了让大家循序渐进地学会工控相关的安全攻防,我们需要先学习一些工控的相关知识。本篇我们就来讲讲与暴力破解相关的基础知识,为后续暴力破解做好准备。

首先,为了能让工业机器相对“智能”,就需要一个可以控制这些机器的设备来控制它,而这个设备应该具备通用性和可复用性,这就是PLC类设备。一个通用的,可重复改写的逻辑控制设备。人们可以通过编写一些程序下载到PLC中,然后PLC通过读取这些程序以达到“智能”控制的效果。

好了,大家都知道PLC的基本功能后,那么就会有一个永恒的问题,一般有用的东西就会涉及到安全问题,既然你能通过编写程序让PLC控制设备,那么就会有别有用心的人也想控制它,所以,这里就涉及到PLC的保护机制。PLC的保护机制和我们常用的手段一样,就是通过设置密码进行保护。

了解完这些基本知识之后,让我们来看一下PLC是怎么进行密码设置的,设置后是怎么保护PLC的。还是和以前一样,我们通过工控实验箱来演示,实验箱实物图如下:

注:实验箱中各设备的功能与连线这里就不多介绍了,不知道的同学可以看上篇文章。

连接PLC

实验箱通电后,用一根网线将电脑与实验箱进行互联,然后就可以使用“STEP 7-MicroWIN SMART”配置PLC,以及编程软件下载,编写程序等操作。(不同厂家和不同型号的PLC需要不同的控制软件,我们的PLC型号是SMART200)

点击“PLC”—“查找CPU”,扫描到一台PLC设备(为什么是扫描的是CPU而不是扫描PLC呢?请自行百度)

通过扫描识别到PLC后,点击“确定”该软件就与plc成功连接,当前界面就是PLC编程界面。

密码配置

双击“CPU ST20”打开“系统块”设置页面,在“安全”标签中密码设置选项中就可以设置密码了,密码保护一共分为4个级别,S7‑200 SMART CPU 的默认密码级别是“完全权限”(1 级),:

  1. 完全权限(1 级):提供无限制访问CPU所有功能。
  2. 读取权限(2级):用户可以不受限制地读取和写入CPU数据和上传程序。 下载程序、强制存储器位置或对存储卡进行编程时需要密码。
  3. 最低权限(3级):用户可以不受限制地读取和写入CPU数据和上传程序。 上传或下载程序、强制存储器位置或对存储卡进行编程时需要密码。
  4. 不允许上传(4 级):该级别的密码保护将阻止程序上传(即使输入正确的密码)。 该选项不允许项目比较。 其它CPU功能的保护方式与最低权限密码相同。

知道了PLC密码保护的相关知识后,我们随便找一个密码级别(这里我们使用只读),设置好密码后下载程序到PLC中,然后再次通过下载程序就需要输入密码(上面密码保护级别里说过,只读级别下载时需要输入密码),结果如下图所示:

PLC密码保护检测

废话不多说,直接上图:

是不是很简单,如果还想验证其它密码保护级别,可以通过上面的上步骤重新修改PLC的密码保护级别,然后再通过ISF中的s7_200_password_check模块进行验证。说到这个模块仔细的同学应该已经发现,上一篇文章里提到的从github中clone的ISF项目里没有s7_200_password_check模块啊,你这个模块是哪里来的?

ISF模块添加

如上面细心网友发现的那样,github中的ISF项目确实没有今天要讲的这个模块,这也就是我们为什么要开发这个框架的原因,它是一套攻击框架,大家可以根据自己对PLC的研究成果,添加不同的功能模块,最后将所有的攻击模块都集成到这个框架中,我们就可以拥有一个强大的工控攻击工具。

接下来我们就通过上面的案例讲解一下,如何给ISF添加一个PLC密码检测模块,Iet’s go!

首先,你需要在ISF的module目录(例:/home/one/soft/isf/module/exploits/Siemens)下创建两个文件,名字任意(例:s7_200_password_check.py,s7_200_password_check.xml)

xml文件

代码语言:javascript
代码运行次数:0
运行
复制
<?xml version="1.0"?>
    <t:config id="7f1a1992802517842c14ddfd1a2e3a6b"          name="s7_200_password_check"          version="1.1.0"          configversion="1.1.0.0"          author="one"          xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'          xmlns:t='tc0'>    <t:inputparameters>    <t:parameter name="TargetIp" description="The Target ip address " type="IPv4"/>    <t:parameter name="TargetPort" description="The Target Port" type="U16" default="102"/>
    </t:inputparameters></t:config>

代码解释:

id:可以是这个模块名称的md5值,也可以复制我当前这个值,然后随变改几个字符即可

name:这里的name就是ISF框架use时的模块名称,也是py文件的名称

TargetIp和TargetPort:是你这个模块需要的参数

py文件

xml文件是用来配置py文件的参数,以及关联ISF框架的,而真正完成扫描或攻击功能的模块是在py里面编写的,下面我们来看s7_200_password_check.py模块是如何编写的。

代码语言:javascript
代码运行次数:0
运行
复制
#encoding:utf-8import socketimport timefrom core.exploit import *
class Check_passwd(BaseExploit):    register_info = {        'ID': 'ICF-2020-F0010009',        'Name': 's7-200检查',        'Author': 'one',        'License': ISF_LICENSE,        'Create_Date': '2020-06-04',        'Description': '''可以显示密码状态''',    }    register_options = [        mkopt_rport(102)    ]
    def exploit(self,*args,**kwargs):        self.ip = self.TargetIp        self.default_port = int(self.TargetPort)        if self.default_port != 102:            return False        try:            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)            sock.connect((self.ip, self.default_port))            pp = "0300001611e00000000100c0010ac1020100c2020101".decode("hex")            sock.send(str(pp))            data = sock.recv(1024)
            pp = "0300001902f08032010000662100080000f0000001000101e0".decode("hex")            sock.send(str(pp))            data = sock.recv(1024)            time.sleep(0.1)            pp = "0300001f02f080320100000004000e00000401120a100200020000030005d0".decode("hex")            sock.send(str(pp))            data = sock.recv(1024)            data2 = data.encode("hex")            str_tmp = data2[-1:]            print data2            if str_tmp == '1':                print "完全读取!"                return True            elif str_tmp == '2':                print("只读!")                return False            elif str_tmp == '3':                print('最低权限!')                return False            elif str_tmp == '4':                print("不允许上传!")                return False            else:                print("异常状态!")                return False        except Exception as e:            print e,"执行错误"            return FalseMainEntry(Check_passwd, __name__)

代码解释:

import:三个导入自然不用说了

Check_passwd:构建模块时,一定要使用类,而不是函数,其次一定要继承BaseExploit

exploit:这个方法就是在ISF中配置完各种参数后,用于执行扫描或攻击的方法

pp:这里发送的数据大家先不用关心,后续文章会慢慢教大家怎么解析PLC协议

str_tmp:用sock发送完3组数据,并接收返回值后,取出最后一位进行判断,看到这里大家应该就能明白上面4种密码保护级别的1234是什么意思了吧

MainEntry:是将ISF框架接收到的参数发送给当前类,然后将检测结果显示出来

总结

好了今天的内容就讲到这里,是不是很简单,有没有想继续学下去的冲动,那就关注我们,一步一步用实例为你打开另一扇门。

精彩推荐

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FreeBuf 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 连接PLC
  • 密码配置
  • PLC密码保护检测
  • ISF模块添加
    • xml文件
    • py文件
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档