← Lablog
ICS 18 April 2025 ✎ Gjoko Krstic

Modbus TCP Attack Primitives: Enumeration to Coil Write

Documenting the full attack chain against unauthenticated Modbus/TCP installations: unit enumeration, coil read, register dump, and write primitives for HMI setpoint manipulation.

Protocol Overview

Modbus/TCP operates on port 502 with no authentication mechanism defined in the protocol specification. Any client that can reach the port can read and write all registers and coils. The protocol was designed for serial RS-485 networks in the 1970s and later wrapped in TCP with no security additions.

Attack Chain

The full attack sequence against a typical Modbus/TCP PLC or RTU:

  1. Discovery — Scan for port 502, send Read Device Identification (function code 0x2B) to fingerprint vendor and model
  2. Unit Enumeration — Iterate unit IDs 1-247, read holding registers from each to map the device tree
  3. Coil Read — Read discrete outputs (function code 0x01) to determine current relay states
  4. Register Dump — Read holding registers (function code 0x03) to extract setpoints, thresholds, and configuration
  5. Coil Write — Write single coil (function code 0x05) or multiple coils (0x0F) to toggle physical outputs

Mitigation

Network segmentation remains the primary defense. Place Modbus devices on isolated VLANs with strict firewall rules. Deploy Modbus-aware IDS rules to detect unauthorized write operations. Where possible, use Modbus/TCP Security (TLS wrapping defined in the 2018 specification update), though vendor support remains limited.