We now have a good picture of our target environment,
and our recon activities have identified a number of hosts and services that
we may want to target in the next stage of the attack.
In particular,
we identified a PLC communicating with operational technology in a
factory environment using the Modbus protocol.
Modbus is an industrial protocol standard that was created by Modicon,
now Schneider Electric,
in the late 1970s for communication between
industrial control system components.
It's a free and open source protocol and is still the most widely
used protocol for connecting industrial devices.
The Modbus protocol is a client‑server architecture meaning a
client device polls one or more server devices.
This means a server device can't volunteer information.
It has to wait to be asked for it.
The client writes data to a server's registers and
reads data from its registers.
A register address or register reference is always in
the context of the server's registers.
In the initial implementation,
Modbus was a single protocol built on top of serial,
so it couldn't be divided into multiple layers.
Over time, different application data units have been introduced,
for example, to allow the use of Modbus in TCP/IP networks.
This led to a separation of the core protocol which
defines the protocol data unit, or PDU, and the network layer,
which defines the application data unit,
or ADU.
The PDU and the code that handles it comprises the core of the
Modbus application protocol specification.
The PDU consists of a 1‑byte function code followed by up
to 252 bytes of function‑specific data.
Every function code has a specific behavior that servers can
flexibly implement based on the particular application.
In addition to the functionality defined at the PDU core,
Modbus can communicate over different types of network.
The most common protocols are serial and TCP/IP,
but you can use others like UDP as well.
There are ADU variants for each network protocol,
but for this course, we'll focus on communication across TCP/IP networks.
TCP ADUs are made up of the Modbus Application
Protocol header concatenated with a PDU.
There are four fields in the header.
The first is a 2‑byte transaction identifier.
This is really important in Ethernet networks where multiple
requests can be outstanding simultaneously.
That is a client can send requests one and two,
but a server could respond to query two,
then query one.
The transaction identifier enables the client to match the
requests to the responses and pass data accurately.
The Protocol Identifier is normally 0, but it can be used
to expand the behavior of the protocol.
The length field indicates the number of remaining bytes in the frame,
including the server ID, the function code, and the data field.
Since TCP packets have built‑in error checking and ensure data coherency and
delivery, packet length is less important than it is in less inherently
reliable networks, such as serial networks. However,
there are some known vulnerabilities in ICS devices where
corrupted length fields can cause a device default.
The unit ID is typically unused for TCP/IP devices as Ethernet networks
use IP and MAC addressing to identify network devices.
However,
Modbus such a common protocol that many network gateways have developed
that convert the Modbus protocol into another protocol.
In these cases,
the unit ID is used to determine the address of the server
device the PDU is intended for. Finally,
for reliability and to complete the ADU, each message includes error
checking information with a cyclic redundancy checksum.
The Modbus standard defines function codes for accessing Modbus registers.
There are four different data blocks defined by Modbus, coils and digital
outputs, whilst discrete inputs and digital inputs, and holding registers, or
analog outputs, whilst input registers, or analog inputs. The addresses or
register numbers in each of the data blocks overlap,
so determining the value of a specific data element requires both
the address, or the register number, and the function code, or
register type. Here we see the function codes most commonly
recognized by Modbus devices.
This is only a subset of the codes available.
Several of the codes have special applications that often don't
apply, leading to mismatches between the functions enabled on the
client and what the server can handle.
There are also unspecified function codes, which allows device
manufacturers to implement functionality that wasn't envisaged by the
developers of the Modbus protocol. To put all this in context,
let's take a look at a typical Modbus request packet. First, we have the
transaction ID of hexadecimal AD, or 173, which allows the client to keep
track of the response received from the server.
As is typical in TCP/IP implementations,
the protocol ID is 0 and the length of the remaining
part of the packet is 6 bytes.
The first of those 6 bytes is the server ID,
which specifies the device that the message is intended for.
The second byte is the function code, which in this case is 5,
which is the instruction to write to a single coil.
This is a digital output, such as switching something on or off.
The final four bytes comprise the data field,
which is made up of the register address, so the coil to be written
to, and the value. So the function code combined with the data field
tells us that the coil at address 67, or hexadecimal 43, should be
activated or switched to on