We now come to the final stages of the ICS Cyber Kill Chain
where we develop and test our ICS attack in an offline
environment before delivering it, installing and modifying it,
and then finally executing it.
First, we need to devise our attack methodology.
We know the Modbus protocol to be inherently unsecure
because traffic isn't encrypted,
and it doesn't require authentication between the sending and receiving parties.
We can take advantage of this by injecting our own
specially crafted Modbus packets.
With what we've learned about Scapy, that seems easy, right?
But we can't just fire packets into the network willy‑nilly.
If the packets are out of sequence with the rest of the network traffic
or somehow don't make sense to the receiving party,
then at best, they'll be dropped, and at worst,
they'll cause a connection reset or a process maloperation.
Reflecting again on our analysis of the Modbus traffic,
we know that the exchange of messages during a PLC cycle takes about 10 ms,
but the time between PLC cycles is about 100 ms.
Trying to sniff, craft,
and inject a packet in less than 10 ms would be challenging,
so we'll take advantage of the quiet time between cycles to do this.
The message exchange comprises six messages,
Read, Discrete, Inputs, Query, Response,
followed by by ACK, then Write Multiple Coils,
Query, Response, and ACK.
We need this final ACK to seed our packet for injection,
but we can't just search for any ACK packet because we could
end up syncing with the wrong TCP string,
so we need to find a way to find the ACK that immediately
follows the Write Multiple Coils Query Response.
The Write Multiple Coils that precedes the ACK we want to sync with
carries the data payload that sets the digital outputs.
Whilst that information changes as the process is controlled,
other parts of the packet remain static.
At the Modbus layer of packet 2980 shown here,
we see the function code is set to 15 for Write Multiple Coils, or
0F in hex, the reference number is set to 0,
the bit count is set to 10, or 0A in hex,
and the byte counts, the number of bytes in the data field,
is set to 2.
These numbers never change for a Write Multiple
Coils packet in this application.
Therefore,
if we search for this pattern in the sniff traffic and then
capture the next ACK packet received, we can seed our malicious packet.
Next,
we can craft our malicious packet using Scapy. From the captured ACK packet,
we'll extract the source and destination IP addresses and ports,
as well as the sequence and acknowledge numbers.
Scapy doesn't natively support Modbus,
but it provides us with the capability to create any packet structure we like,
so we can create our own Modbus layer and add it to
the IP and TCP layers we build.
Finally,
we'll use sendp to inject the packet at layer 2 and use
Wireshark to monitor the effects.