Funded by National Science Foundation (NSF)
Funded by Cyber Florida
Instructor: Dr. Cliff Zou, 407-823-5015, czou@cs.ucf.edu
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:
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).
We first run the ModbusPal on Linux VM1 (192.168.1.104). The command to run this Java code is:
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
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
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.
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
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