(二)S7Comm协议分析

前言

上篇我们讲述了Modbus协议的基本原理和结构,这一篇我们把目光转移到转向私有协议,来看看另一家巨头西门子的S7Comm。

S7Comm是什么?

西门子是德国的一家超大型企业,在能源、工业、医疗、基建等等方面都有它的身影,同时它也位列全球500强第66名。作为一个以电报起家的大型企业,它对于通信更是重视,S7comm就是西门子为了它生产的PLC之间、SCADA与PLC之间的通信而设计的专属协议。

和Modbus的应用层协议不同,S7comm的协议栈修改程度更高,在应用层组织的数据经过COTP协议、TPKT协议的进一步处理后,最终通过TCP进行传输,下面是wireshark wiki给出的S7comm的协议栈:

OSI LayerProtocol
Application LayerS7 communication
Presentation LayerS7 communication(COTP)
Session LayerS7 communication (TPKT)
Transport LayerISO-on-TCP(RFC 1006)
Network LayerIP
Data Link LayerEthernet
Physical LayerEthernet

鉴于数据包逻辑上是由高层进行封装再一步步的转递给较低层,但我们接收到包后是低层一层层拆卸交给上层,基于逆向思维,我们之后的分析应该是由低向高展开的。

TPKT协议

我相信大家对于传输层往下的内容应该比较熟悉了,都是TCP/IP的基本内容,我就不再赘述,直接从会话层来看。

TPKT协议是一个传输服务协议,它为上层的COPT和下层TCP进行了过渡。我们常用的RDP协议(remote desktop protocol,windows的远程桌面协议)也是基于TPKT的,TPKT的默认TCP端口为102(RDP为3389),其实它本身为payload增加的数据并不多,主要就是以下几个:

在这里插入图片描述

  • version,1byte,表明版本信息
  • reserved,1byte,看到这个名字就知道是保留的了
  • length,2byte,包括payload和这三部分在内的总长度

COTP协议

COTP协议的全称是Connection-Oriented Transport Protocol,即面向连接的传输协议,从这个名字就可以看出,它的传输必然是依赖于连接的,所以在传输数据前必然有类似TCP握手建立链接的操作。

让我们先来看看具体的流量包

在这里插入图片描述
首先是TCP的三次握手,在192.168.25.146与192.168.25.139间建立了TCP连接,之后是两个COTP的包,注意,这里wireshark为我们标注出了CR和CC,后面的COTP包都是DT,这里的CR和CC其实分别是connect request和connet confirm的,也就是建立连接的过程,之后连接建立成功后,发送DT包,也就是data ,是在发送数据。

我们接着再看看他们携带的数据

在这里插入图片描述
可以看到,DT包和连接包有着明显的不同,连接包明显多了一堆内容,这其实是COPT包的两种形态,COTP连接包(COTP Connection Packet)和COTP功能包(COTP Fuction Packet)

首先来看COPT连接包,通过上面的wireshark的分析我们可以看到,主要有以下几个字段:

  • length,1byte,数据的长度,但并不包含length这个字段(个人感觉很奇怪……)
  • PDU type,1 byte,标识类型,图中的0x0d即为连接确认的类型,常有的还有
0xe,连接请求
0x0d,连接确认
0x08,断开请求
0x0c,断开确认
0x05,拒绝
  • DST reference,2byte,目标的引用,可以认为是用来唯一标识目标
  • SRC reference,2byte,源的引用,同上
  • option,1byte,可以看到wireshark将8位拆为了前四位和后两位:前四位标识class,也就是标识类别 倒数第二位对应Extended formats,是否使用拓展样式 倒数第一位对应No explicit flow control,是否有明确的指定流控制
  • parameter,附加的参数字段,参数可以有多个,每个参数又由以下几个字段构成:
code,1byte,标识类型
length,长度
对应的数据

接着就是COPT功能包:

  • length,1byte,长度
  • PDU type,1
    byte,图中为0x0f,即为数据传输,此外的type都不太常用,这里不再提了
  • option,1byte,以位为单位划分:
    第一位,标识是否为最后一个数据包(从这可以看出,COPT协议当数据较多时,会分为几个单元传输;后七位,标识TPDU的number。

S7Comm协议

总算是来到了最后的S7comm协议,它的结构很简单,主要分为三部分:

  • Header,主要是数据的描述性信息,最重要的是要表明PDU的类型
  • Parameter,参数,随着不同类型的PDU会有不同的参数
  • Data,具体的数据
    在这里插入图片描述
    header:
    在这里插入图片描述
  • Protocol id,1 byte,即协议的id,为0x32
  • ROSCTR,1byte,pdu的类型,一般由以下几种:
0x01,job,就是开工干活的意思,主设备通过job向从设备发出“干活”的命令,具体是读取数据还是写数据由parameter决定
0x02,ack,0x02,确认
0x03,ack data,从设备回应主设备的job
Reserved,2byte,保留
PDU reference,pdu的参考
parameter length,参数的长度
error class,错误类型,像是图中的0x00就是没有错误的意思,而常见的请求错误则是0x85
error code,错误码,结合错误类型来确定错误,图中的0x00同样是没有错误的意思

下面来看具体的流量包:

在这里插入图片描述
可以看到该pdu为job,也就是主设备在发号施令,而通过parameter可以看到,function是0x04的read,也就是读取数据,item count意思是后续跟了几个item,该pdu就一个,所以为1。而这个item的结构就有要单独说说了:

  • variable specification,1byte,一般就是0x12(我没见过别的……)
  • 长度,Length of following address specification,数据的长度
  • Syntax Id,符号id,一个标志,决定了一些格式性问题,这里是0x10是Address data S7-Any pointer-like DBx.DBXx.x的意思,主要就是对于后续的寻址起到了一定的限定
  • 传输大小,也可以认为是传输类型,在这是4,也就是WORD
  • DB number,就是数据块编号的意思,0就代表要找的东西不在数据块里
  • area,要操作的“东西”,比如0x82,就是读设备的输出,通过这一位也可以看到,我们要读的数据不在DB里,所以DB number为0,如果为DB的话,这1byte应该为0x84
  • address,具体的地址,如下图所示,前五位没用到,第六位到第二十一位是Byte地址,最后三位是Bit的地址

在这里插入图片描述
再来看看上个pdu的相应,这里截图没截到header,header最值得关注的是pdu的类型,这里是0x03,也就是我们之前提到过的对于job的相应

在这里插入图片描述

而paramter部分可以看到,function是与job pdu的相同的。Data部分就是传回来的具体数据了,return code是返回码,用来标识job让干活的结果,这里是0xff,代表的是成功的意思,除了这个,还有以下几种:

  • 0x01,硬件错误
  • 0x03,想访问的东西不让访问
  • 0x05,地址越界了
  • 0x06,你请求的数据类型和请求的”东西“的数据类型不一致

接着是data的长度(是真的data的长度,不包含前面),最后就是具体的data了,可以看到,这里读到的是0x0000。

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值