Scapy解析S7Comm协议层级错误问题排查求助
排查Scapy解析S7Comm报文层级错误的方案
核心排查步骤
修正COTP相关绑定规则
Scapy2.5.0默认解析逻辑可能错误嵌套了COTP层,先清理旧绑定再重新关联正确层级:# 清除COTP与错误子层的绑定(需替换为实际触发COTP解析的字段值,比如pdu_type=0x02) if 0x02 in conf.layers_binding.get(COTP, {}): del conf.layers_binding[COTP][0x02] # 绑定COTP_TCP_Data直接承载S7COMM bind_layers(COTP_TCP_Data, S7COMM)重点确认:COTP的
pdu_type为0x02(Data PDU)时,应触发COTP_TCP_Data解析,而非COTP层。校验S7COMM长度字段计算
出现Raw层通常是Scapy认为S7COMM载荷未读完,检查自定义S7COMM层的length字段:- 对比原始字节流中S7COMM段的实际长度,与Scapy解析出的
S7COMM.length是否匹配 - 确认长度字段是否包含自身头部长度(S7COMM协议中长度通常含头部),若计算错误会导致剩余字节被识别为Raw
- 对比原始字节流中S7COMM段的实际长度,与Scapy解析出的
检查S7COMM层的载荷判断逻辑
若自定义S7COMM层重载了guess_payload_class,需确保它不会错误返回Raw类:def guess_payload_class(self, payload): if not payload: return NoPayload # 根据S7COMM功能码或子结构规则判断,而非直接返回Raw return S7COMM_SubPDU # 替换为实际子层类,或调用父类默认逻辑强制手动解析验证
用原始字节流手动构建报文,排除自动解析干扰:from scapy.all import raw, TPKT, COTP_TCP_Data, S7COMM raw_data = b"..." # 接收的完整字节数据 pkt = TPKT(raw_data) pkt.payload = COTP_TCP_Data(raw(pkt.payload)) pkt.payload.payload = S7COMM(raw(pkt.payload.payload)) print(pkt.show())手动解析后层级正常的话,说明自动解析的绑定规则仍未生效,需细化bind_layers的触发条件(比如指定COTP的pdu_type参数)。
适配Scapy版本差异
对比旧版Python2 Scapy与2.5.0的ISO-on-TCP解析逻辑:- 确认COTP_TCP_Data的类定义是否继承正确父类
- 检查TPKT与COTP_TCP_Data的默认绑定是否被新版本覆盖
内容的提问来源于stack exchange,提问作者Mories
相关产品推荐
相关产品推荐

