Learning Modbus TCP with ControlThings.IO
- Only 1 master is connected to the network at a time.
- Only the master can initiate communication and send requests to the slaves.
- The master can address each slave individually using its specific address or all slaves simultaneously using address 0.
- The slaves can only send replies to the master.
- The slaves cannot initiate communication, either to the master or to other slaves.
So we can immediately see that we have a .10 host issuing queries and a whole bunch of others responding. Let's confirm our suspicion that 148.81.0.10 is the master by applying some display filters. First, let's see all the packets where .10 is the source:
So in addition to the master we have a total of 13 slaves it's talking to. (Notice the huge difference in the volume of traffic sent from the master compared to each individual slave). I found another great description of Modbus TCP here where it's stated that:
"Modbus will support up to 247 slaves from addresses 1 to 247 (JBUS 1 to 255) - address 0 is reserved for broadcast messages. In practice, the number of slave addresses that can be used is determined by the communications link that is chosen. For example, RS485 is limited to a total of 31 slaves."
So that's question 2 answered. The next question asks us whether the master is writing any data to the slaves. Let's have a look!
Well that seems pretty clear, we seem to have several different 'Read' operations being performed but also at least one 'Write' operation ('Write Multiple Coils'). But lets have a quick look at the Modbus specification to confirm this:
Okay, so here we see that Modbus supports many different read and write operations and the specification provides full details of each. Notice how the function number in the spec also corresponds to what is actually displayed in the packet itself: 'Write Multiple Coils' is function 15, 'Read Discrete Inputs' is function 2 etc. Nice!
On closer inspection, the majority of traffic in the capture appears to consist of the following 4 functions:
- Function 1: Read Coils
- Function 2: Read Discrete Inputs
- Function 4: Read Input Registers
- Function 15: Write Multiple Coils
So next, the final part of the challenge asks us to identify whether the spike in traffic in the middle of the capture is related to Modbus. Let's take a look at that now. First of all where is this spike? We can use the I/O Graph in Wireshark to analyse the traffic in this capture and this is what we get:
Hmmm ... no obvious spike there that I could see anyway. I reached out to ControlThings.io on their Discord and queried this. Shortly after I got the following reply from Justin Searle:
"Correct. There is no Modbus spike. And sorry, that question originates from the ~/Samples/Protocols/Combined/Plant1.pcap capture which is a superset of that Modbus capture and several other captures. If you check out that Plant1.pcap file, you will see there is a traffic spike in another protocol."
Okay, so sounds like we're done with Modbus for now, but let's check out that other pcap that Justin is talking about:
So immediately we can see multiple protocols are in use here, not just Modbus. Let's retry that traffic analysis and see if we can find the spike:
And there we have it! So now let's try and figure out what's causing it. By clicking directly at the top of the spike we can see that the traffic spikes at packet no. 28254, so let's take a look at that:
As we can see, this is indeed not a Modbus spike but instead appears to be caused by 148.81.0.10 sending CIP (Common Industrial Protocol) Multiple Service Packets to a range of other hosts that are then responding with Success messages.
After checking back in with Justin, I was reminded of the "Try Harder" days of OSCP. There is more to this part of the challenge than meets the eye as it turns out and CIP is not what's actually causing the spike! Using Justin's hints I modified my approach as follows:
First up, I changed the I/O graph to display bytes instead of the default, which is packets. This resulted in a much more prominent visualisation of the traffic spike as shown below:
To change the display to bytes you need to double-click on the the word "Packets" in the "Y Axis" column and this then brings up a drop-down control that lets you choose what you want shown on that axis.
Another improvement that lets us see the spike in even more detail is to change the default time-interval down from 1 second to 10ms or 100ms. The screenshot below shows the spike displayed with a 100ms interval:
So if it's not CIP, what is actually causing this spike?
The first thing I wanted to do was to reduce the size of the problem space. I identified the packet numbers of the approximate start and end of the spike and used editcap to create a new pcap file containing only those packets I was interested in:
With only around 3000 packets, my new file (Spike.pcap) was much more manageable to work with. I took a look at the I/O graph of the new file, showing all the traffic:
Next, I created a bunch of traffic filters, one for each protocol in the new PCAP file and applied them:
As can be seen, the TDS protocol traffic matches the profile of the spike, accounting for significantly more traffic than the other protocols at this timestamp. So let's dig a little deeper and look at the traffic stats for the capture:
Interestingly, in my new capture file there were only 12 more TDS packets than Modbus packets during the period of the spike and the TDS packet count was only 2.5% higher than Modbus. Looking at this, I began to wonder whether TDS was really the source of the spike. However, returning to the I/O graph and viewing the size of the TDS traffic (red) compared to the Modbus traffic (black) it was pretty clear what's going on:
I really enjoyed this exercise and it was a great way to dip a toe in the water with some of these industrial protocols for the first time. It was also great to learn some new features of Wireshark and to see how easy it is to fall into the trap of making incorrect assumptions about network traffic.
Many thanks to Justin and the team at ControlThings.IO! Check out their Discord server and download ControlThings.IO here.
Comments
Post a Comment