Craft Modbus
Craft Modbus
protocol in part because it is open and free. Like other industrial controls systems protocols
though, it was not designed with security in mind. A tool like Scapy, which is designed amongst
other things to craft and send packets, could allow an attacker to inject specially crafted packets
The Modbus protocol comes in different versions including Modbus over TCP/IP and
Modbus RTU. The structure of Modbus RTU utilizes the following fields: 1-byte slave ID
address, 1-byte function code, 2-byte data address of the first register, 2-byte value indicating the
number of registers selected, and a 2-byte cyclical redundancy check (CRC). The protocol data
unit (PDU) is made up of the preceding structure except for the slave ID and CRC. A summary
of the protocol’s structure as both Modbus RTU and Modbus over TCP/IP is shown in Figure 1.
Figure 2
Start Scapy by running the command “scapy” in the Linux terminal. In Windows, one
may have to follow the directions located in the Scapy documentation. (Biondi & Community,
2018)
It is simple to create an empty IP packet. Use the IP() function to create the packet.
Arguments can be passed in to initialize the packet with desired attributes. After creating the
packet, it can be viewed in a few forms. A raw view of the hex can be viewed by passing the
packet into the hexdump() function. There is a display() method that can be called on the packet
that will display the packets attributes more cleanly. An example of a simple packet and its
dissection can be found in Figure 3. Building the TCP/IP stack only requires adding those
Figure 3
Now that the basic functionality of Scapy has been demonstrated, the next step will be to add the
fields needed to the packet to replicate a Modbus packet. In this instance, the packet displayed in
Figure 4
CRAFTING MODBUS PACKETS WITH SCAPY 4
Set the source and destination fields by using the following commands.
Ether(src=src_mac, dst=dst_mac)
IP(src=src_ip, dst=dst_ip)
TCP(sport=src_port, dport=dst_port)
Figure 5
CRAFTING MODBUS PACKETS WITH SCAPY 5
It may be apparent that there are several fields in the output that have not been modified.
For instance, the “ihl” field is set to “None”, but Scapy was never directed explicitly to add that.
This is because there are many fields that come with default values which one can view by
Figure 6
If Scapy is going to mimic the packet exactly, then all the fields must be the same as the
test given. The interactive shell that has been used to this point is convenient for setting a few
variables and performing some quick tests, but if Scapy is to perform more advanced tasks, it
The module will need to be imported by typing “from scapy.all import *”. From there the
all the fields that have been covered will need to be defined. Also, Modbus is not a part of the
module so there will need to be a child class of the Packet class defined. The layer will be
comprised of fields just as in other layers. The format to do this is defined in figure 7. The field
type does not have to be ShortField or XByteField, but they were used for this example.
Figure 7
CRAFTING MODBUS PACKETS WITH SCAPY 7
When the hexdump from this packet is performed, one sees that it is identical to the hex
When this is called, the script now shows that it has sent a packet.
If this is being captured, the results should be as expected and in using tcpdump in this
References
B+B SmartWork. (2018, September 11). MODBUS TCP/IP AT A GLANCE. Retrieved from B+B
SmartWork: http://www.bb-elec.com/Learning-Center/All-White-
Papers/Modbus/Modbus-TCP-IP-at-a-Glance.aspx
Biondi, P., & Community, S. (2018). Download and Installation. Retrieved from Scapy:
https://scapy.readthedocs.io/en/latest/installation.html
Modbus.org. (2018, September 18). Modbus Application Protocol Specification. Retrieved from
http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b3.pdf