ICS/OT Under Siege — What 7 Industrial Protocols Tell You About Who’s Knocking
Across the last 30 days our fleet logged ~50 million events (sensor1 37.2 M, sensor2 10.7 M, sensor3 2.5 M). Most of that volume is the usual long-tail commodity scanning — SMTP, RDP, Telnet, SMB. What’s interesting is the small slice that specifically looks for industrial control protocols. Our seven ICS/OT honeypots saw clean targeted traffic: Siemens S7comm and Modbus dominate, IEC 60870-5-104 and EtherNet/IP show consistent pulse, OPC UA gets a steady trickle from researcher tools, and BACnet/DNP3 are quietly enumerated but rarely deeply exercised.
The seven honeypots, side by side (last 7 days, sensor1)
| Protocol | Default port | Honeypot profile | Events |
|---|---|---|---|
| S7comm Siemens S7 | TCP/102 |
S7-1200 CPU 1214C, FW V4.5.2, “WaterTreatment-PLC03” | 499 |
| Modbus Modbus/TCP | TCP/502 |
Schneider Electric PM5560, FW 3.4.2, unit 1 | 227 |
| IEC-104 IEC 60870-5-104 | TCP/2404 |
Power utility RTU emulation | 160 |
| ENIP EtherNet/IP (CIP) | TCP/44818 |
Allen-Bradley device class | 128 |
| OPC-UA OPC UA | TCP/4840 |
Discovery + GetEndpoints surface | 100 |
| DNP3 DNP3 | TCP/20000 |
SCADA RTU profile | 11 |
| BACnet BACnet/IP | UDP/47808 (TCP/25 also probed) |
Johnson Controls FX-PCG2611, Building A Floor 3 | 6 |
Counts above are protocol-classified application-layer hits — i.e. the honeypot’s parser successfully decoded the wire format, which is the threshold separating “someone tried” from “someone connected.” The raw TCP/SYN volume on the same ports is ~10× higher but mostly Shodan/Censys-class banner-grabbing.
Per-protocol — what we actually saw
The honeypot answers with the Siemens S7-1200 CPU 1214C order number (6ES7 214-1AG40-0XB0) and firmware V4.5.2 — a plausible-looking but ageing PLC that an attacker would expect to find on a real industrial network. We didn’t see any credential-bypass attempts (S7Comm doesn’t have native auth) or write attempts — just enumeration.
Function Code 43 (Read Device Identification) requests with object-id 0x01-0x03 (vendor / product / version) are what attribution-focused scanners use. Our honeypot returns “Schneider Electric PM5560” with firmware 3.4.2 — a current, in-warranty industrial power-meter that would be worth scoping further on a real network.
We didn’t see any Command with Select Before Operate attempts (C_SC_TA_1 / C_SE_TA_1) which would indicate an attacker trying to actually flip a remote breaker. The 160 hits are enumeration, not action.
opcua-modeler, UaExpert, and Nuclei
templates emit when they sweep for OPC UA endpoints.
What this tells you about your real ICS posture
Three takeaways that apply equally well to a real plant, substation, or building-management network as they do to a honeypot:
- Banner-grab volume is not the metric that matters. The big numbers (Shodan, Censys, ZoomEye-class scanners) generate most of what shows up on the wire, but they don’t represent adversary intent. The metric is protocol-classified hits — events where the wire-format parser actually engaged. That’s the number we report above.
- Function-code targeting is the early-warning bar. S7 Read SZL, Modbus FC 43, IEC-104 General Interrogation — these are reconnaissance with intent, not catalogue-style enumeration. They are also fundamentally indistinguishable from legitimate maintenance traffic, which is why authentication plus allow-listed source ACLs are the only defence that holds.
- The protocols that don’t answer don’t get probed twice. The 10× SYN-vs-classified ratio we noted at the top is symmetric: tooling that doesn’t get an ICS-shaped response back on the first packet moves on. A real industrial endpoint that simply doesn’t respond to unauthenticated probes ends up with the same wire-level signature as one that’s not there at all. That is, by itself, a defence.
How we classify
Each honeypot is a focused stdlib-only Python service that answers only the protocol’s well-formed wire frames. The classifier then walks the parsed PDU and assigns one of the following attack-type tags:
- ics_enumeration — banner-grab, discovery, device-identify shape
- ics_recon_function_code — specific Read/Identify FCs with target-fingerprint intent
- ics_write_attempt — FC 5/6/15/16 Modbus, S7Comm write, IEC-104 control-direction (none observed in the 30-day window)
- ics_command_with_intent — select-before-operate, breaker-flip, PLC stop/start (none observed)
The honeypots are alert-only and never engage write paths, but the classifier is the same one used in pentests when we run these protocols through the AFA fuzzer — so if a real ICS write does land, the existing rules promote it.