1

我正在尝试使用 scapy 构建一个 MODBUS 数据包, 但 Wireshark 无法识别它。我的意思是,MODBUS 被解释为 TCP 数据。

这是 Scapy 的 python 代码:

from scapy.all import *


class Modbus(Packet):
    name = "Modbus/tcp"
    fields_desc = [ ShortField("Transaction Identifier", 1),
                    ShortField("Protocol Identifier", 0),
                    ShortField("Length", 5),
                    XByteField("Unit Identifier",0),
                    ]

def make_test():
    pkt = TCP(sport=502, dport=502)
    return Ether()/IP(src="5.5.5.101",dst="5.5.5.100")/pkt/Modbus()


while True:
    send(make_test())

有人知道如何解决它?

4

2 回答 2

1

我用 2 处更改运行了相同的代码,Wireshark 将其识别为 Modbus:

首先,当您发送空数据包(n=0)时,长度字段的默认值必须为 2,而不是 5(根据Wikipedia为 n+2 。

其次,您缺少字段功能代码。

所以,最后我的 fields_desc 看起来像这样:

fields_desc = [ ShortField("Transaction Identifier", 1),
                    ShortField("Protocol Identifier", 0),
                    ShortField("Length", 2),
                    XByteField("Unit Identifier",0),
                    ByteField("Function Code", 0)
                    ]

Wireshark 抱怨是因为 0 实际上不是有效的功能代码,但它正确地将其解释为 modbus。

于 2019-10-24T10:53:10.190 回答
0

您的代码中没有 3 次 TCP 握手,这意味着主机之间没有建立通信通道。为了解决这个问题,需要创建套接字。

这是我的代码,可能对其他人有帮助。

from scapy.all import *
import time

# Modbus ADU
class ModbusTCP(Packet):
    name = "Modbus/TCP"
    fields_desc = [ ShortField("Transaction Identifier", 1),
                    ShortField("Protocol Identifier", 0),
                    ShortField("Length", 6),
                    XByteField("Unit Identifier", 247),
                    ]

# Modbus PDU
class Modbus(Packet):
    name = "Modbus"
    fields_desc = [ XByteField("Function Code", 4),
                    ShortField("Reference Number", 1),
                    ShortField("Word Count", 2),
                    ]

# Create a socket and connect
s = socket.socket()
s.connect(("192.168.95.10", 502))   # IP and port
ss = StreamSocket(s, Raw)

while True:
    try:
        # Encapsulate modbus inside the raw data, then send and receive
        # Anything can be done with response
        ss.sr1(Raw(ModbusTCP()/Modbus()))
        time.sleep(1)
    except KeyboardInterrupt:
        break

参考:

于 2021-08-10T14:33:04.067 回答