Home
VAPT Web Application PentestAPI PentestMobile App PentestInfrastructure PentestAI & LLM PentestOT / ICS PentestIoT PentestPenetration TestingAll VAPT services
Red Team Red Team EngagementAdversary SimulationAssumed BreachPurple TeamingSocial Engineering
Sectors Banking & Financial ServicesGovernment & Public SectorHealthcareOil, Gas & EnergyAviation & LogisticsRetail & E-commerceManufacturing & IndustryTelecommunicationsTechnology & SaaS
CompanyResourcesBlogFree Consultation

Modbus/TCP unauthenticated command injection: writing to a process that never checks who is asking

Modbus/TCP carries no authentication, so any host on the control network can write to a PLC. This article shows how the attack runs and what stops it.

Joel Aviad OssiJoel Aviad OssiRed Team Lead, RedTeam Security
7 min read
An isometric control network diagram: a workstation and a network switch connected to a rack-mounted PLC by blue flow lines, with a separate red line bypassing the workstation and writing directly to the PLC.

Key takeaways

  • Modbus/TCP has no authentication field: any host that can reach port 502 can read and write any register the device supports.
  • Function codes 05, 06, 15 and 16 write process values directly; the PLC applies them on the next scan cycle and cannot distinguish an attacker's write from a legitimate one.
  • Source IP allowlisting on port 502 and function-code-aware DPI blocking write FCs from non-engineering hosts are the practical compensating controls for existing plant.
  • Modbus/TCP Security (RFC 8205) adds TLS with client certificates but deployment remains low because most installed PLCs predate the standard.
  • An OT monitoring platform needs function-code-level decoding, not just port-502 visibility, to detect write commands from unexpected sources.

The protocol that carries no authentication field

Modbus was designed in 1979 for serial links between a master device and a set of field instruments on a physically isolated bus. Wire access to the bus was the assumed access control. Modbus/TCP arrived two decades later and placed that same frame on Ethernet with no authentication, session tokens, or message integrity checks added. CWE-306, missing authentication for a critical function, is the class of weakness this fits: a request that alters process state carries no verification of who sent it.

Port 502 is the registered Modbus/TCP port. Any host that can reach it can issue any function code the device supports. Function codes 01 through 04 read discrete inputs, coil states, input registers and holding registers. Function codes 05, 06, 15 and 16 write them. No permission model separates read from write. MITRE ATT&CK for ICS T0855 lists unauthorised command messages as a core impact technique, and T0836 covers the direct parameter modification a write to a holding register achieves.

The three kill chain phases for a Modbus unauthenticated write, from control-network access to process impact.

Getting on to the control network

A Modbus write requires a foothold on the control network. The Purdue reference model places process control at Level 2 and supervisory systems at Level 3, with a demilitarised zone at Level 3.5 separating plant from corporate IT. Purdue-level VLAN enforcement with strict ACLs at each zone boundary is the architecture that keeps an IT-side compromise from reaching port 502. In practice those boundaries erode: engineering workstations run both plant software and corporate email, supplier VPN tunnels terminate inside the plant network rather than in a DMZ, and remote-access jump servers sometimes span both zones.

A unidirectional gateway, sometimes called a data diode, enforces a physical one-way link from the control network outward to the historian or corporate side. It is the architectural control that makes Modbus unreachable from the IT zone regardless of software configuration: no TCP session can be initiated inward. The sibling article Engineering workstation to PLC: how control logic tampering happens covers the path from a compromised engineering workstation to a PLC; this attack starts further back, at any host on the reachable control network. An OT/ICS pentest tests whether those zone boundaries hold before an attacker discovers they do not.

Mapping the process with read requests

With a host that can reach port 502, the first step is to map the process layout. A register sweep walks the coil and holding register address space, issuing read requests from address 0 and stepping forward until the device stops responding or returns exception codes. Coils (function code 01) report discrete on/off states: a pump running, a valve open, a relay energised. Holding registers (function code 03) carry analogue setpoints and configuration values: a temperature limit, a pressure threshold, a motor speed reference. Input registers (function code 04) carry live sensor readings that reflect current process conditions.

A read sweep gives the tester a map of the process: which address corresponds to which physical element, what the current values are, and what a normal operating range looks like. The write step uses that map. NIST SP 800-82 Revision 3 describes this reconnaissance phase as a necessary precursor to a command injection attack and recommends passive traffic analysis as the detection approach, rather than active blocking that can disrupt legitimate PLC polls.

Holding register sweep with pymodbus (authorised test
from pymodbus.client import ModbusTcpClient

client = ModbusTcpClient('192.0.2.10', port=502)
client.connect()

# Read holding registers 0-99 to map the process layout
result = client.read_holding_registers(address=0, count=100, slave=1)
if not result.isError():
    for i, val in enumerate(result.registers):
        print(f'HR[{i:03d}] = {val}')
else:
    print(f'Error: {result}')

client.close()

Issuing a write the PLC accepts without question

A Modbus write takes the same wire format as a read. Function code 06 writes a single holding register; function code 16 writes a block. The transaction identifier in the Modbus/TCP header is a sequence number for matching responses to requests: it is not a credential and the device does not verify it. The PLC receives the write and applies it on the next scan cycle, typically within milliseconds. From the controller's perspective, the command is indistinguishable from one sent by the engineering workstation. No session, signature, or origin field exists in the frame.

In a controlled test against a lab replica, or during a maintenance window agreed in writing under the scope of an OT/ICS pentest, a write to holding register 42 pushes the temperature setpoint from 320 (32.0 degrees C) to 850 (85.0 degrees C). If the new value exceeds the historian's configured alarm threshold, an operator console alerts. If it falls within a plausible but unintended band, the manipulation runs undetected until the physical effect shows. The code below is the complete transaction: the PLC asks nothing before applying it.

Single-register write with pymodbus.
from pymodbus.client import ModbusTcpClient

# Authorized Testing Only: do not run against live plant
# Target: holding register 42, current value 320 (32.0 C setpoint)
client = ModbusTcpClient('192.0.2.10', port=502)
client.connect()

write_result = client.write_register(address=42, value=850, slave=1)
if not write_result.isError():
    print('Write accepted: HR[42] now 850 (85.0 C)')
else:
    print(f'Write error: {write_result}')

client.close()
Modbus/TCP write attack sequence between an attacker and a PLC on port 502. The attacker reads holding registers to map the process. The PLC returns values including a temperature setpoint. The attacker writes a new value to that register.
The complete Modbus/TCP write transaction: no challenge, no credential, write accepted and applied.

What your monitoring should catch

An OT monitoring platform that decodes Modbus at the function-code level should alert on write function codes from addresses outside the approved engineering workstation pool. Function codes 05, 06, 15 and 16 from an unexpected source IP are the direct signature of this attack. A register read sweep from a host that has never previously issued Modbus requests is the reconnaissance precursor. Both indicators are available from passive traffic mirroring without inline blocking. A rule that fires on any port-502 traffic catches the probe but also catches every legitimate PLC poll and historian read, generating alert volume that trains operators to ignore it. The sibling article What your OT monitoring should catch during an ICS pentest lists the full detection set for an ICS engagement.

Effective detection depends on a baseline of approved Modbus source addresses. Most plants have never documented which host addresses are legitimate Modbus sources, so a write-from-unexpected-source rule has nothing to compare against. Building that baseline is a prerequisite, and an infrastructure pentest of the control-network architecture often surfaces that gap for the first time.

Modbus function codes relevant to detection: what each code does and what an unexpected source signals
Function codeOperationDetection relevance
FC 01Read coilsReconnaissance: sweep from unknown source
FC 03Read holding registersReconnaissance: maps setpoints and configuration
FC 04Read input registersReconnaissance: maps live sensor values
FC 05Write single coilWrite attempt: unexpected source is attack indicator
FC 06Write single registerWrite attempt: most common setpoint manipulation FC
FC 15Write multiple coilsWrite attempt: bulk discrete output change
FC 16Write multiple registersWrite attempt: bulk setpoint change, highest impact

Controls that break the chain

Source IP allowlisting on port 502 is the most direct compensating control. A network ACL that passes Modbus only from engineering workstation addresses prevents any other host from issuing read or write commands, regardless of its position on the control network. The engineering workstations then become the residual attack surface, which is why an OT/ICS pentest should scope them in explicitly. The article How to buy an OT/ICS pentest covers how to document that scope in the proposal and what a tester should demonstrate against it.

Function-code-aware deep packet inspection, available in ICS-aware firewall products and purpose-built OT security appliances, adds a finer-grained layer. A rule that blocks write function codes 05, 06, 15 and 16 from non-engineering-workstation addresses while passing read function codes preserves historian polling and monitoring traffic. That is narrower and operationally safer than a blanket block on port 502, which stops all Modbus communication including legitimate plant operations.

Modbus/TCP Security, defined in RFC 8205 and adopted in IEC 60870-5-7, adds a TLS transport with client certificate authentication to the standard Modbus/TCP frame. It closes the authentication gap at the protocol level rather than working around it with network controls. Deployment remains low because most installed PLCs and remote terminal units predate the standard by decades, and retrofitting TLS typically requires a firmware update, a new network interface module, or a device replacement. For new equipment procurement, specifying RFC 8205 support is a reasonable contractual requirement. For existing plant, source IP allowlisting and function-code DPI are the practical layered controls while an upgrade programme is planned.

Modbus security in UAE industrial facilities

The UAE operates substantial industrial infrastructure across Abu Dhabi and Dubai: hydrocarbon processing, utilities, water treatment and discrete manufacturing. Much of this plant runs Modbus/TCP on control networks that were segmented for operational reasons before cybersecurity was part of the design brief. The NESA-published UAE Information Assurance Standards apply federally to critical information infrastructure, which includes operational technology in designated critical sectors. An operator subject to the IAS is expected to manage access to control systems, and an OT network that exposes Modbus/TCP without source restriction does not satisfy that access-control requirement.

In Abu Dhabi, the ADHICS framework applies to healthcare facilities running building management and clinical systems, some of which use legacy fieldbuses including Modbus. In Dubai, the DESC framework applies to Dubai government entities and their suppliers, including those providing industrial automation and facilities management services. Both frameworks require documented access control for networked systems. An OT network that places Modbus/TCP on an unrestricted VLAN, reachable from any segment that can route to the control network, would not satisfy that requirement under either regime.

A practical route for a UAE operator is an OT/ICS pentest that names Modbus access control as a scope item, tests whether write function codes are reachable from outside the engineering workstation pool, and documents the result as audit evidence. The remediation output, source IP allowlisting and function-code DPI, is also the compliance artefact: a network configuration that blocks unauthenticated writes from non-approved sources is a technical control a DESC or IAS auditor can verify against a firewall ruleset.

Frequently asked questions

What is Modbus/TCP and why does it have no authentication?

Modbus was designed in 1979 as a serial protocol for industrial field instruments on a physically isolated bus. Physical wire access was the assumed access control. Modbus/TCP placed that same protocol frame on Ethernet without adding authentication or integrity checks. The weakness is architectural, not a later oversight.

Which Modbus function codes are used to write to a PLC?

Function code 05 writes a single coil, FC 06 writes a single holding register, FC 15 writes multiple coils, and FC 16 writes multiple holding registers. These four are the write surface for parameter manipulation. Function codes 01, 03 and 04 are used in the preceding reconnaissance phase to map the process state.

How does a Modbus command injection differ from a software vulnerability?

A typical software vulnerability exploits a flaw introduced during development. Modbus command injection exploits the deliberate design of the protocol: there is no authentication field to bypass because none was ever defined. A patch cannot fix it. Mitigation requires network controls around the device or a protocol upgrade to RFC 8205 Modbus/TCP Security.

What is CWE-306 and how does it apply to Modbus?

CWE-306 describes a system that permits a critical function to execute without verifying the caller's identity. Modbus/TCP is a direct example: a write command that alters a physical process parameter carries no credential. None is required. The device cannot distinguish a legitimate engineering workstation command from an attacker's write.

What is Modbus/TCP Security and why is it not widely deployed?

Modbus/TCP Security, defined in RFC 8205 and adopted in IEC 60870-5-7, adds a TLS layer with client certificate authentication over the standard transport. Deployment is limited because most installed PLCs and RTUs predate the standard and retrofitting TLS requires a firmware update or hardware replacement rather than a configuration change. For new procurement it is a viable requirement.

How does MITRE ATT&CK for ICS classify Modbus write attacks?

Technique T0855 covers unauthorised command messages sent to field devices without operator intent. Technique T0836 covers the direct modification of process parameters. Both apply: T0855 captures the unauthorised write command and T0836 captures the manipulation of the setpoint or coil state that the write delivers.

Can an ICS firewall block Modbus writes without disrupting plant operations?

Yes, if it supports function-code-aware deep packet inspection. A rule blocking FC 05, 06, 15 and 16 from non-engineering-workstation addresses while passing read function codes and all traffic from approved sources preserves historian polling and monitoring. A blanket block on port 502 would stop all Modbus communication, including legitimate plant operations.

What should OT monitoring alert on to detect this attack?

Write function codes 05, 06, 15 and 16 from source addresses outside the approved engineering workstation list are the primary indicator. A register read sweep from a host with no prior Modbus history is the reconnaissance precursor. Both are available through passive traffic mirroring. Effective rules require a documented baseline of approved Modbus source addresses.

How is a Modbus write test conducted safely during an OT pentest?

Safe testing requires either a lab replica of the target PLC and process or a maintenance window agreed in writing with the plant operator and engineering team before the test begins. The target registers, address ranges and value limits must all be agreed in the scope document. No write should be issued against a live process without explicit operator approval and a monitored rollback plan.

The engagements this applies to

Joel Aviad Ossi, Red Team Lead at RedTeam Security
Joel Aviad OssiRed Team Lead, RedTeam Security

Joel Aviad Ossi is Red Team Lead at RedTeam Security, the Dubai-licensed trading brand of WebSec FZCO. He scopes and runs objective-based engagements across the UAE.

Let's talk about your security

Tell us the objective you want tested. We will come back with a scope, a timeline and a quote, under NDA from the first conversation.

Email [email protected]
IFZA Business Park, Building A2
Nadd Hessa, Dubai Silicon Oasis
Dubai, United Arab Emirates