Global Modbus/TCP Scanning Campaign Hits 14,426 Internet-Exposed PLCs in 70 Countries — Including Active Write Attempts
Introduction
Cato Networks' threat-research team has published findings from a three-month observation window (September–November 2025) that documents a coordinated global probing campaign against internet-exposed Modbus/TCP programmable logic controllers (PLCs). The campaign hit 14,426 distinct IPs across 70 countries, generated ~235,500 inbound Modbus requests from 233 source IPs, and — most worrying — included 3,240 Write Multiple Registers (function code 0x10) requests from a single source, which is manipulation, not reconnaissance. Six high-reputation IPs geolocated to China used the rare expanded-device-identification function code (0x2B/0x0E with sub-code 0x02), a pattern consistent with targeted intelligence collection rather than opportunistic scanning. The single biggest takeaway: tens of thousands of PLCs that should never be on the public internet still are.
What Happened
Cato's analysis of inbound Modbus/TCP (TCP/502) traffic against its customer environments and adjacent honeypots over Sep–Nov 2025 yielded:
| Activity | Volume | Risk |
|---|---|---|
| Read Holding Registers (0x03) baseline scanning | ~235.5K requests, 233 source IPs | Medium |
| Read Device Identification (0x2B/0x0E, sub-code 0x01) | Common across most sources | Medium |
| Bulk DoS-style reads (≈124 registers per request, 158.1K reads against one target) | High volume from few sources | High |
| Expanded device identification (0x2B/0x0E, sub-code 0x02) | 175 requests from 6 IPs, mostly China-geolocated, high-reputation infrastructure | High |
| Write Multiple Registers (0x10) | 3,240 requests from one IP, starting at register 0x0BB8, writing 27–122 registers | Critical |
Geographically: 70 countries; top three (US 36%, France 13%, Japan 12%) account for 61% of targeted IPs. Manufacturing was the most-frequently-targeted sector (18%), followed by healthcare, construction, and government.
The function-code mix is the story. Read Holding Registers (0x03) is the standard ICS-scanner footprint — Shodan, Censys, and most red-team toolkits look like that. Read Device Identification (0x2B/0x0E sub-code 0x01) is also fairly common; it returns vendor name, product code, and revision. The expanded variant (sub-code 0x02) is rare — it returns extended object metadata that scanners almost never request unless the operator is doing deliberate device-fingerprinting for a specific exploit. The fact that only six IPs used it, all from China-geolocated high-reputation infrastructure, is the textbook signature of intelligence collection.
The Write Multiple Registers traffic is the inflection point. Function code 0x10 is not reconnaissance — it changes PLC state. Holding registers control setpoints, alarm thresholds, motor speeds, valve positions, batch parameters. 3,240 writes from a single source against writable register ranges is either a vulnerability test, an active sabotage attempt, or an automated probe looking for PLCs that respond. Cato did not disclose which targets were hit or whether the writes succeeded.
The campaign overlaps with the broader CISA / ENISA messaging throughout 2025 about pro-Russian and pro-PRC hacktivist crews specifically hunting publicly-exposed PLCs in water utilities, manufacturing, and energy. Several previous campaigns (CyberAv3ngers against Unitronics, Volt Typhoon's Asia-Pacific OT recon) followed the same fingerprint → manipulate pattern.
Why It Matters
Modbus/TCP has zero authentication and zero encryption built into the protocol. Any IP that can reach TCP/502 on a PLC can read every register and (for unprotected coils/holding registers) write to them. The protocol design assumes a trusted air-gapped network. The reality, per Shodan and BinaryEdge, is roughly 20,000 public Modbus/TCP endpoints reachable from the open internet at any given time.
The campaign Cato documented isn't sophisticated. It's automated, indiscriminate, and effective. The infrastructure compromised by 0x10 writes could be a water-treatment plant, a pulp mill, a power-plant feedwater system, an HVAC chiller — and the operators may never know the attempt happened, because Modbus has no native logging. ICS asset owners who haven't audited public exposure in 2026 are running on luck.
The OT-IT convergence story matters here too: "we have a firewall in front of our SCADA network" is not the same as "no PLC is reachable from the internet." A common failure pattern is a managed switch with a PLC on a converter side, a Lantronix/Silex serial-to-IP bridge with a public IP (see also: BRIDGE:BREAK CVE round, April 2026), a remote-access VPN where an engineer left port-forwarding enabled, or a cellular modem that defaults to a public listener. Every one of these gets enumerated by Shodan within days of being deployed.
Who Is Affected
- Manufacturers, utilities, and infrastructure operators with any Modbus/TCP-speaking device reachable on TCP/502 from the public internet
- Operators of cellular-connected PLCs (water tanks, lift stations, oil/gas wellheads, agricultural irrigation)
- Sites with serial-to-Ethernet converters (Lantronix, Silex, Moxa, Digi, etc.) that bridge old serial PLCs to TCP networks
- The US, France, Japan, Canada, India, Philippines, Switzerland, Germany, Italy, and Peru together represent ~86% of observed targeting
- Healthcare BMS/medical-device-management Modbus deployments — increasingly a Cato-flagged target sector
How to Protect Yourself
Step 1: Find every Modbus device that's actually reachable from the public internet.
# From an external scan host (NOT inside your OT network)
# Replace YOUR_PUBLIC_RANGE with your assigned ranges from RIPE/ARIN
nmap -Pn -sS -p 502 --open YOUR_PUBLIC_RANGE -oG modbus-public.gnmap
# Confirm the service banner with a Modbus identification query
nmap -Pn -sS -p 502 --script modbus-discover --script-args='modbus-discover.aggressive=true' \
YOUR_PUBLIC_RANGE -oN modbus-deviceids.txt
# Cross-reference against Shodan / Censys for what attackers see
curl -s "https://api.shodan.io/shodan/host/search?key=$SHODAN_KEY&query=port:502+net:YOUR_RANGE" \
| jq '.matches[] | {ip:.ip_str, port:.port, org:.org, banner:.data}'
Step 2: Take Modbus off the public internet. No exceptions. If a PLC needs remote operator access, put it behind a Zero Trust gateway with per-user authentication, MFA, and full session recording. Block TCP/502 inbound at every perimeter:
# Linux iptables
iptables -A INPUT -p tcp --dport 502 -j DROP
iptables -A FORWARD -p tcp --dport 502 -j DROP
# pfSense / OPNsense — add a floating rule blocking TCP/502 inbound on WAN
# Cisco ASA
access-list outside_in deny tcp any any eq 502
For cellular-connected RTUs, demand from your cellular provider that the SIM be on a private APN with a routable IPSec tunnel back to your control center — not on the public internet.
Step 3: Segment internally. Even if a PLC isn't internet-reachable, the IT-side compromise pattern (phishing → workstation → flat-network-pivot → Modbus write) is exactly how Volt Typhoon and CyberAv3ngers operate. Apply Purdue-model segmentation:
# Example: corporate IT (10.10.0.0/16) must not reach OT (10.50.0.0/16) on 502
iptables -A FORWARD -s 10.10.0.0/16 -d 10.50.0.0/16 -p tcp --dport 502 -j DROP
iptables -A FORWARD -s 10.10.0.0/16 -d 10.50.0.0/16 -p tcp --dport 102 -j DROP # S7
iptables -A FORWARD -s 10.10.0.0/16 -d 10.50.0.0/16 -p tcp --dport 44818 -j DROP # EtherNet/IP
iptables -A FORWARD -s 10.10.0.0/16 -d 10.50.0.0/16 -p udp --dport 47808 -j DROP # BACnet
Only an explicit jump-host inside a DMZ subnet should be allowed Modbus access, and only outbound from there.
Step 4: Monitor Modbus traffic on the OT side. Tools that understand the protocol:
- Zeek with the
modbusanalyzer enabled — gives you amodbus.logwith every function code, register start, and quantity - Snort / Suricata with the Quickdraw ICS rules
- Claroty / Nozomi / Dragos / Tenable.OT for commercial passive monitoring
Specifically alert on:
# Suricata rule example — Modbus write to PLC from non-engineering workstation
alert tcp !$ENGINEERING_VLAN any -> $PLC_NET 502 (msg:"Modbus write attempt from \
non-engineering source"; flow:established,to_server; \
content:"|10|"; offset:7; depth:1; \
sid:2026100001; rev:1;)
For function code 0x2B/0x0E sub-code 0x02 (the China-geolocated higher-intent fingerprint):
alert tcp any any -> $PLC_NET 502 (msg:"Modbus expanded device identification probe"; \
flow:established,to_server; \
content:"|2B 0E 02|"; offset:7; depth:3; \
sid:2026100002; rev:1;)
Step 5: Patch and harden the PLCs themselves. Modern Siemens, Rockwell, Schneider, and Mitsubishi PLCs support write-protect switches (physical key), authenticated programming sessions (NETHERMAC, CIP Security), and HTTPS-based engineering. Enable them. Set a firmware passphrase. Disable unused services (web server, FTP, SNMP).
Step 6: Add Modbus-specific intrusion testing to your annual program. Don't wait for a real adversary to write to your registers. Scope an authorized red-team exercise that specifically attempts function code 0x05 (Write Single Coil), 0x06 (Write Single Register), and 0x10 (Write Multiple Registers) against test PLCs in a segmented lab. The findings always justify the budget for the segmentation projects you've been deferring.
Step 7: Map your asset inventory to CISA's KEV and ICS advisories. Subscribe to CISA's ICS feed:
curl -s https://www.cisa.gov/cybersecurity-advisories/ics-advisories.xml \
| xmllint --xpath '//item/title' - 2>/dev/null
Most ICS advisories include a "Mitigations" section that explicitly tells you what Modbus/CIP/EtherNet/IP traffic to block.
Source
- Cato Networks Threat Research — Global Campaign Discovered with Modbus PLCs Targeted
- Industrial Cyber — Cato traces large-scale Modbus/TCP activity targeting PLCs
- Security Online — The Global Surge in Modbus/TCP Probes Targeting Our Physical World
- TechFlowDaily — LMDeploy CVE-2026-33626 (sidebar coverage of the Modbus campaign)
- CISA ICS Advisories
- Digital Bond Quickdraw Snort Rules