Sometimes, yes. A plant engineer who asks whether a port scan can crash a programmable logic controller is not being difficult, they are asking about a documented failure mode. CISA's advisory ICSA-19-106-03 names five vendors, ABB, Phoenix Contact, Schneider Electric, Siemens and WAGO, whose controllers can be pushed into a denial of service condition by nothing more exotic than a heavier than usual flow of ordinary network packets landing on the same CPU that runs the control logic. That is not a hypothetical. It is a published advisory covering named CPU families.
The honest answer has three parts: which device, which kind of scan, and how the scan is run. A five year old Ethernet card riding on a thin embedded stack behaves nothing like a modern managed switch. A SYN sweep that only checks whether a port answers behaves nothing like a vulnerability scanner throwing crafted payloads at it. And a scan run at HMI-equivalent polling rates with an engineer standing at the panel behaves nothing like the same tool left on its default settings overnight. This guide works through all three, names the real incidents behind the caution, and sets out what "safe" actually means in numbers rather than reassurance.
Why old PLCs fall over
Three things make a legacy controller fragile on the network side, and they compound.
First, the TCP/IP stack itself is often small and old. Many embedded controllers, HMIs and remote terminal units built between the late 1990s and the mid 2010s licensed a commercial or open source stack meant to fit in a few hundred kilobytes of firmware, not to survive a hostile network. Two widely cited research disclosures show how far this reaches: URGENT/11 (Armis, 2019) found eleven flaws, six of them remote code execution grade, in the IPnet stack shipped inside Wind River VxWorks, a real time operating system Armis estimated was running on over 200 million devices including SCADA and industrial controllers. Ripple20 (JSOF, 2020) found nineteen flaws, four of them critical with CVSS scores above 9, in the Treck TCP/IP stack embedded in products from Schneider Electric, Rockwell Automation and dozens of other vendors. Neither disclosure required a vulnerability scanner at all, ordinary malformed or unusual packets were enough to trip the bugs.
Second, the control loop and the network stack frequently share the same silicon and the same priority scheme. A PLC's scan cycle, read inputs, execute the ladder or structured text program, write outputs, is the thing the safety and process engineering was built around. On many small and mid range controllers, servicing an Ethernet interrupt storm competes for the same CPU cycles as that loop. CISA's ICSA-19-106-03 describes exactly this: high network load consuming CPU in a way that affects the device's normal cycle time, named against the ABB PM554-TP-ETH, Phoenix Contact ILC 151 ETH and ILC 191 ETH 2TX, Schneider Modicon M221, Siemens S7-1211, S7-314 and LOGO! 8, and several WAGO controllers. When the cycle time slips past its watchdog threshold, the safe response most of these devices are designed to take is to fault, not to keep running degraded.
Third, connection table headroom is small and rarely documented. A Modbus TCP slave, an S7 CPU or a BACnet device was sized for one engineering workstation and one SCADA client, not for a scanner opening many sockets in parallel. Nothing catastrophic needs to happen for a table to fill, the practical symptom is usually that the legitimate HMI session gets refused or drops, which on a live process is its own kind of incident.
The documented cases
The oldest and most quoted examples come from the British Columbia Institute of Technology's Industrial Security Incident Database, summarised by Eric Byres and Justin Lowe in "The Myths and Facts behind Cyber Security Risks for Industrial Control Systems" (VDE Kongress, 2004). Three of their cases are still cited in nearly every ICS security training deck:
- A ping sweep run against a production network caused a robotic arm to become active and swing through 180 degrees.
- A ping sweep against a system controlling integrated circuit fabrication caused it to hang, destroying 50,000 dollars of wafers in progress.
- A penetration test intended to inventory hosts on a gas utility's IT network strayed onto the SCADA segment and locked the control system for four hours, interrupting gas flow.
The best documented modern case is Digital Bond's Project Basecamp, presented at the S4 conference in January 2012. Researcher Reid Wightman showed a Schneider Electric Modicon Quantum PLC crashing to a fail state after malformed requests to its FTP and HTTP services, catalogued as CVE-2012-0929 and covered in CISA's alert ICS-ALERT-12-020-03B, which also records that the same project found roughly two hundred Modicon Quantum controllers reachable directly from the public internet at the time. More recently, Siemens' own advisory ICSA-22-041-01 (update B) covers three CVSS 7.5 denial of service flaws, CVE-2021-37185, CVE-2021-37204 and CVE-2021-37205, triggered by specially formed packets on port 102/TCP against the S7-1200 and S7-1500 CPU families, the SIMATIC Drive Controller and the ET 200SP Open Controller. No authentication was required.
What a SYN scan actually sends, versus a full connect
A SYN scan, Nmap's -sS, sends a single TCP SYN packet at a port. If the port answers with SYN-ACK, the scanner immediately sends a RST and moves on, the three way handshake is never completed. This is called a half-open scan, and on a general purpose server it is lighter weight than a full connection because the operating system never allocates a socket for it. A full connect scan, -sT, completes the handshake properly, the way a real client application would, then closes the connection normally.
On IT infrastructure the SYN scan is the gentler option. On embedded ICS stacks the advice runs the other way. Guidance built specifically for scanning ICS/SCADA ranges, including the widely shared reference maintained on GitHub as nmap_tutorial, recommends -sT over -sS for exactly this reason: a small embedded stack has usually only been tested against real client behaviour, a completed handshake followed by a clean close. A stray RST arriving on a half-open connection, or an unusual flag combination the stack was never tested against, is more likely to be mishandled than a connection that looks and behaves exactly like the HMI's own client library. The same guidance adds --scan-delay 1s and --max-parallelism 1, so probes are spaced out and never issued concurrently against one device.
Why the service probe is the dangerous part, not the port sweep
A plain port sweep, SYN or connect, tells you almost nothing except whether something answered on that port. It carries no protocol payload. Service and version detection, Nmap's -sV, or the default script set under -A, is a different category of traffic entirely: it sends a sequence of protocol specific probes, an HTTP request, a TLS client hello, a string designed to provoke a banner, until something matches a signature. A vulnerability scanner with "safe checks" enabled still sends application layer requests, it only stops short of live exploit payloads.
The independent scanning vendor runZero summarised the mechanism plainly in its guidance on scanning ICS safely: legacy scanners that send intentionally malformed traffic to fingerprint an operating system can make an embedded stack freeze or reboot because the unexpected traffic triggers error handling the stack never had, and devices written with too little input validation can react erratically to any unfamiliar request, not only a hostile one. That is precisely the mechanism behind the Modicon Quantum crash in Project Basecamp, a malformed request to the FTP and HTTP services, not a scan of the ports those services sat on. The port sweep found the door. The malformed request is what broke it.
A scan is not the same thing as a protocol level read
These get conflated constantly, and they carry different risk. Asking "is TCP 502 open" is a transport layer question, the device never has to parse Modbus, S7comm or anything else. A protocol level read, the SCADA client's own register or data block read, is an application layer exchange the device already services continuously, so it sits on a different risk tier to a scan entirely. Which Modbus function codes are a safe, read-only poll and which touch outputs is its own question, covered in Modbus TCP security.
Identification reads sit in between and deserve the same caution as a version probe. Nmap's modbus-discover script, for instance, issues a Read Device Identification request, function code 0x2B (43), sub-function 0x0E, specifically to pull vendor and model strings out of a device. It is a legitimate, standards defined request, but it is still an unusual one for many field devices, and it should be throttled and logged exactly like a service probe rather than treated as harmless because it happens to speak the right protocol. The rule of thumb worth keeping: a transport level check is the lowest risk tier, a protocol read that matches the device's existing polling pattern is the middle tier, and any identification or version exchange, in whatever protocol, belongs in the same risk tier as a scanner's service detection.
What "safe" actually means
"Safe" is a set of numbers and exclusions, not a feeling. The parameters below are drawn from the ICS scanning guidance cited above and from the incidents that made them necessary.
| Parameter | Setting | Why |
|---|---|---|
| Scan type | TCP connect (-sT), never SYN (-sS) | Matches the handshake pattern the device's own stack was actually tested against. |
| Parallelism | --max-parallelism 1, one host at a time | Avoids opening several sockets at once against a connection table sized for a single SCADA client. |
| Rate | Tens of packets per second per host, not thousands | runZero gives 40 pps per host as a general throttling starting point, and separately advises beginning even lower, at 1,000 pps from the scanner as a whole and 20 pps per host, before a segment is well known. |
| Timing | --scan-delay 1s, no -T4/-T5 templates | Spreads probes out so the traffic never resembles a flood to a watchdog timer. |
| Depth | Port discovery only on fragile or unidentified devices, no -sV/-A | The malformed or unfamiliar payload, not the open port, is what crashed the Modicon Quantum in 2012. |
| Never-probe list | Checked against the asset inventory before the window opens | Cyclic and multicast I/O channels are live scheduled control traffic, not a service waiting to be enumerated. The full list of ports and protocols that should never take a probe belongs to ICS protocol ports, not repeated here. |
| Window and witness | Agreed maintenance window, an engineer at the panel, a power cycle plan ready | ICSA-19-106-03's fix for several affected controllers was a configuration change agreed with the vendor, not a firmware patch, which only works if someone with authority over the device is present. |
What IEC 62443 and NIST SP 800-82 do not tell you
IEC 62443 and NIST SP 800-82 both tell an assessor to inventory assets and assess risk before touching a network. Neither hands over the one number that actually matters at 2am before a maintenance window: the packet rate at which a specific firmware build on a specific CPU starts missing its cycle time. That number, when it exists at all, lives in a vendor test report, in a CISA advisory written after someone else found it the hard way, or nowhere. ICSA-19-106-03 covers five vendors and still is not a complete list, it is a list of what has been reported, not what is fragile.
The standards also do not tell you that a scanner's "safe checks" toggle was built for IT hosts and only disables exploit style plugins, it does not know that the target underneath is running on a stack with a two or four socket connection table. And they do not tell you that a scan that ran cleanly on Tuesday is not proof it will run cleanly on Thursday, because ICSA-19-106-03's failure condition was the combination of existing network load and the added traffic, not the added traffic on its own. A quiet backup window and a busy production shift are not the same test.
What they get right is the sequencing: passive before active, lab before live, and engineering sign-off before either. Followed properly, with the parameters above and a device that is genuinely well behaved, the residual risk of a scan reads much closer to the transport layer risk of the network itself than to the failure cases documented here. It is not zero. No one who has read ICSA-19-106-03 or the Basecamp writeup should say it is. It is close enough, run properly, that the honest brief for a plant engineer is not "don't scan", it is "scan like this."
Nexich runs its own assessments the same way it describes them here: authorised offensive testing inside the perimeter, air-gapped by default, and read-only against control networks.
Frequently asked questions
Is Nmap safe to run against ICS devices?
With the right settings, mostly. Use a TCP connect scan (-sT) rather than SYN (-sS), cap parallelism at one host at a time, add a one second scan delay, and skip version detection (-sV) and the -A script set on fragile or unidentified devices. Guidance built specifically for ICS ranges recommends exactly these settings, because Nmap's defaults were built for IT hosts, not embedded stacks.
What is the difference between a SYN scan and a full connect scan?
A SYN scan sends only the first packet of the TCP handshake and never completes it, useful on IT hosts because it is quick. A full connect scan completes the handshake like a real client, then closes cleanly. On embedded ICS stacks the connect scan is usually the safer choice, because it matches the only kind of connection the device's stack was actually tested against before it shipped.
Which PLC families have documented scanning or network load faults?
CISA's advisory ICSA-19-106-03 names the ABB PM554-TP-ETH, Phoenix Contact ILC 151 ETH and ILC 191 ETH 2TX, Schneider Modicon M221, Siemens S7-1211, S7-314 and LOGO! 8, and several WAGO controllers, all able to suffer a denial of service under heavy network load. Schneider's Modicon Quantum PLC crashed under malformed requests in Digital Bond's 2012 Project Basecamp research, catalogued as CVE-2012-0929.
Can reading a Modbus register crash a PLC?
That is a question about Modbus's own read-versus-write safety rather than about scanning, and it is answered in full in <a href="modbus-tcp-security.html">Modbus TCP security</a>. What belongs here is the layer above: a scan that only checks whether a port is open never reaches Modbus at all, so it carries none of a register read's risk, whatever that risk turns out to be for a given function code.
What scan rate is considered safe on an OT network?
There is no universal number, but published guidance gives a workable starting point: independent scanning vendor runZero gives 40 packets per second per host as a general throttling baseline, and separately advises starting even lower, around 1,000 packets per second from the scanner as a whole and 20 packets per second per host, before a segment is well known. Combine either with a single connection at a time and no version probes on unidentified devices.
Should a vulnerability scanner's safe checks setting be trusted on a control network?
Not on its own. Safe checks disable live exploit attempts but still send full application layer requests, built and tested against ordinary IT servers, not a controller with a handful of open sockets and a real time scan cycle to protect. Treat it as a starting point rather than a guarantee, and keep it off fragile or unidentified devices entirely.
- CISA ICSA-19-106-03, PLC Cycle Time Influences
- Armis, URGENT/11 research
- JSOF, Ripple20 disclosure
- Byres and Lowe (2004), The Myths and Facts behind Cyber Security Risks for Industrial Control Systems
- NVD, CVE-2012-0929
- CISA, ICS-ALERT-12-020-03B, Modicon Quantum vulnerabilities
- CISA ICSA-22-041-01, Siemens SIMATIC industrial products
- nmap_tutorial, ICS/SCADA scanning guidance (GitHub)
- runZero, Active scanning industrial control systems safely