Ever wondered how large-scale power plants monitor or control the myriad of systems that fill their environment? Have you thought about how some of the world’s greatest industrial hacks were enacted?
This post will look to illuminate how one tiny legacy protocol, namely "ModBus" could help to understand just how straight forward this could be. To gain a more in-depth understanding we will be pulling apart the following things:
A "control system" can be defined as a system that manages, commands, directs, or regulates the behavior of other systems.
An "Industrial Control System" is simply the generic term that describes a group of integrated control systems which are used to control instrumentation within an industrial environment. These types of systems may be made up of Relays, which could be used to control attached components or, the monitoring of various sources such as water pressure gauges for example.
In common parlance, an ICS can be compared to a symphony conductor. It’s system that directs and controls all the sub-systems resulting in a smooth-running operation.
"Operation Technology" is the term used to describe the hardware and software used to detect or cause a change to a component of a "Industrial Control System". A common way to control such components is using a "PLC (Programmable Logic Controller)", which is simply a Microprocessor-based controller that can be used to bridge the gap between the analog world (a physical relay that controls a light) and the digital world (a network interface that allows individual PLC's to be interconnected for management and control purposes).
Specific protocols have been developed to control these interconnected PLC's. One of which, named ModBus has become the de-facto open standard commonly used to connect diverse ICSs over an Ethernet structure.
Modbus has been around for many years. It was initially developed in 1968 and released into the market in 1979 by Modicon, now Schneider Electric, as a protocol designed to replace hard-wired relay systems.
Modbus is now an open standard and a widely used communications protocol that allows for the monitoring and controlling of individual PLCs within an ICS.
ModBus has become the de facto standard, truly open and the most widely used network protocol in the industrial manufacturing environment. It has been implemented by hundreds of vendors on thousands of different devices to transfer discrete/analog I/O and register data between control devices. It is a lingua franca of common denominator between different manufacturers.
The ModBus protocol functions as a method to share messages amongst a group of interconnected devices. This messaging mechanism is used by each device to share information amongst one another, typically over a common physical medium type. The common physical medium type in use may vary across the industry. The choice of common medium type is commonly dependent on the type of device in use, that is to say not all devices share a standard physical interconnection type and thus ModBus provides a way in which to bridge this gap. This bridging is why ModBus has a widespread appeal and hence its broad usage.
The ModBus protocol itself comes in many flavors. These varying flavors exist to facilitate the diversity in physical medium types in use across the industry.
In a generic sense the protocol uses a Client/Server architecture, where each device is assigned a unique identifier. Using this architecture, a client will typically communicate to one or more listening server devices using the unique identifier as reference. The client in this case will send ModBus requests and commands, which direct the server devices to execute a native command.
The following section will expand on the main two types of flavors that are commonly found to be in use across the industry.
The ModBus protocol comes in two main variants or flavors. These flavors specifically cater to the two main types of mediums or physical communications interfaces, namely Serial or Ethernet. We will describe both in this post, however Ethernet will be our primary focus, especially when describing "The Exploits" in a later section.
1. ModBusRTU (Remote Terminal Unit)
ModBus Daisy Chain
DB-9 Connector Type
2. ModBusTCP
ModBusTCP Typical Setup
At a 30,000 foot view the ModBus frame or MBAP (ModBus Application Protocol Header) looks something like this:
However, a closer look at a ModBus frame appears like this:
Now, if we were to populate the frame with data it may start resembling something like this: 000000000006FF0600020f0f
Given that most of us don't speak native HEX, I have broken things down even further in a more digestible format below:
0000 0000 0006 FF 06 00020f0f
<2-byte Transaction ID>|<2-byte Protocol ID>|<2-byte length>|<1-byte Unit ID>|<1-byte function code>|<Data for response or commands>
The static portion of the frame i.e., the first seven bytes remain mostly unchanged between transactions. Where it starts to become a little more dynamic is in the last section of the frame. The section that is being referred to, in this instance, starts from the 1-byte function code onwards. This section provides the server with information about how it should respond. This response may also require the PLC to execute a low-level function e.g., switching of a relay.
The following table illustrates the available function codes. Function codes are simply commands sent from a client to a server that instruct the server to do something useful.
Referring to our example, the function code in use is '06', which as we can see is the code for the 'Write Single Holding Register' function. If we break down this specific functional code, we will understand its requirements and/or format.
Function Code ‘06’
As seen, the function code '06' uses two a 2-byte fields for its request, the first of which is the address to be written to and the second is the value that is required to be written. The first value corresponding to '0002' is the address to be written to. The second value corresponding to '0f0f' is the value that is required to be written.
A register simply refers to an address location in memory. In our case this address location will be '40002'. The reason that this value is 40002 and not 0002 is that the output holding register (the register that will be monitor for change) starts off at offset memory location '40000'. So, in our case, we have instructed address location 40002 to be populated with a two-byte value of '0f0f'.
Write Holding Registers
When an output holding register is changed the on-board controller, after monitoring its new value will execute upon the value found in the register. This may correspond to either a ON or OFF for example.
Now that we have the theory behind us, let’s look at some of the main reasons that this type of protocol is susceptible to attack.
Some of the ModBus protocol weaknesses include:
An attacker taking advantage of these deficiencies can chain them together ultimately leading to control of the devices.
Practical Example
This particular practical example uses a ModBus enabled device. This device is used to control two physical relays, which in this instance is connected to a strobe light. This strobe light could be easily substituted for a door controller or alternatively a myriad of other potential target devices.
This example shows how an attacker can:
The main goal for this post was to showcase the under-hood workings of what makes an OT tick. ModBus and various other protocols are often at the heart of many OT environments and as such places many ICSs at risk in terms of compromise.
The underlying weaknesses as so described in this post, are often not considered in forethought due a number of reasons, some of which may include: