26 Jun 2026 · 4 min read
I put a man on the wire of four OT protocols. Here is what leaked.
security · ot · modbus · mqtt · opc-ua · architecture
I spent a week putting a man on the wire of the protocols that run the plant floor. Modbus, then EtherNet/IP and S7comm, then MQTT and Sparkplug, then OPC UA. Each one got a real lab, a real capture, and the same two questions: what can I read, and what can I change, from a host that was never given permission to do either.
The answers were consistent enough to state up front. On three of the four, a stranger on the segment reads every value and writes the ones that move equipment, and no protocol asks him who he is. The fourth can say no, and on most sites it is configured not to.
This post is the map. Each part is a link to the full write-up with the capture in it.
Part 1 — a pump moved itself
A pump was running at 42 hertz, then at 15, and the HMI logged no operator. The write that moved it was twelve bytes of Modbus TCP: a function code that means write, the address of the speed register, and a value. No field for a password, because Modbus has nowhere to put one. The device could not tell my write from the control system's.
The lesson was not that Modbus is broken. It is that Modbus answers a question from 1979, when the security boundary was the locked panel, and a flat converged network deleted that boundary without replacing it. Read the capture.
Part 2 — the name brand did not buy a lock
The comfortable reply to Part 1 is that Modbus is old. So I stood up a Rockwell controller speaking EtherNet/IP and a Siemens controller speaking S7comm, both current, both what a plant actually runs, and put a man on the wire of each. The Rockwell accepted a CIP tag write in the clear. The Siemens accepted an S7 write to a data block in the clear. Neither Setup Communication nor RegisterSession carried a credential.
Three protocols from three eras and three vendors, one identical trust model: the wire believes whoever is on it. That is not a bug list. It is a shared assumption the network used to enforce and now does not. Read the captures.
Part 3 — the broker trusted everyone
Then the modern stack, the one sold as the grown-up successor to the flat plant network. I put a man on the wire of an MQTT broker running a Unified Namespace. Every connection carried no username and no password, and the broker accepted every one. From an anonymous host I published a single valve-close command, and the broker fanned it out to every subscriber, including the controller that acts on commands.
The new stack repeated the old mistake, and moved it to a hub where the blast radius is larger. The difference, and it is the good news, is that this time the protocol can defend itself. Authentication, an ACL, and TLS would have turned my anonymous command into a rejected connection. Read the capture.
Part 4 — the door that could say no
The capstone is the exception. I built an OPC UA server with two doors, NoSecurity and Sign & Encrypt, and read the same value through both. Through the open door the value sat on the wire as a plain number. Through the secure door the same read returned the same answer and the wire saw nothing. Across the whole capture, both reads succeeding, the value crossed in the clear exactly once.
OPC UA is the protocol the others should have been, designed in a networked world with a lock in the specification. It fails in the field for the same reason MQTT does: the secure mode is an afternoon of work and a certificate, and None makes the integration work in five minutes. Read the capture.
The one rule underneath all of it
Put the four together and a single rule falls out for where to stand.
The protocols that cannot defend themselves, Modbus and EtherNet/IP and S7comm, are defended at the network. Segment the cell so the controllers are reachable only through a path you drew on purpose. Permit the writes that must happen and drop the rest. Alarm on the write that should never come. None of that touches the protocol, because the protocol cannot help you.
The protocols that can defend themselves, MQTT and OPC UA, are defended at the protocol. Turn authentication on. Give every client an ACL. Run TLS. Use Sign & Encrypt and real certificates. The lock is in the box already, waiting to be switched on.
And you do both, always, because there is a legacy drive in every cell that will never speak anything but plaintext, and a segment boundary is the only thing that protects it. The older the protocol, the more the burden falls on the drawing. The newer it is, the more the protocol will carry, if you let it.
None of this is exotic. The man on the wire in every one of these labs was not a nation-state with a zero-day. He was ordinary access landing one hop too close: a contractor's laptop, a reused HMI, a jump host with a shared password. The fix he is afraid of is not a better protocol. It is a boundary in the drawing and a lock switched on, and most plants have skipped the free half of that for years.
The whole series, with every capture and the harness that produced it, starts at the pump that moved itself.
Keep reading
Newsletter
New essays, by email.
SCADA, cloud, AI, and the plant floor — a short email when something new is published. No noise, unsubscribe anytime.


