trying to build a MODBUS packet with scapy

时间:2016-08-31 12:23:16

标签: python-2.7 scapy modbus-tcp

i'm trying to build a MODBUS packet with scapy, but Wireshark can't recognize it. i mean, the MODBUS interpreted as the TCP data.

here is the python code of Scapy:

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())

someone has an idea how to fix it?

2 个答案:

答案 0 :(得分:0)

我运行了相同的代码,但进行了两次更改,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。

答案 1 :(得分:0)

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

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

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

参考文献: