工控modbus协议fuzz测试验证小结

背景
最近几个月从事工控安全工作,其中涉及到模糊测试和漏洞分析,之前一直在忙各自项目,所以对漏洞挖掘没怎么做,这两天刚好对施耐德PLC进行了一次fuzz,出现了两次异常,这篇文章对异常进行分析的一个小结。

涉及到的知识
因为时间关系这个文章写的不是很详细,如果你有一些基础的话,看起来会容易,会涉及到如下技术:1.python数据类型转字节流,涉及到struct库的使用。2.modbus协议数据包的结构。3.数据包字节流的16进制表示,其实这个wireshark有这个功能,但没法用。3.可能需要一些工控的基础知识,里面的概念说的简约一些,一些部分需要自己去查


关于Fuzz
又叫模糊测试,原理就是往被测试目标发送大量畸形数据,去发现目标漏洞的一种方法,这个技术不是本次文章的重点。


工控系统简称ICS,全称工业额控制系统,有兴趣自行百度。

PLC介绍
可编程控制器,和一般的控制器的差别是它是可以对其编程的,而且有网卡接口,用来控制设备的,因为没有硬盘,所以很多没有操作系统,只有固件,也有一部分PLC比较强大有操作系统和web服务,

Modbus介绍
Modbus是由Modicon(现为施耐德电气公司的一个品牌)在1979年发明的,是全球第一个真正用于工业现场的总线协议。ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。
ModBus网络只有一个主机,所有通信都由他发出。网络可支持247个之多的远程从属控制器,但实际所支持的从机数要由所用通信设备决定。采用这个系统,各PC可以和中心主机交换信息而不影响各PC执行本身的控制任务。
正文
首先大家看一下我的Fuzz结果,因为有两次异常,这边贴出来一次代表一下

 

这是fuzz的日志,其中00-00-00-00-00-03-00-00-de引发了通信异常,要对这个异常进行复现,所以要构造同样的数据包发送给目标,看能否再次引发,目前只知道协议的modbus的,对这个数据格式有待确定,通过查询modbus协议结构,发现它有应该有12个字节,但是这边只有9个单元,所以我很疑惑这些是单个字节的16进制还是18个数字,我隐约肯定这是一个数据包,应该是16进制,但是和协议数据包的长度又对不上

然后我去看了一下fuzz脚本的源代码,首先这个脚本是我从GitHub上下载的,并不是我自己写的,然后我阅读了一下它的源代码,找到了字节转换的一部分重要的代码,这里涉及到python的数据格式和字节流转换的问题,因为python自带的数据类型并不能直接发送到TCP上传输的,因为TCP层上传输的是字节流,而不是python的数据类型,稍后会讲到数据转换成字节。

 


数据类型转字节流
通过上面的代码进行分析,数据项转换成字节刚好是9个字节,意思是日志打印的是9个字节可以确定,这边需要提一点是python转换成字节流的时候的位数问题,比如一个整形8,你传入struct.pack的字符格式不同,它转换的字节数也是不同的,因为它对应C语言的整形,一般情况你使用i做参数的话它会把数字转为4个字节,对应C语言的整形,下面会放一张表

 

还有涉及到二进制的大端和小端传输方式
 

为了让大家更直观的看到差异,给大家做个例子,其中a=0

 

大家看到H和B转为的字节码位数是不一样的,所以查看程序的源代码我确定了字节的位数和字节的含义,在fuzz的源码上找到了字节数量和日志中的16进制的对应关系,确定了字节的含义。

构造引发异常的modbus数据包
接下来是构造modbus数据包,用16进制数据封装成一个modbus数据包,根据modbus协议的结构,在日志中的数据其实把数据包的头和控制部分已经定义好了,它先更改的是数据部分,这边需要做的是封装成16进制然后验证数据包。

首先我写了一个简单的python脚本,然后把日志里的字符串写成16进制形式数据

 

然后对发送的数据包使用wireshark进行流量分析,如下图

 

大家可以看到,完成了数据传输,而且服务端有响应,说明那个数据并不能使PLC产生漏洞,但也有好的一面是构造的数据包是正确的,然后接着验证构造的数据包如下,大家可以看到它的数据部分是de,和日志的最后一个字节是一致的,说明按照字节序是可以构造数据包的,而不需要再考虑大端小端问题

 

很遗憾这次没有挖到漏洞,不过对流程做个小结,后续会有更多分享。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值