Live observations — 30-day window through 2026-05-30 May 2026

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.

ICS/OT Modbus S7comm IEC-104 DNP3 OPC-UA EtherNet/IP BACnet

The seven honeypots, side by side (last 7 days, sensor1)

ProtocolDefault portHoneypot profileEvents
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

S7comm Siemens S7-1200 emulation — the most-poked PLC of the fleet
499 application-layer hits in 7 days. The dominant pattern is S7CommPlus connection requests followed immediately by connection-teardown — classic banner-grab shape (Shodan’s S7 module does exactly this). A small fraction follow up with Read SZL (System Status List 0x0011 / 0x001C) probes that try to pull the order number, firmware version, and rack/slot ID from the CPU. Those are the ones interested in identifying a real target, not just cataloguing it.

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.
Modbus Modbus/TCP — coil reads from everyone, function-code-43 from research kits
227 hits. Modbus/TCP is the most polyglot of our ICS surfaces — we saw Modbus probes on the real port (502) and also random TCP ports (102, 1521, 1883, 548, 9042, 20443) where TCP-fingerprinting tools mis-classified non-Modbus services as Modbus. The 502 traffic itself is mostly Function Code 1 (Read Coils) at unit-id 1, often with the Modbus-spec example values like address 0, quantity 1. That shape is generic enumeration tooling, not a real attack.

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.
IEC-104 IEC 60870-5-104 — STARTDT / TESTFR keep-alive shape
160 hits. Almost everything we see on 2404 is the protocol’s STARTDT activation (start data transfer) frame followed by TESTFR keep-alive — you can’t fingerprint an IEC-104 RTU without doing the activation handshake first, which is why even passive scanners have to perform it. Once the session is open the next frame is usually a General Interrogation (C_IC_NA_1, type 100) that asks the RTU to dump its state — a perfect attribution probe.

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.
ENIP EtherNet/IP — List Identity is the entire conversation
128 hits. List Identity (command 0x0063) UDP/44818 broadcast is the canonical “what are you” request, and it’s ~95% of the traffic. The few session-opening attempts (Register Session, command 0x0065) followed by Forward Open we saw are characteristic of CIP object-browsing — researchers or pentest tooling stepping through the device’s assembly objects.
OPC-UA OPC UA — a steady trickle from researcher tooling
100 hits over 7 days. OPC UA gets a smaller crowd than the legacy protocols, which fits its position in the stack: it’s the modern, certificate-secured replacement, so opportunistic scanning tools largely ignore it. What we do see is the OPN(SecureChannel) + GetEndpoints shape that opcua-modeler, UaExpert, and Nuclei templates emit when they sweep for OPC UA endpoints.
BACnet BACnet/IP — Who-Is broadcasts, occasional ReadProperty
6 hits. BACnet on UDP/47808 is mostly Who-Is broadcasts that scanners use to enumerate building-automation devices on a network. Our honeypot answers as “Johnson Controls FX-PCG2611” at “Building A Floor 3” — coherent enough that the scanner records the device but rare enough that we don’t generally see follow-up ReadProperty calls.
DNP3 DNP3 — the quietest of the seven, by design
11 hits in a week. DNP3 on TCP/20000 is heavily concentrated in North American electric and water utilities and rarely shows up in indiscriminate internet sweeps. The few hits we see are DNP3 Link-Layer Function Code 4 (Unconfirmed User Data) probes — the cheapest way to confirm a DNP3 outstation is present without committing to a full handshake.

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:

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:

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.