吉沃运营专员 发表于 2021-8-6 11:57:21

如何配置 Modbus 工控蜜罐

DecoyMini 免费蜜罐工具集成可视化仿真编排引擎,支持通过界面配置来定义对网络请求数据的解析方式,基于对请求参数的判断来响应对应的数据,实现对服务和应用的仿真能力。

对网络请求数据的处理支持多种方式,包括:


[*]直接读取网络请求数据:支持直接读取指定长度,也支持按指定数据结尾来进行读取,对读取的数据可以直接存储到参数里,也可以将数据缓存,以便进行二次解析。
[*]对缓存数据的解析:支持通过字节偏移、位偏移等方式从缓存数据里提取指定范围的数据。

对提取的数据支持以指定的类型存储到参数里,包括:


[*]字符串
[*]字节数组
[*]整数(大端)
[*]整数(小端)

在请求响应部分,引擎根据请求参数的综合条件判断,来决定给请求方的响应数据,支持的响应数据类型包括:


[*]字符串;
[*]二进制;
[*]指定的配置文件;
[*]指定的数据文件;

同时支持响应后关闭连接、跳转到指定参数来继续执行等操作。
在应答的同时,可以按需开启日志记录功能,记录的内容包括操作用户、操作类型、操作结果、日志描述、日志级别、请求参数等,以实现对攻击行为的详细记录。
一、Modbus 介绍static/image/hrline/1.gif

Modbus 是由 Modicon (现在的施耐德电气 Schneider Electric) 公司于 1979 年开发,已经成为工业领域通信协议的业界标准,现在是工业电子设备之间常用的连接方式,已经是工业领域全球最流行的协议。

Modbus 协议是一种应用层报文传输协议,用Master/Slave方式通信,在 1996 年施耐德公司推出基于以太网 TCP/IP 的 ModbusTCP 协议后,Modbus 共支持 ASCII、RTU、TCP 三种报文类型,物理层接口支持 RS232、RS422、RS485 和以太网等接口。

1.1 协议格式介绍
ModbusTCP 的数据帧可分为两部分:MBAP+PDU。

1.1.1 报文头 MBAP
MBAP 为报文头,长度为 7 字节,组成如下:


事务处理标识协议标识长度单元标识符
2 字节2 字节2 字节1 字节

各属性含义解释如下:


内容解释
事务处理标识可以理解为报文的序列号,一般每次通信之后就要加1以区别不同的通信数据报文。
协议标识符00 00表示ModbusTCP协议。
长度表示接下来的数据长度,单位为字节。
单元标识符可以理解为设备地址。

1.1.2 帧结构 PDU
PDU 由功能码+数据组成。功能码为 1 字节,数据长度不定,由具体功能决定。

功能码定义

Modbus 的操作对象有四种:线圈、离散输入、保持寄存器、输入寄存器。


对象含义
线圈PLC 的输出位,开关量,在 Modbus 中可读可写
离散量PLC 的输入位,开关量,在 Modbus 中只读
输入寄存器PLC 中只能从模拟量输入端改变的寄存器,在 Modbus 中只读
保持寄存器PLC 中用于输出模拟量信号的寄存器,在 Modbus 中可读可写

根据对象的不同,Modbus 的功能码定义如下:


功能码含义
0x01读线圈
0x05写单个线圈
0x0F写多个线圈
0x02读离散量输入
0x04读输入寄存器
0x03读保持寄存器
0x06写单个保持寄存器
0x10写多个保持寄存器

功能码更详细的说明如下:


\数据类型功能描述功能码功能码(十六进制)异常功能码
比特访问物理离散量输入读输入离散量20x020x82
内部比特或者物读线圈10x010x81
理线圈写单个线圈50x050x85
写多个线圈150x0F0x8F
16 比特访问输入存储器读输入寄存器40x040x84
内部存储器或物理输出存储器(保持寄存器)读多个寄存器30x030x83
写单个寄存器60x060x86
写多个寄存器160x100x90

错误代码表说明如下:


代码名称
1非法功能
2非法数据地址
3非法数据值
4从站设备故障
5确认
7从属设备忙
8存储奇偶性差错
0A不可用网关路径
0B网关目标设备响应失败

更详细的协议格式定义,请读者查阅 Modbus 协议规范。

二、仿真模板配置static/image/hrline/1.gif

了解 ModbusTCP 协议后,开始 Modbus 仿真模板配置。安装好 DecoyMini 工具,登录进管理中心。



进入仿真模板,用 TCP 自定义引擎新建 "Modbus TCP 协议" 模板,设置基本的模板参数,开始结合 Modbus 协议格式来配置模板对应的解析规则。

2.1 请求数据解析
DecoyMini 会按照顺序从第一条规则往后执行解析规则。依次配置参数解析规则来解析事务处理标识、协议标识、长度、单元标识符等参数。

2.1.1 事务处理标识
事务处理标识为报文头前 2 个字节,定义名为 number 的参数直接从网络请求数据中读取 2 个字节的数据即可。在响应数据里可以通过 {{number}} 形式来对事务处理标识值进行引用。

配置的规则如下:



2.1.2 协议标识
协议标识为事务处理标识随后 2 个字节,定义名为 protocol 的参数继续从网络请求数据中读取 2 个字节的数据。读取的数据将会存放在 protocol 参数中,在响应数据里可以通过 {{protocol}} 形式来引用对应的数据。

配置的规则如下:



2.1.3 数据长度
数据长度为协议标识后 2 个字节,定义名为 length 的参数继续从网络请求数据中读取 2 个字节的数据按整数 (大端) 格式存储到参数中。在响应数据里可以通过 {{length}} 形式来引用数据长度对应的值。

配置的规则如下:



2.1.4 读取数据区域
数据长度后为具体的数据区域,需要根据数据长度值来读取对应长度的数据,定义名为 readdata 的参数从网络请求数据中读取 {{length}} 个字节的数据存储到参数中;由于随后还需要对 readdata 数据进行进一步解析,因此需要为此参数启用缓存数据功能。

配置的规则如下:



2.1.5 单元标识符
单元标识符为数据区域的第一个字节,因此,需要从已缓存的 readdata 参数里去进行解析。定义名为 devno 的参数,设置解析数据源为缓存数据,指定缓存数据名称,设置为通过字节偏移 (0:1) 来获取数据。

配置的规则如下:



2.1.6 功能码
功能码为 PDU 首部,在单元标识符后面,从已缓存的 readdata 参数里去进行解析。定义名为 function 的参数,设置解析数据源为缓存数据,指定缓存数据名称,设置为通过字节偏移 (1:2) 来获取功能码对应数据。

配置的规则如下:



2.1.7 数据
数据为 PDU 第二部分,从已缓存的 readdata 参数里去进行解析。定义名为 data 的参数,设置解析数据源为缓存数据,指定缓存数据名称,设置为通过字节偏移 (2:{{length}}) 来获取请求数据。

配置的规则如下:



最终配置完成的解析参数完整列表如下:



2.2 请求响应配置
2.2.1 协议格式检查
需要先检查是否为有效的 Modbus 请求,根据协议标识符以及实际读取的数据长度是否和报文头里定义的长度一致来判断。如果不满足条件,则为非 Modbus 协议连接,直接关闭 TCP 连接。

判断协议标识符是否有效规则定义如下:



判断数据长度是否有效规则定义如下:



2.2.2 读线圈
在设备中读线圈状态(功能码为 0x01)


[*]请求:MBAP 功能码 起始地址H 起始地址L 数量H 数量L
[*]响应:MBAP 功能码 数据长度 数据

本示例直接返回设备故障的异常功能码(81)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.3 写单个线圈

写设备中的一个输出(功能码为 0x05)


[*]请求:MBAP 功能码 输出地址 H 输出地址 L 输出值 H 输出值 L
[*]响应:MBAP 功能码 输出地址 H 输出地址 L 输出值 H 输出值 L

本示例直接返回设备故障的异常功能码(85)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.4 写多个线圈
写设备中的一个线圈序列的值(功能码为 0x0F)


[*]请求:MBAP 功能码 起始地址 H 起始地址 L 输出数量 H 输出数量 L 字节长度 输出值 H 输出值 L
[*]响应:MBAP 功能码 起始地址 H 起始地址 L 输出数量 H 输出数量 L

本示例直接返回设备故障的异常功能码(95)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.5 读离散量输入
从设备中读多个连续的离散量输入状态(功能码为 0x02)


[*]请求:MBAP 功能码 起始地址 H 起始地址 L 数量 H 数量 L
[*]响应:MBAP 功能码 数据长度 数据

本示例直接返回设备故障的异常功能码(82)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.6 读输入寄存器
从设备中读多个连续输入寄存器(功能码为 0x04)


[*]请求:MBAP 功能码 起始地址 H 起始地址 L 寄存器数量 H 寄存器数量 L
[*]响应:MBAP 功能码 数据长度 寄存器数据

本示例直接返回设备故障的异常功能码(84)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.7 读保持寄存器
从设备中读保持寄存器连续块的内容(功能码为 0x03)


[*]请求:MBAP 功能码 起始地址 H 起始地址 L 寄存器数量 H 寄存器数量 L
[*]响应:MBAP 功能码 数据长度 寄存器数据

本示例直接返回设备故障的异常功能码(83)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.8 写单个保持寄存器
在设备中写一个保持寄存器(功能码为 0x06)


[*]请求:MBAP 功能码 寄存器地址 H 寄存器地址 L 寄存器值 H 寄存器值 L
[*]响应:MBAP 功能码 寄存器地址 H 寄存器地址 L 寄存器值 H 寄存器值 L

本示例直接返回设备故障的异常功能码(86)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.9 写多个保持寄存器
在设备中写连续寄存器块(功能码为 0x10)


[*]请求:MBAP 功能码 起始地址 H 起始地址 L 寄存器数量 H 寄存器数量 L 字节长度 寄存器值
[*]响应:MBAP 功能码 起始地址 H 起始地址 L 寄存器数量 H 寄存器数量 L

本示例直接返回设备故障的异常功能码(96)和错误码(04),读者可以按需修改为所需的返回数据。返回数据后跳转到第一个参数,重新接收新的请求。

对应的响应数据配置规则如下:



2.2.10 未知操作处理

如果功能码非上述值,则为不支持的功能码请求操作,直接关闭链接。



四、蜜罐部署效果static/image/hrline/1.gif

在 DecoyMini 上部署配置好的 Modbus 仿真模板,用 Modbus 工具来进行连接测试,设置正确的 IP 和端口后可以正常连接。



执行各种功能请求,也可以按预期进行正确响应。



由此可见,通过 DecoyMini 的仿真模板经过简单的配置就实现了对 Modbus 工控协议、设备的仿真。以上配置的模板可以到 http://bbs.decoyit.com/template.php 下载,此模板仅配置了 Modbus 的基本功能,读者可以根据自己的需求去改进以支持更完善的功能、仿真模拟不同的工控设备,实现更完备、多样化的高仿真的工控设备攻击诱捕环境。

DecoyMini 免费蜜罐工具的仿真模板功能具有很强的仿真自定义能力,后继将为大家继续分享基于此免费工具来实现对更多协议、服务和应用的仿真自定义方法,敬请期待!大家感兴趣的可以下载工具安装体验,工具免费下载地址:https://github.com/decoymini

liuming 发表于 2022-1-21 15:28:29

{:5_150:} 歪睿顾德
页: [1]
查看完整版本: 如何配置 Modbus 工控蜜罐