DNP3协议简单介绍及协议识别方法

0x1 简介

DNP(Distributed Network Protocol,分布式网络规约)是一种应用于自动化组件之间的通讯协议,常见于电力、水处理等行业。SCADA可以使用DNP协议与主站、RTU、及IED进行通讯。
DNP协议标准由IEEE提出,参考了IEC 870-5、以及其他一些IEC协议。主要为了解决SCADA行业中,协议混杂、没有公认标准的问题。
DNP协议有一定的可靠性,这种可靠性可以用来对抗恶劣环境中产生的电磁干扰、元件老化等信号失真现象,但不保证在黑客的攻击下、或者恶意破坏控制系统的情况下的可靠性。
DNP协议提供了对数据的分片、重组、数据校验、链路控制、优先级等一些列的服务,在协议中大量使用了CRC校验来保证数据的准确性。以下是一些DNP协议的特点:
• DNP3.0规约是一种分布式网络协议,适用于要求高度安全、中等速率和中等吞吐量的数据通信领域。
• DNP3.0规约以IEC870-5标准为基础,该规约非常灵活,满足目前和未来发展的要求,且与硬件结构无关。
• DNP3.0规约采用网络通信方式。
• DNP3.0规约支持点对点、一点多址、多点多址和对等的通信方式。
• DNP3.0规约支持问答式和自动上报数据传输方式。
• DNP3.0规约支持通信冲突碰撞避免/检测方式,能保证数据传输的可靠性。
• DNP3.0规约支持传送带时标的量,尤其有利于配电自动化系统采集分时电度值和分析事故原因。
• 灵活采取适当的扫描方式,DNP3.0规约可以在一定程度上实现实时优先级。

0x2 协议格式

DNP3.0规约的文本共分4部分:数据链路层规约,传输功能,应用层规约及数据对象库。

DNP3.0 可以承载在 tcp 链路上

0x2.1 数据链路层规约 

数据链路层规约文件规定了DNP3.0版的数据链路层,链路规约数据单元(LPDU)以及数据链路服务和传输规程。
数据链路层采用一种可变帧长格式:FT3。
一个FT3的帧被定义为一个固定长度的报头,随之以可选用的数据块。每个数据块附有一个16位的CRC校验码。固定的报头含有2个字节的起始字,1个字节的长度,1个字节的控制字,1个16位的目的址,1个16位的源地址和1个16位的CRC校验码。

 DNP 协议FT3 如下

  注:控制 control 1 字节。

  1. DIR: 方向(DIRECTION)位
  • DIR=1 表示此帧自A发向B(即主站发出方向)
  • DIR=0 表示此帧自B发向A(即发向主站方向)

     2、PRM: 原发标志位(PRIMARY)

  • PRM=1 表示此帧来自原发站(通信发起站)
  • PRM=0 表示此帧来自响应站(通信应答站)

        注意:原发站不一定就是主站,外站也可以是原发站。

      3、FCB:帧的计数位(FRAME COUNTBIT)

  • 系用以防止对同一个副方站丢失或重复信息帧,每次成功地完成一次发送并确认(SEND-CONFIRM)服务(即由同一个原发站起动,向同一个副方站的发送服务)后该位就翻转一次。

     4、FCV:帧计数有效位(frame count valid),它可使FCB位生效。

  • FCV=0 表示FCB位无效。
  • FCV=1 向副方站指示本帧的FCB位状态有效,必须和FCV置位的最近一帧之FCB位状态进行校核

      5、DFC 数据流控制位

 防止从站的数据溢出,如果主站送入的数据导致从站数据溢出,则相应消息中包含这个标示位,需要主站通过查询链路状态进行恢复.

      6、 功能码

0x2.2 传输功能TPDU

这部分定义对于DNP数据链路层充当伪传输层的传输层功能。伪传输层功能专门设计用于在原方站和副方站之间传送超出链路规约数据单元(LPDU)定义长度的信息。

 

0x2.2.1 传输层报头数据块

其中:传输层报头——传输控制字,1个字节;数据块——用户数据,1~249个字节。

 

       

FIN  表示是否是最后一帧

  1. FIN=0 非最后一帧
  2. FIN=1 最后一帧

FIR  表示构成报文的第一帧

  1. FIR=0  非第一帧
  2. FIR=1 第一帧 

0x2.3 应用规约 APDU

这部分定义了应用层报文(APDU)的格式。这里,主站被定义为发送请求报文的站,而外站则为从属设备。被请求回送报文的RTU或智能终端(IEDs)是事先规定了的。在DNP内,只有被指定的主站能够发送应用层的请求报文,而外站则只能发送应用层的响应报文。

0x2.3.1 应用报文格式

请求(响应)报头——标识报文的目的,包含应用规约控制信息(APCI);对象标题——标识后随的数据对象;数据——在对象标题内的指定类型的数据对象。

0x2.3.2 应用报文报头字段的定义

请求报头分应用控制、功能码两个字段。每个字段为8位的字节;响应报头分应用控制、功能码、内部信号字3个字段。每个字段也为8位的字节。

 请求包头

 响应包头

 APCI

 字段含义

  1. FIR:此位若置“1”,表示本报文分段是整个应用报文的第一个分段。
  2. FIN:此位若置“1”,表示本报文分段是整个应用报文的最后一个分段。
  3. CON:此位若置“1”,表示应用报文的发送方期待接收该分段的一方在收方的应用报文中给予确认接受方予以确认,且在确认报文内用一个应用功能码(0)。
  4. SEQUENCE:表示分段的号码。分段号码0至15是为主站 的请求和全部外站的响应保留的(不是主动上报的响应)。分段号码16至31是为外站来的主动上报的响应保留的。关于主动上报的响应,每个来自或发向同一外站的每个连续的分段也都必需有一个升序的序号(这个号码自15溢出到0)。
  •           主站与外站应用的响应逾时。这些逾时规定了一个应用对一个响应必需等待多长时间,或对CONFIRM响应要等待多长时间方才重发或异常地中断通信的回合。
  •           主站与外站应用的重发计数。应用可以支持也可以不支持应用层的重发,重发计数规定,如果响应失败,请求可重发几次,或者收不到CONFIRM响应时可将原响应重发多少次。
  •           一个外站在开始处理第二个请求之前,必须将前一个请求完全处理好并对它作出响应。它不能同时处理多个请求。
  •           主站发到外站的全部请求其序号为0至15。发自外站的非请求的响应其序号则包括在16至31以内。
  •           注:一个未经请求的响应是外站发出的一个报文,通常它包含着事件数据,它会自动发送给主站,主站无需为这个数据而询问外站。
  •           注:建议外站所报告的任何已变化了的数据在发送时均要求在响应中带有确认。

  功能码

    

1. 传输功能码
代码功能说明
0确认用于对请求与响应报文分段之确认。对此报文不要求响应。
1请外站送所指定的对象;以所请求的对象(可用的对象)作响应。
2向外站存入指定的对象;以操作的状态作响应。
2. 控制功能码
代码功能说明
3选择选择或打开输出点但不置定或产生任何输出作用(控制,
设置数值,模 拟输出);以所选控制点的状态作响应。“操作”功能码被用以激活这些输出。
4操作对于由“选择”功能所已选定的点设置或产生输出动作;
用控制点的状态作为响应。
5直接操作选择并设置或操作指定的输出,用控制点的状态作响应。
6直接操作,无确认6 选择并设置或操作指定的输出,但不发送响应给请求方。
3.冻结功能码
代码功能说明
7立即冻结复制指定的对象于一个冻结缓存,并以操作的状态作响应。
8立即冻结(无确认)复制指定的对象于一个冻结缓存,不用报文作响应。
4. 传输功能码
代码功能说明
9冻结与清除复制指定的对象于一个冻结缓存,然后清除对象,用操作的状态作响应
10冻结与清除(无确认)复制指定的对象于一个冻结缓存,然后清除对象,不用报文去响应。
11有时间的冻结在指定的时间和时间间隔上,复制指定的对象于一个冻结缓存,用冻结操作的状态作响应。
12有时间的冻结(无确认)复制指定的对象于冻结缓存,在指定的时间和时间间隔上,不用报文去响应
5.应用的控制功能码
代码功能说明
13冷再启动实现所要求的复位顺序;以指示时间的时间对象作响应,直到外站可以工作为止。
14热再启动实现所要求的部分复位顺序;以指示时间的时间对象作响应,直到外站可以工作为止。
15将数据初始化到缺省值将指定的数据初始化到上电的初始值;以操作的状态作响应。
16初始化应用程序使指定的应用程序准备就绪运行;以操作的状态作响应。
17启动应用程序启动指定应用程序运行;以操作的状态作响应。
18停止应用程序停止指定的应用程序;以操作的状态作响应。
6. 组态功能码
代码功能说明
19保存组态将指定的组态数据保存入非易失的存储器用一个指示时间对象作响应直到外站可用为止。
20允许非请求报文允许对指定的时间对象自发地报告;以操作的状态作响应。
7.传输功能码
代码功能说明
21停用非请求报文停用指定数据对象的自发报告;以操作的状态作响应。
22分配等级将指定的数据对象分配给特定的等级(CLASS)。
8.时间同步功能码
代码功能说明
23延迟测量允许应用程序为一个特定的外站计算其通路的延迟(或传播延迟)。由此功能码所算出的数值应被用以在设置外站时间时,调节日期的时间
9.保留功能码
代码功能说明
23~120保留供今后之用
121~128仅保留供测试之用
10.响应功能码
代码功能说明
0确认对报文分段的确认,既用于请求也用于响应,该报文不请求响应。
129响应响应于一个请求的报文。
128非请求的响应非由请求提示的非请求响应。

0x2.3.3 应用报文交互原则        

序号工作规则

  1. 序号自15滚到0或31滚到16。从DNP主站发出的每个连续的请求分段都有一个升序序号。至于请求报文的重发则例外。关于单个分段的请求在重发时其序号是不递增的。至于多分段请求的重发,所重发的请求中第一个分段的序号就是方才失败的请求之最后分段的序号。
  2. 对于单分段的请求其单分段响应具有与请求相同的序号。
  3. 对一个单分段请求的多分段响应,它的第一个分段,具有与请求相同的序号。至于多分段响应的后续分段,其序号是递增的
  4. 对于多分段请求的多分段响应,其第一个分段的序号与多分段请求的最后分段之序号相同

重发处理规则

  1. 当一个响应在逾越时限之后没有被收到,如果系统使用的是应用层重发,则该请求将仍用同一序号重发。
  2. 如果所收到的两个报文具有相同的序号,通常意谓着报文的响应未被对方站收到。在这种情况下,就重发响应(不必要重新处理这个报文)。
  3. 如果所收到的两个CONFIRM响应具有相同的序号,则不理会第二个响应。

主站的请求与非请求响应之冲突

​       当外站发生了非请求响应时,有一种可能是在外站发送非请求响应的同时,主站也在发送请求。当外站期待收到对其非请求响应的CONFIRM时却收到了主站的请求。主站正期待收到其请求的响应时收到了非请求的响应。

​        对上述情况以及类似情况的处理取决于主站所发出的请求之类型。

​        主站永远将立即处理非请求响应,即使主站正在期待先前所发请求之响应时,也要立即处理非请求响应。如果外站要求确认(即CON位置位)主站就要立即发出对非请求响应之CONFIRM。

​        通常外站将立即处理请求,即使它正在期待先前所发请求响应之CONFIRM。除了对系统数据(例如二进制输入数据,事件计数数据等等)的READ请求以外,所有的请求都按此处理。这种操作模式被称之为立即处理(IMMEDIATE_PROCESS MODE)模式。另一种办法是外站若正在等待先前非请求响应之CONFIRM时,它就不处理主站来的READ请求,在处理请求之前,将先等待CONFIRM.这种功能性的变异,其目的在于防止数据事件之丢失或重复。这种操作的模式被称之为PROCES_AFTER_CONFIRM(确认后处理)模式。

  • 立即处理模式(IMMEDIATE PROCESS)
  • 确认后处理模式(PROCESS AFTER CONFIRM)

​       当外站收到一个对系统数据的READ请求时,并且先前一个非请求响应也尚未得到CONFIRM时,外站将不处理READ请求,直到非请求响应获得CONFIRM为止。如果外站立即处理了READ请求,就要承担失落数据或数据重复的危险。这是因为有可能READ请求所要的数据对象已经在尚未CONFIRM的非请求响应之中了。

出错后数据恢复

       DNP应用层依靠数据链路层作所有报文的发送 接收与检错,应用层不负责对通信问题的恢复。如果一个通信回合的故障被数据链路层报出,应用层应中止应用层的通信回合并向用户报告出错。此外,主站应用层应指示出全部外站响应内的内部信号值。用户层负责启动任何一种出错的恢复步骤,用户层特别应利用自任何外站响应发送回来的内部信号(IIN)。

0x2.3.4 对象标题

报文的对象标题制定包含在报文中的数据对象或是被用来响应此报文的数据对象。
应用报文中,对象、限定词、变程的灵活使用,可以表示多种数据类型和数据表示格式,满足用户的不同需要。这也是DNP3.0规约的一大优点

0x3 DNP设备识别方法

DNP3可通过TCP/UDP进行封装,以便在以太网上运行,支持DNP3协议的从设备默认会开放TCP的20000端口用于通信。DNP3协议在设计之初依然是没有考虑到安全、认证等的一些因素,以致后来出现了Secure DNP3(主要加强了认证)。在DNP3目前的应用、传输上个人的观点还是要比MODBUS可靠,DNP3在主站会话上需要约定目的地址、源地址,而从设备收到后需要验证目标地址,然后再进行处理,如果目的地址不相同则会根据在协议栈实现的处理上来决定是否不响应和关闭连接,或者返回异常功能报文等。想要精准识别运行在tcp的20000端口的服务是否为DNP3,可以使用DNP链路层协议(协议格式如下图),

dnp3_link


将其封装成需要发送的识别报文,这样便可以枚举出想要通信设备的目的地址,又能准确判断该端口运行有DNP3服务,并且报文构造相对简单。
在协议的控制字方面可以使用协议中的9号功能码请求链路状态,相应的设备如果响应回复一般则会返回11,如下图为控制字格式:

dnp3_control_code


如下图为功能码取值:

dnp3_control_function_code

需要注意的是正因为设备对非法连接(目的地址)请求的处理方式不一样,在应用到实际的全网扫描中不可能全部尝试到所有的地址(目的地址长2个字节,范围在0-65535),另外还需要实现协议的CRC的算法。这样从实现到扫描整体的代价都会比较大。

那么我们可以看一下Shodan在DNP协议的识别这块是如何做的,如下图是在公网监听了tcp/20000端口后收到的包。

shodan_dnp3_1


我们可以看到Shodan在针对DNP3协议在公网扫描识别上,也还是采用了枚举的方式,并且看似有些暴力,再根据下图你会发现Shodan总共尝试了101个地址,

shodan_dnp3_enumerate


故你会在Shodan检索port:20000时发现设备的源地址(Source address/对应主站的目的地址)都没有超过100。

那我们实现针对DNP的扫描插件时也可参照Shodan的做法,在组包时定义一段范围的地址来进行批量探测,并且探测1-100的目的地址组包大小有1010个字节,在批量扫描探测时还要受网络收发延时影响。所以Shodan目前能检索到的数据也不足1000,现在看来貌似也没有相对好的做法。

根据Shodan的套路这个扫描规则还是很好制定的,我们可以定义一个探测包,再定义判断返回报文的长度、包头部是否为DNP的协议头0x05,0x64,然后解析源、目的地址、功能码,非常简单就能实现一个与Shodan一模一样的针对DNP3协议扫描的基于NMAP的NSE插件。

dnp3-enumerate

0x4 调试及工具分享

如下工具可以快速帮你熟悉、调试、仿真、测试DNP3协议:

opendnp3

opendnp3是automatak开源的基于IEEE-1815 (DNP3)的开源协议栈。

Aegis™

Aegis™是automatak开源的一个针对工控协议进行模糊测试(Fuzz)的框架,其中包含对DNP3协议模糊测试的模块,官方的Project Robus项目曾经发布过多个应用在DNP3协议健壮性上的漏洞,官方在发布MODBUS模块后貌似没有再继续开源了。

Protocol Test Harness

Protocol Test Harness是Triangle MicroWorks公司开发的一款协议仿真、调试软件,软件可以仿真多种工控协议包括DNP3,可以方便你完成调试、仿真

  • 5
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值