You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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层的载荷判断逻辑
    若自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 09:52:46