工控CTF_Modbus TCP
参考文章
https://blog.csdn.net/song123sh/article/details/128387982
https://www.anquanke.com/post/id/185513#h2-0
概况
Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP
modbus可以说是将读写指令分为了两大类,一类是离散的,也就是位操作,非1即0;第二类是模拟的,也就是数字,可以叫做字操作。
- DO(digital output 数字量输出),所谓线圈就是离散的输出状态,01即读一个离散的输出状态,举个不恰当的栗子,你家灯泡接到某个控制器上(实际上并不会存在这种情况……),我们可以通过01加上数据,比如1,让他亮,加上0,让他灭。
- DI (digital input 数字量输入),所谓的离散输入就是它,还是上面的栗子,我们想知道灯的开关是咋样的呢?就用02指令看看,如果是1,哦,按下去了,如果是0就是没按。通过这个不恰当的栗子我们大概也可以猜到,这是不可写的(如果你随便一个指令把开关给按死了,那我这灯不是彻底开不了了?),可以理解为外部对工控系统所带来的“开关”影响。
- AO(AnalogOutput 模拟输出),保持寄存器的功能,和DO最大的不同就是它不再是0或1,可以是一个数值,比如,我们设定的PID运行参数,或者是温度的上下限等等
- AI(Analog Input 模拟输入),也就是输入寄存器,和DI一样,可读但不可写,可以理解为外部对于系统的多位输入
Modbus TCP数据格式
Transaction identifier : 事务标识符
Protocol identifier : 默认为0
Length : 数据的长度
Unit identifier : 从机地址,因为使用了TCP/IP所以用ip地址来标识从机,所以该位可忽视,或者做进一步分发
Function code : modbus的功能码
Data :具体的数据
具体分析一条Modbus/TCP数据包
7484 329.001243 172.16.3.23 172.16.1.33 Modbus/TCP 66 Query: Trans: 13304; Unit: 1, Func: 3: Read Holding Registers
7484 数据包序号
329.001243 时间戳,表示数据包的捕获时间
172.16.3.23 源地址,发送此数据包的设备IP地址
172.16.1.33 目的地址,接收此数据包的设备IP地址
Modbus/TCP 协议类型,表示此数据包使用Modbus/TCP协议
66 数据包长度,66字节
Query: 请求信息,表示此数据包是一条查询请求
Trans: 13304 事务标识符,用于匹配请求和响应,这里是13304
Unit: 1 目标设备编号,这里是1号设备
Func: 3 功能码,这里是0x03,表示读保持寄存器的请求
Func 功能码(常见)
Modbus的操作对象有四种:线圈、离散输入、保持寄存器、输入寄存器。
对象 | 含义 |
---|---|
线圈 | PLC的输出位,开关量,在Modbus中可读可写 |
离散量 | PLC的输入位,开关量,在Modbus中只读 |
输入寄存器 | PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读 |
保持寄存器 | PLC中用于输出模拟量信号的寄存器,在Modbus中可读可写 |
1:读线圈
2:读离散输入
3:读保持
4:读输入
5:写单个线圈
6:写单个保持
15:写多个线圈
16:写多个保持
90:施耐德高危功能码,它是施耐德自定义的非标准功能码
筛选技巧
流内可直接得到的flag既不可能是位操作,也不可能是字操作,都太短了,所以聚焦的就应该是包长度大的,或者是类似16功能码那样写多个字的指令。
在wireshark过滤流中即可 ((modbus) && (modbus.func_code == 16)) && (modbus.byte_cnt)
如此使用
筛选出所有Modbus协议
modbus
下两步可以直接在对应位置选择:作为过滤流应用 --> ...且选中
分析功能码,以功能码为1举例
(modbus) && (modbus.func_code == 1)
找回包(对比发现回包有一个代表长度的Byte Count)
((modbus) && (modbus.func_code == 16)) && (modbus.byte_cnt)
搜寻异常流量
Func 功能码
17:主机正在对从机的某文件记录区块进行读取或写入操作
109:主机/从机接收到无效数据时的异常响应
67:重置通讯参数
1:读取线圈状态
先逐次查看容易出现异常的功能码
(modbus) && (modbus.func_code == 17)
筛选后要注意查看Data数据,对比筛选正常流量跟异常流量,并在此基础上新增对Data的筛选
如 当正常流量的data为600000时
(((modbus) && (modbus.func_code == 17))) && (modbus.data != 06:00:00)
用此方法对异常流量功能码依次处理
当呈现的是Byte Count数据时,对比数量进行筛选
(modbus.func_code == 1) && (modbus.bit_cnt != 1)
异常一定是有请求数据异常导致,这样就找到了异常流量包
标签:modbus,工控,TCP,Modbus,CTF,&&,寄存器,数据包 From: https://www.cnblogs.com/Mar10/p/17453022.html