IEC 60870-5-104协议解析&模糊测试的一些策略
1ance 发表于 上海 技术文章 6430浏览 · 2024-04-08 15:53

前言

本文分为两部分:第一部分对104协议进行解析,按照协议报文结构从前往后逐步进行解析,并结合相关的通信流量,以便读者更直观地理解;第二部分介绍了104协议模糊测试的一些策略和思路。笔者是也是因项目而初次接触104协议,如有不足之处,请谅解!在此特别感谢郑老师对104协议模糊测试方面的指导。

1. 简介

IEC 60870-5-104远动规约用于厂站与调度主站间的通讯,电力系统中常见的设备分为调度端(主站、控制站、客户机)典型设备如SCADA,服务端(子站、被控站、服务机)典型设备如FTU(馈线终端)、DTU(站所终端)、TTU(配变终端)、RTU(远程终端单元),两者之间通过104规约来进行数据通信与传输。
IEC 60870-5-104 协议是基于IEC 60870-5-101 协议在 TCP-IP 协议上使用的扩展。IEC 60870-5-101是基于串口的通信协议,IEC 60870-5-104是基于以太网的通信协议。默认端口是TCP2404

2. 规约数据结构

数据报文结构共分为三个部分:
应用规约控制信息:APCI(Application protocal control information)
应用服务数据单元:ASDU(Application service data unit)
应用规约数据单元:APDU(Application protocal data unit)


APDU=APCI+ASDU,104规约规定APDU报文最长为255个字节,所以ASDU最大为249。

2.1. APCI解析


启动字符:68H,十六进制表示,长度为1字节。
APDU长度域:定义了APDU体的长度,它包括 APCI 的四个控制域八位位组和ASDU长度。
控制域定义了保护报文不至丢失和重复传送的控制信息、报文传输启动/停止、以及传输连接的监视等控制信息。
控制域1和2:为发送序列号,控制域1最后一位比特不参与发送序列号计算。
控制域3和4:为接收序列号,控制域3最后一位比特不参与接收序列号计算,固定为0。
由于存储方式是小端模式,第一个开始计数的发送序列号是控制域1,第一个开始计数的接收序列号是控制域3,并且因为最后一位不参与计算,实际序列号*2=序列号值。


示例:
1、主站发送报文,序列号为(0,0)表示发送序列号为0,接收序列号为0。
控制域1和2:0000 0000 0000 0000 (0000H)
控制域3和4:0000 0000 0000 0000(0000H)

2、子站回复报文,序列号为(0,1)表示发送序列号为0,接收序列号为1。
控制域1和2:0000 0000 0000 0000 (0000H)
控制域3和4:0000 0010 0000 0000(0200H)传输时数据为:0002H

3、主站发送报文,序列号为(1,1)表示发送序列号为1,接收序列号为1。
控制域1和2:0000 0010 0000 0000 (0200H)传输时数据为:0002H
控制域3和4:0000 0010 0000 0000(0200H)传输时数据为:0002H

2.2. 控制域解析

I帧为长帧,带有信息发送(ASDU)并确认对方帧,发送和接收序列号有效,最长度为255。
控制域1的最低位比特为0时,标识信息传输格式类型为:I格式即I帧。上图示例即为I帧。


S帧为短帧,不带有信息,仅用于确认接收对方帧,仅接收序列号有效,长度为6字节。
控制域1的最低位比特为1,倒数第二位为0时,标识信息传输格式类型为:S格式即S帧。

U帧为短帧,用于启动控制信息,仅控制域1有效,其余固定为0,长度为6字节。
控制域1的最低位比特为1,倒数第二位为1时,标识信息传输格式类型为:U格式即U帧。

00 00 01 11 启动命令 0x07,完整命令为:68 04 07 00 00 00
00 00 10 11 启动确认 0x0B,完整命令为:68 04 0b 00 00 00
00 01 00 11 停止命令 0x13,完整命令为:68 04 13 00 00 00
00 10 00 11 停止确认 0x23,完整命令为:68 04 23 00 00 00
01 00 00 11 测试命令 0x43,完整命令为:68 04 43 00 00 00
10 00 00 11 测试确认 0x83,完整命令为:68 04 83 00 00 00

2.3. ASDU解析

ASDU部分是I帧信息帧独有的,ASDU部分其实是IEC 60870-5-104信息的有效数据的载荷,不同ASDU数据类型对应的信息元素内容也不同


完整类型标识如下表:参考链接:IEC104规约(一)协议结构阐述

  1. 监视方向过程信息
    从站发送给主站;标度化值-类似INT16,短浮点值-类似float
  2. 控制方向过程信息
    主站发送给从站
  3. 监视方向系统信息
    从站发送给主站,当厂站(从站)短重新上电、初始化参数、重新分配缓存区等情况下,厂站需要给主站发送该类型,而主站收到该类型的APDU包,主站一般会做一次总召唤
  4. 控制方向系统信息
    主站发送给从站
分类 类型标识 类型名称
监视方向过程信息(上行) 1 单点信息
2 带短时标的单点信息
3 双点信息
4 带短时标的双点信息
5 步长位置信息
6 带短时标的步长位置信息
7 32比特串
8 带短时标的32比特串
9 测量值,归一化值
10 带短时标的测量值,归一化值
11 测量值,标度化值
12 带短时标的测量值,标度化值
13 测量值,短浮点数
14 带短时标的测量值,短浮点数
15 累计值
16 带短时标的累计值
17 带时标的保护设备事件
18 带时标的继电保护装置成组启动事件
19 带时标的继电保护装置成组输出电路信息
20 具有状态变位检出的成组单点信息
21 测量值,不带品质描述的归一化值
30 带CP56Time2a时标的单点信息
31 带CP56Time2a时标的双点信息
32 带CP56Time2a时标的步位置信息
33 带CP56Time2a时标的32比特串
34 带CP56Time2a时标的测量值规一化
35 带CP56Time2a时标的测量值标度化
36 带CP56Time2a时标的测量值短浮点
37 带CP56Time2a时标的累计量
38 带CP56Time2a时标的继电保护装置
39 带CP56Time2a时标的继电保护装置成组启动事件
40 带CP56Time2a时标的继电保护装置成组输出电路信息
41-44 为将来的兼容定义保留
控制方向过程信息(下行) 45 单命令
46 双命令
47 步调节命令
48 设点命令,归一化值
49 设点命令,标度化值
50 设点命令,浮点数值
51 32比特串
52-57 为将来的兼容定义保留
58 带CP56Time2a时标的单命令
59 带CP56Time2a时标的双命令
60 带CP56Time2a时标的步调命令
61 带CP56Time2a时标的设点命令,归一化值
62 带CP56Time2a时标的设点命令,标度化值
63 带CP56Time2a时标的设点命令,浮点数值
64 带CP56Time2a时标的32位比特串
65-69 为将来的兼容定义保留
监视方向系统信息(上行) 70 初始化结束
71-99 为将来的兼容定义保留
控制方向系统信息(下行) 100 总召唤
101 电能脉冲召唤命令
102 读命令
103 时钟同步命令
104 测试命令
105 复位进程命令
106 延时获得命令
107 带CP56Time2a时标的测试命令
108-109 为将来的兼容定义保留
控制下行参数信息(下行) 110 规一化值的参数
111 比例系数的参数
112 浮点数值的参数
113 参数的激活
114-119 为将来的兼容定义保留
文件传输 120 文件准备就绪
121 节准备就绪
122 召唤目录,选择文件,召唤文件,召唤节
123 最后节,最后段
124 确认文件,确认节
125
126 目录
127 为将来的兼容定义保留

2.3.2. 可变结构体(VSQ)

SQ=0:信息对象的地址不连续(意思就是每个信息对象都会一个对象地址),信息是无序的,接收方不需要按照顺序进行处理。
SQ=1:信息对象的地址连续 (只有第一个信息对象有地址,其他对象的地址就是累加1),信息是有序的,接收方需要按照顺序进行处理,以确保信息的正确性和完整性。
示例:

2.3.3. 传送原因(COT)


传送原因两字节分开,第1个字节高两位比特为T和P/N,COT 6比特。
T表示测试,只用于测试,不会控制处理器&更改系统状态

  • T=0 (非测试模式), T=1 (测试模式)
    P/N (positive/negative) bit
    积极/消极的激活确认。
  • 当使用主站下发命令时,这个位域是有意义的。该位域通常表示控制命令是否被成功执行 P/N=0表示肯定确认,P/N=1表示否定确认。

源发地址OA:用来标明响应来自那个主站的召唤,一般写0
传送原因如下表:

传送原因 语义 应用方向
1 周期、循环 上行
2 背景扫描 上行
3 突发 上行
4 初始化 上行
5 请求或被请求 上行/下行
6 激活 下行
7 激活确认 上行
8 停止激活 下行
9 停止激活确认 上行
10 激活终止 上行
11 远方命令引起的返送信息 上行
12 当地命令引起的返送信息 上行
20 响应站召唤 上行
21 响应第 1组召唤 上行
响应第 n组召唤 上行
36 响应第 16 组召唤 上行
37 响应累积量站召唤 上行
38 响应第 1组累积量召唤 上行
39 响应第 2 组累积量召唤 上行
40 响应第 3组累积量召唤 上行
41 响应第 4组累积量召唤 上行
44 未知类型标识 上行
45 未知的传送原因 上行
46 未知的应用服务数据单元公共地址 上行
47 未知的信息对象地址 上行

示例:

2.3.4. 应用服务数据单元地址即ASDU公共地址(Addr)

站地址:主站可以在一个104链路上连接多个子站,为了区分子站的报文而使用站地址,1-254为站地址,255为全局地址即广播地址。一般是主站和子站一对一通讯,默认值为1。
示例:

2.3.5. 信息对象地址(IOA)

信息对象地址:用于区分子站上不同应用的寻址,3字节,如遥控、遥信、遥调等地址不同。
当IOA=000000H时,表明本帧报文不携带数据,是功能性的报文,如总召、对时等。
02版本的104规约信息对象地址

应用 地址 点号
遥信 0001H 1
0002H 2
0001H-4000H 0003H 3
0004H 4
0005H 5
0006H 6
遥测 4001H 16385
4002H 16386
4001H-5000H 4003H 16387
4004H 16388
4005H 16389
4006H 16390
4007H 16391
遥控 6001H 24577
6002H 24578
6001H-6100H 6003H 24579
6004H 24580
6005H 24581
6006H 24582
6007H 24583
6008H 24584
6009H 24585
600AH 24586
遥调 6201H 25089
6202H 25090
6201H-6400H 6203H 25091
6204H 25092
6205H 25093
6206H 25094
6207H 25095

示例:点号24577,单点命令

2.3.6. 信息元素集

具体不展开,可参考文章:详解IEC104 规约【最详细版】,后续章节介绍常用的一些信息对象。

3. 总召命令

控制站(client)可以在任何时候发送召唤命令,以同步受控站(Server)中的所有过程变量的值。召唤命令分为总召唤群组召唤,现详细描述如下:

  • 总召唤/general interrogation (GI)
    总召唤命令会请求受控站(Server)中所有群组的所有数据对象的值的更新给控制站。
  • 群组召唤
    在受控站(Server)端,数据对象可以通过配置COT(传输原因)的值为20~36来设定数据对象的召唤群组。20代表总召唤,21~36 分别对应INRO1~INRO16,分别对应16个召唤群组。控制站(client) 在召唤时,可以通过指定召唤群组,来让该召唤组中的数据对象值更新。
    总召流程:主站下发总召命令→子站回复确认总召命令→子站上送信息→子站回复激活终止报文
    总召激活:68 0e 04 00 1a 00 64 01 06 00 01 00 00 00 00 14
    64:总召命令的类型标识
    06:激活总召
    14:总召-信息元素内容(站内询问-全局)


确认激活:68 0e 1a 00 06 00 64 01 07 00 01 00 00 00 00 14


子站上送单点信息:68 17 1c 00 06 00 01 8a 14 00 01 00 01 00 00 01 00 00 01 00 00 00 00 00 00
01:单点信息的类型标识
14:传送原因-响应总召
010000:IOA地址01
010000:第一个信息对象地址01
01:SIQ信息元素,最低位SPI标识单点遥信0分1合
又因为SQ的值为1,true状态,信息对象连续,后续信息对象地址在第一个地址基础上加1,故无地址,只有SIQ信息元素内容。
下面描述解释内容参考:https://blog.csdn.net/changqing1990/article/details/134327980

IV:VALID (0) / INVALID (1)。数据值是否有效,当采集系统识别到异常的情况(如更新设备丢失或无法运行),将这个位域标为1。该情况下信息对象的值,不会被定义。这个位为1表示信息对象的值是不正确的,不被使用
NT:TOPICAL (0) / NOT TOPICAL (1)。NT为刷新标志位,若最近的刷新成功则值就称为当前值(0),若一个指定的时间间隔内刷新不成功或者其值不可用,值就称为非当前值(1)。设备处于调试态或装置通讯中断都有可能造成非当前值。
SB:NOT SUBSTITUTED (0) / SUBSTITUTED (1)。SB为取代标志位,当信息对象的值由值班员(调度员)输入(即人工置数)或者由当地自动原因(模拟遥信)所提供时,即为被取代。如人工置数情况下。这意味着该值不是从正常测量中得出的。
BL:NOT BLOCKED (0) / BLOCKED (1)。BL为封锁标志位,信息对象的值为传输而被封锁,值保持封锁前被采集的状态。封锁和解锁可以由当地联锁机构或当地自动原因启动。


报文解析如下:


子站上送双点信息:68 0e 1e 00 06 00 03 81 14 00 01 00 0b 00 00 00
03:双点信息的类型标识
14:传送原因-响应总召
0b 00 00:IOA地址
00:DIQ信息元素内容,DPI最低两位比特标识双点遥信1开2合,0和3为中间状态


报文解析:


子站上送测量信息:68 8f 22 00 06 00 0d 9a 14 00 01 00 01 40 00 00 00 00 00 00 000000000000000000000000000000000000000000000000000000000000000000000054994b420000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
0d:浮点遥测的类型标识
14:传送原因-响应总召
014000:IOA地址4001
00 00 00 00 00:前四字节为32位浮点值,00表示QOS限定符
示例:0x54994b42转化成32为浮点数

import struct

def hex_to_float(hex_string):
    # 将十六进制字符串转换为整数
    int_value = int(hex_string, 16)
    # 将整数转换为32位浮点数
    float_value = struct.unpack('<f', struct.pack('!I', int_value))[0]
    return float_value

def float_to_hex_le(float_num):
    # 将单精度浮点数转换为小端存储的字节序列
    byte_data = struct.pack("<f", float_num)
    # 将字节序列转换为十六进制字符串
    hex_str = byte_data.hex()
    return hex_str

报文解析:


激活终止:68 0e 2a 00 06 00 64 01 0a 00 01 00 00 00 00 14
64:总召命令的类型标识
0a:传送原因-激活终止

4. 遥控命令

单点即使用1个比特位标识开关状态,只采集一个常开的辅助接点,值为1表示合位,0表示分位。
双点即使用2个比特位标识开关状态,采集常开常闭两个辅助接点,当常开点值为1并且常闭点值为0,即10表示合位;当常开点值0并且常闭点值为1,即01表示分位;当两个位置值都为1,或两个值都为0,则认为开关位置不能确定,中间状态。

命令传输分位直接控制(Single command)和选择控制(Select and execute)
直控的流程: 主站下发执行命令→子站回复确认执行报文。
选控的流程:主站下发选择(预置)命令→子站回复确认选择报文→主站下发执行命令→子站回确认执行报文→子站回激活终止报文

4.1. 单点命令

单点即使用一个比特位标识开关状态,值为1表示合位,0表示分位。
1、单点遥合
激活预置选择:68 0e 0c 00 22 00 2d 01 06 00 01 00 01 60 00 81
2d:单点命令的类型标识
06:传送原因-激活
81:最低位值为1表示合位,0表示分位,当前为合位;最高位值为1表示选择,0表示执行
IOA:24577是0x006001的十进制数,即遥合的点位


确认预置选择:68 0e 22 00 0e 00 2d 01 07 00 01 00 01 60 00 81
07:传送原因-确认激活预置


激活执行:68 0e 0e 00 24 00 2d 01 06 00 01 00 01 60 00 01
01:最低位值为1表示合位,0表示分位,当前为合位;最高位值为1表示选择,0表示执行


确认执行:68 0e 24 00 10 00 2d 01 07 00 01 00 01 60 00 01
07:传送原因-确认激活执行


激活终止:68 0e 26 00 10 00 2d 01 0a 00 01 00 01 60 00 01
0a:激活终止,命令执行完成


2、单点遥分
激活预置:68 0e 04 00 16 00 2d 01 06 00 01 00 01 60 00 80
确认预置:68 0e 16 00 06 00 2d 01 07 00 01 00 01 60 00 80
激活执行:68 0e 06 00 18 00 2d 01 06 00 01 00 01 60 00 00
确认执行:68 0e 18 00 08 00 2d 01 07 00 01 00 01 60 00 00
激活终止:68 0e 1a 00 08 00 2d 01 0a 00 01 00 01 60 00 00

4.2. 双点命令

双点:低两位用来标识开关状态,01为分位,10为合位,11和00状态不确定。
1、双点遥分
激活预置:68 0e 08 00 1c 00 2e 01 06 00 01 00 01 60 00 81
2e:双点命令的类型标识
06:传送原因-激活
81:低2位值为01表示分位,10表示合位,当前为分位;最高位值为1表示选择,0表示执行
IOA:24577是0x006001的十进制数,即遥分的点位


确认预置:68 0e 1c 00 0a 00 2e 01 07 00 01 00 01 60 00 81

激活执行:68 0e 0a 00 1e 00 2e 01 06 00 01 00 01 60 00 01
06:激活执行遥分
01:执行遥分


确认执行:68 0e 1e 00 0c 00 2e 01 07 00 01 00 01 60 00 01
07:确认预置
01:确认执行遥分


激活终止:68 0e 20 00 0c 00 2e 01 0a 00 01 00 01 60 00 01
0a:激活终止


2、双点遥合
激活预置:68 0e 10 00 28 00 2e 01 06 00 01 00 01 60 00 82
确认预置:68 0e 28 00 12 00 2e 01 07 00 01 00 01 60 00 82
激活执行:68 0e 12 00 2a 00 2e 01 06 00 01 00 01 60 00 02
确认执行:68 0e 2a 00 14 00 2e 01 07 00 01 00 01 60 00 02
激活终止:68 0e 2c 00 14 00 2e 01 0a 00 01 00 01 60 00 02

5. 时钟同步

时钟同步流程:主站下发时钟同步命令→子站回复确认时钟同步
时钟同步激活:68 14 04 00 1e 00 67 01 06 00 01 00 00 00 00 ab b8 3a 10 0b 01 18
67:时钟同步命令的类型标识
06:激活时钟同步
ab b8 3a 10 0b 01 18:主站向子站同步的时钟值-Jan 11, 2024 16:58:47.275000000 中国标准时间

时钟同步激活确认:68 14 1e 00 06 00 67 01 07 00 01 00 00 00 00 ab b8 3a 10 0b 01 18
67:时钟同步命令的类型标识
07:激活确认

6. 复位进程

复位进程流程:主站下发复位进程命令→子站回复确认复位进程
复位进程激活:68 0e 08 00 2e 00 69 01 06 00 01 00 00 00 00 01
69:复位进程的类型标识
06:激活复位进程
01:QRP复位进程信息元素内容


复位进程激活确认:68 0e 2e 00 0a 00 69 01 07 00 01 00 00 00 00 01
69:复位进程的类型标识
07:激活复位进程确认

0 条评论
某人
表情
可输入 255