Skip to content
Sedat Özdemir
Writing

industrial-security

The Packet That Stops the PLC: Air-Gap Fairy Tales and Realities in the OT World

When you intercept a 'Function Code 05' request from an unauthorized IP on Wireshark, you realize within seconds that the physical valve or motor is no longer under your control. Welcome to the world of OT.

Sedat Özdemir
· 4 dk read

When you catch a Modbus TCP packet with 'Function Code 05' (Write Single Coil) on Wireshark, and it's coming from an unauthorized IP address, it only takes seconds to realize that the physical valve or motor on the floor is no longer under your control. In the world of OT (Operational Technology), you don't get an 'Error 404'; things either explode, stop, or spin much faster than they should.

Folks, today we’re stepping out of our 'IT security' comfort zone and entering industrial sites ruled by noisy machinery, the smell of oil, and Windows XP machines that haven't been updated in 20 years. In the simulations we've run at testCompany, we've seen that manipulating a PLC (Programmable Logic Controller) can have much more devastating consequences than finding an SQL Injection in a web app.

'Air-Gap' is Just a Consolation Prize

For years, we've been told the fairy tale that industrial systems are not connected to the internet and are therefore 'unhackable.' That 'Air-gap' we talk about is mostly an illusion these days. That USB stick a technician brings on-site 'because it has music on it,' the maintenance engineer's laptop used to connect to the PLC (the same one they use to stream series at home), or that 4G modem installed 'on the sly' to send sensor data to the cloud... they all poke holes in that famous air-gap.

The biggest problem with industrial systems is that they are 'Insecure by Design.' These protocols (Modbus, Profinet, S7comm, EtherNet/IP) weren't designed with the thought, 'What if someone sends a fake packet here?' When the Modbus protocol was developed in the 1970s, the priority wasn't security; it was making sure data reached the other side of those thin cables without errors. We are still using the same protocol today, just wearing a TCP layer as a suit.

How to 'Talk' to a PLC?

From a Red Teamer's perspective, once you pivot from the IT network to the OT network, things move very 'linearly.' There is no encryption, usually no authorization mechanism, and the handshake process is child's play.

For instance, let’s look at a standard Modbus packet structure. In a defanged scenario, a critical packet sent to shut down a coil (relay) looks something like this:

# Modbus TCP - Write Single Coil (Defanged Example)
Transaction ID: 0x0001
Protocol ID: 0x0000
Length: 0x0006
Unit ID: 0x01
Function Code: 05 (Write Single Coil)
Reference Number: 0x0064 (Valve ID)
Data: 0x0000 (Close command - 0xFF00 opens)

If you have libraries like pymodbus at your disposal, you don't even need to be a genius to perform this. Here is that simple but dangerous Python logic we use in test environments (like the testCompany labs):

# FOR EDUCATIONAL PURPOSES: Attempting to write data to a PLC register
from pymodbus.client import ModbusTcpClient

def check_industrial_valve(target_ip):
    # Defanged target: 127.0.0.1 or internal lab IP
    client = ModbusTcpClient(target_ip, port=502)
    if client.connect():
        print(f"[+] Connection successful: {target_ip}")
        # Attempting to write to coil number 100 (relay)
        # client.write_coil(100, False)
        client.close()

Related posts