ICS / OT INCIDENT · WATER SECTOR

The Warning They Declined

Two small Colorado water systems were breached in August. We had reached out to those operators, flagged the exact exposure, and been passed over. Weeks later, foreign hackers were inside the controls.

Matt Lucas  |  September 18, 2026  |  5 min
A raised palm waving off an offered water-system risk assessment
TL;DR
  • What: Foreign actors breached two small Colorado water systems in August 2026, reaching the programmable logic controllers directly and altering equipment settings, alarms and pump cycles.
  • Impact: Colorado says drinking water was not affected, but the intruders held operational control long enough to disable alarms and change pumping. The distance to a real safety event was one operator decision, and that operator did not work for the utility.
  • Fix: Get the control systems off the open internet, put monitoring on the OT layer, and alarm on setpoint and alarm-state changes. Copy-paste checks below.
  • Who: Any small water, wastewater or utility operator that keeps its controls reachable so a remote handful of staff can run the plant.

A story ran this week about two water utilities in Colorado that foreign hackers walked into last month. The reporting is accurate as far as it goes. What it does not say is that we had already sat across the table from those operators, shown them how someone would get in, and offered to close the gap. They said no. Weeks later, someone else said yes for them.

What happened

In August 2026, two small Colorado water systems serving roughly 400 people between them were breached. The intruders did not touch the water. They touched the controls. They reached the programmable logic controllers directly, the boxes that run the pumps and valves, then turned off alarms, cut remote access, changed pumping cycles, and altered equipment settings. The utilities regained control and alerted the state. Colorado says drinking water quality and treatment were not affected.

Disabling alarms is not vandalism, it is reconnaissance

Turning off alarms and changing pump cycles is someone learning the plant. The state is right that nobody got sick this time. That is the good news and the whole of it. The distance between what happened and a real safety event was one decision at the keyboard, and the person at the keyboard did not work for the utility.

The part that did not make the report

Roughly two months ago, before any of this, we reached out to water operators in Colorado and walked them through this precise failure mode: control systems reachable from outside, remote access with nothing watching it, and no alarm when the settings change underneath you. The two utilities compromised in August are among the operators we had contacted. We named the exposure. We offered to fix it. We were passed over on cost.

We are not naming the utilities, and we are not going to. They are small, they are under-resourced, and they made the same call that hundreds of systems like them make every week. The point is not who they are. The point is that the exposure was findable, because we found it, and it was preventable, because we offered to prevent it.

Why this was predictable

None of it required a nation-state. It required a scan. A small utility runs its plant with a skeleton crew and keeps the controls online so a couple of operators can reach them from home. That is reasonable. What makes it dangerous is the rest of the pattern that tends to travel with it: the controllers are reachable from further away than anyone intends, the remote path has no monitoring on it, and nothing raises a hand when a pump schedule or an alarm threshold is quietly rewritten.

An attacker does not need inside knowledge to find that. A scan finds it, which means the defender can find it first, and the fix is rarely exotic. It is knowing what is exposed, watching the control layer the way IT has watched the office network for twenty years, and getting told the moment something changes.

This is a pattern, not a bad week

Colorado is not an outlier. The water sector is being mapped, system by system.

100+
US water attacks in 2026
12
States hit this year
30+
Systems affected in Minnesota
900+
EPA-counted vulnerabilities since FY2025

These are not sophisticated campaigns against hardened targets. They are a wide, patient sweep of the softest infrastructure a country has, and the water sector is soft because it was never funded to be anything else.

Our own exposure index, Colorado, today

We keep a passive index of internet-reachable industrial control systems, the same view an adversary builds before choosing a target. As of today it shows close to 400 exposed control systems in Colorado, 40 of them running software with vulnerabilities under active exploitation, including on DNP3 and Modbus, the protocols that run water and power. The two systems in the news are not the last two in Colorado. They are the two that already happened. The rest are neighbors of the utilities that were hit, exposed the same way, right now. We are not publishing which ones, for the obvious reason.

What actually stops it

Fix It Yourself

Everything above is what happened. This is what to run. The check commands change nothing.

Check whether you are exposed

From a host OUTSIDE your network, probe your own public ranges for listening control-protocol ports (Modbus, DNP3, EtherNet/IP, BACnet, S7, Niagara Fox). Replace the range with your own allocation.

nmap -Pn -sS -p 502,20000,44818,47808,102,1911 203.0.113.0/24

On the perimeter firewall, list any inbound rule that reaches those ports, and any remote-access path into the OT VLAN.

grep -E "(:502|:20000|:44818|:47808|:102|:1911)\b" /etc/firewall/rules.* ; echo "--- review any ACCEPT/DNAT to the OT subnet above ---"

Confirm change logging is actually on at the controller or HMI: look for setpoint writes and alarm enable or disable events in the last 30 days.

grep -iE "setpoint|alarm.*(disable|enable)|program.*(download|write)" /var/log/scada/*.log | tail -50

Close it

Take the controllers off the open internet. Remote access to OT goes through a VPN with multi-factor authentication, never a port forwarded straight to a PLC or HMI. No monitoring in place yet: at minimum restrict the control ports to a named jump host and log every session.

Print (do not apply) a firewall rule that drops inbound to the control ports from anything outside your allow list, review it, then apply it on the firewall.

echo 'iptables -A INPUT -p tcp -m multiport --dports 502,20000,44818,47808,102,1911 ! -s 10.20.0.0/24 -j DROP'

Turn alarm and setpoint change auditing on and ship it off the device, so an attacker cannot both change a setting and erase the record of it.

Prompts for the agent you already run

You run a small water or utility plant and want to know what of your OT is reachable before touching anything.

I run a water utility with programmable logic controllers and HMIs. Help me find what of my OT is reachable from outside. Step 1: read my network inventory, firewall config, and any VPN or remote-access config you can find, and show me the files you read. Step 2: list every device or rule that exposes a control-protocol port (502 Modbus, 20000 DNP3, 44818 EtherNet/IP, 47808 BACnet, 102 S7, 1911 Niagara Fox) to the internet or to a flat network, and explain how you decided each one. Step 3: for each exposure, give me the read-only command to confirm it from outside. Do not change any firewall rule, device config, or account. Stop and ask me before anything that writes to a device.

You suspect a controller was touched and need to scope it from logs the device does not control.

Assume one of my PLCs may be compromised. Using only my firewall, netflow and DNS resolver logs, not the device's own logs, find every inbound and outbound connection involving the controller IP I give you over the last 30 days. Group by peer IP, port and first-seen time, and flag anything on a control-protocol port from an external source, any new destination the device has never contacted, and any session outside my stated maintenance windows. List the exact log files and fields you used and paste sample lines so I can verify. Do not modify, rotate or delete any log.

What to alert on

The primary observable is a control-protocol connection crossing the boundary: in firewall or netflow records, alert on any inbound flow from an external source to ports 502, 20000, 44818, 47808, 102 or 1911 on an OT-network host, and on any outbound flow from those hosts to a destination outside your defined update and peer list. Pair it with a device-level signal that an attacker cannot quietly suppress: forward controller and HMI audit logs off the box and alert on setpoint writes, program downloads, and alarm enable or disable events that fall outside a change window. On the remote-access path, alert on any OT VPN authentication that succeeds outside maintenance hours or from an unfamiliar source. Treat a device's own clean log as unproven when the network record disagrees, because operational control includes control of the logs.

Get the assessment we offered them

If you run water, wastewater, or any plant a small team keeps online from a distance, the OT exposure assessment is fixed in scope and modest against the cost of an incident. We will show you exactly what we would have shown them.

Request an OT assessment