Online Digital Forensics Courses and Labs
Building a Low-cost and State-of-the-art IoT Security Hands-on Laboratory

Funded by National Science Foundation (NSF)
Funded by Cyber Florida

Modbus-based Industrial Control System Attack


 

Instructor: Dr. Cliff Zou, 407-823-5015, czou@cs.ucf.edu

Prerequisite:

  • Knowledge of basic usage of Linux machine and virtual machine environment.
  • Basic knowledge of networking and TCP/IP.

Goals of this tutorial:

  • Learn how to simulate Modbus-based industrial control system.
  • Understand the interactions and network traffic between Modbus Master and Slave.
  • Conduct basic penetration testing attack to Modbus-based ICS devices using Metasploit.

Software Needed:

  • VirtualBox (if you do not have VirtualBox installed please see Lab Setup).
  • Kali Linux VM for VirtualBox (can be downloaded here).
  • ModbusPal: a java-based Modbus slave simulator (download here).
  • QModMaster: a Modbus Master simulator (download here).

Basic Introduction:

Modbus: A Popular Communication Protocol for Industrial Control System (ICS)

There are several popular communication protocols for ICS. Modbus is a popular one; and there are many simulators for Modbus protocol. A very good Youtube tutorial on Modbus protocol and how it works can be found at: https://www.youtube.com/watch?v=k993tAFRLSE.

Key Points for Modbus:

Modbus Master and Slave Communication:

Modbus Master and Slave Simulator Setup:

There are many Modbus Slave Simulators. In this lab we will use ModbusPal (http://modbuspal.sourceforge.net/), which is a Java-code Modbus Slave simulator that can run under any Java supported OS. It provides GUI interface and can be used to create multiple Modbus Slaves conveniently.

When running ModbusPal on one virtual machine (VM1), it emulates a Modbus Gateway that has the IP address of the virtual machine (accepts TCP connections on port 502). When you create multiple Slaves using ModbusPal, each Slave is identified by its Unit ID (ranging from 1 to 247).

We run Modbus Master Simulator on another virtual machine (VM2). As long as VM2 can connect to VM1, the emulated Modbus Master can control/access those Modbus Slaves behind the Modbus Gateway. The network setup is illustrated in Figure 1.

 

Figure 1: Network Setup of Modbus Master and Slaves Using Two Virtual Machines

There are many free Modbus Master Simulators, such as Radzio Modbus Master simulator, QModMaster, and Mbtget. In this lab, we will use QModMaster simulator, which is a Windows-based Master simulator with GUI interface.

Under VirtualBox, we run ModbusPal Slave Simulator on a Kali Linux VM (VM1), and the QModMaster Master Simulator on a Windows VM (VM2). 

Interactions between Modbus Master and Modbus Slaves:

We first run the ModbusPal on Linux VM1 (192.168.1.104). The command to run this Java code is:

#java -jar ModbusPal.jar


Click "Add" button to manually add two Slaves (ID: 2 and 4). Click the 'eye' icon on a Slave bar to open the Slave panel and edit its content. In each Slave panel, add holding registers (16-bit) and coils (bit), and change some of their values. Note that coil only has value of 0 or 1. Then click the "Run" button on ModbusPal to run the simulator, which will listen and accept incoming TCP connections to port 502.
 

Figure 2: ModbusPal Running with Two Slaves Created

Note: ModbusPal 1.6b version has a bug that you can only manually add each Slave and change its registers/coils ---you cannot use the 'duplicate" button (the + icon) to duplicate another slave, nor use the "Load" to load a previously saved Modbus project file. Otherwise the Slaves cannot respond to Master's query correctly.

Second, we start the QModMaster Simulator on the Windows VM2 (192.168.1.106). Edit the "Modbus TCP..." under the "Options" menu, and put the ModbusPal's IP address (VM1). Then we click the "Connect" button to let Master set up TCP port 502 connection to ModbusPal. Now the Master is ready to access/modify Slaves' data.

 

Figure 3: QModMaster Simulator Configuration

Read Slave's Data: In QModMaster, change the "Slave Addr" to be the Slave ID you want to query, select the "Function Code" to read holding Slave's registers or read coils, choose the "Number of Registers/Coils" to be less than or equal to the number of registers/coils you have created on the Slave node. After this setup, click "Read/Write" menu button to read data. The following figure shows the Master obtains Slave 2's registers data, and Slave 4's coil data.

 

Figure 4: Modbus Master Read Registers/Coils data from Slaves

Modify Slave's Data: Next we test Modbus Master writing Registers/Coils data to Slaves. The following figure shows a change of multipe registers. On QModMaster, change the function code to "Write Multipel Registers", and change the number of Registers to be less than or equal to the Slave's predefined number of registers. After change those registers' values, click "Read/Write" command button, and you can see the register values on the corresponding ModbusPal Slave has been updated.

 

Figure 5: Modbus Master Modifies Multiple Registers on the remote Slave

Analyzing Modbus Master/Slave TCP Traffic Using Wireshark:

For the above experiments, before you click the "Read/Write" button on QModMaster, start Wireshark on Kali Linux (VM1) where the ModbusPal is running. Whenver you click the "Read/Write" button on the Master, you can see a query packet from Master to Slave and a response packet from the Slave to Master. The following figure shows the query and response packets from a QModMaster write command to write 3 registers' values to Slave #2.

 

Figure 6: Wireshark Capturing Query/Response Packets between Modbus Master and Slave


Using Metasploit to Attack Modbus Slaves:

Because Modbus Master communicates with Slaves in plain-text and there is no authentication procedure, an attacker can easily generate the same format of query packets to Modbus Slaves to access/modify Slave's registers/coils, as long as:

Hackers have incooperated Modbus attack modules in Metasploit, thus the second requirement above can be overcomed by using Metasploit. In Kali Linux, run "msfconsole" to start Metasploit. When you search modbus, you can find the following attack modules:

In this experiment, we use a second Kali Linux VM (VM3: 192.168.1.103) to launch Metasploit attack. To satisfy the first requirement above, VM3 should be put in the same LAN as the target VM (VM1: 192.168.1.104) where ModbusPal is running. 

Modbus Slave Scanner:

We can use the Metasploit "modbus_findunitid" attack module to scan and find out all Modbus Slaves existed in the LAN or behind a Modbus Gateway. For the two Slaves created by ModbusPal shown on Figure 2, the Modbus Slave Scan procedure is illustrated in the following figure. The only parameter to set is the 'rhost' IP address (target IP), and we can see Slave ID 2 and 4 have been found.

 

Figure 7: Use Metasploit to Scan and Find All Modbus Slaves

Modbus Slave Data Access/Modify:

We can use the Metasploit "modbusclient" attack module to read/write registers/coils on a given Modbus Slave. The explanation of modbusclient module can be found here. The following test use the Modbus example shown in Figure 2. The default action for modbusclient module is to read registers.

The following figure shows how to read the 5 register values from Slave 2. Note that the 'data_address' 0 means the address 1 on ModbusPal GUI panel.
 

Figure 8: Use Metasploit to Read Modbus Slave Registers

Now we change the 'action' option to "WRITE_COILS" to write multiple coil values to Slave 4. The attack procedure is illustrated in the following figure. The 10 bits coil values can be seen updated on the Slave 4 on the target VM1.

 

Figure 9: Use Metasploit to Modify Modbus Slave Registers