finding-plcs-online
practicalLesson 2 β Finding PLCs Online
The Exposure Reality
Shodan indexes over 90,000 devices on port 502 at any given time. These are not honeypots β they are operational PLCs, RTUs, and SCADA gateways exposed directly on the public internet. Most are there because someone connected a cellular modem for remote monitoring and left the default gateway open, or because a firewall rule was misconfigured, or because the integrator did not understand that port 502 with no authentication means anyone on the internet can read and write the device.
Before touching anything active, Shodan gives you passive intelligence on the exposed population. This is legal. Shodan crawls the internet and banners are already collected β you are querying a search engine, not sending packets to industrial devices.
Shodan Queries
Shodan supports boolean queries, field filters, and facet analysis. The most relevant filters for Modbus hunting:
port:502
Returns all indexed hosts with TCP port 502 open. Not all of these are Modbus β some are other services on that port β but the vast majority are.
port:502 modbus
Matches hosts where Shodan's banner analysis confirmed Modbus protocol. Shodan probes port 502 with a Modbus device identification request and tags the result.
port:502 "Schneider Electric"
Targets Schneider Electric devices. The string appears in the FC43 vendor name field or the raw banner. Schneider PLCs (Modicon M340, M580, Momentum) are common in water treatment and building automation.
port:502 "Siemens"
Siemens S7 devices sometimes appear on port 502 in Modbus compatibility mode. The primary Siemens protocol is S7comm on port 102, but dual-protocol devices exist.
port:502 country:FR
Restricts results to France. Combine with org or ASN for targeting specific infrastructure operators.
port:502 org:"Enedis"
Targets assets registered to a specific organization's ASN. Enedis is the French distribution system operator. This query has historically returned active devices in substations.
port:502 net:203.0.113.0/24
Restricts to a CIDR block. Useful when you have a target IP range from a network map or BGP data.
port:502 before:2024-01-01
Finds devices that have been continuously exposed since before a certain date β often the most neglected systems.
Combining filters:
port:502 modbus country:US org:"water"
Facets for analysis (use facet: on the Shodan website):
- facet:country β geographic distribution
- facet:org β organizations with most exposed devices
- facet:product β identified device types
Reading Shodan Results
A typical Shodan result for a Modbus device looks like this:
{
"ip_str": "203.0.113.47",
"port": 502,
"transport": "tcp",
"product": "Schneider Electric Modicon M340",
"data": "Modbus/TCP\nDevice Identification:\n Vendor Name: Schneider Electric\n Product Code: BMX P34 2020\n Revision: V3.40\n Vendor URL: www.schneider-electric.com\n Product Name: Modicon M340",
"org": "ExampleISP",
"country_name": "France",
"timestamp": "2026-05-10T08:22:11.000000"
}
Key fields to extract from Shodan data:
- product: Shodan's identified device type
- data: The raw banner, which for Modbus includes the FC43 response if the device supports it
- org: The organization (from WHOIS/BGP) β tells you who owns the device
- hostnames: Reverse DNS β sometimes reveals asset names like plc01.plant-name.example.com
From the FC43 data in the banner you get vendor, model, and firmware version. Cross-reference the firmware version against the vendor's security advisories. Schneider Electric publishes CVEs for their PLCs β a firmware version from the banner can map directly to a known vulnerability.
Nmap Discovery
When you have authorization to scan a target network, Nmap's NSE (Nmap Scripting Engine) provides two relevant scripts for Modbus:
Basic discovery:
nmap -p 502 --script modbus-discover <target>
This sends a Modbus device identification request (FC43) and reports back. Example output:
PORT STATE SERVICE
502/tcp open modbus
| modbus-discover:
| sid: 1
| Slave ID: \xFF\x00Schneider Electric\x00BMX P34 2020\x00V3.40
|_ Unit ID: 1
Aggressive mode (scans all unit IDs 1-247):
nmap -p 502 --script modbus-discover \
--script-args modbus-discover.aggressive=true <target>
Aggressive mode is slower but finds devices that only respond on non-default unit IDs. Some devices are configured with unit ID 255 or other non-standard values specifically to avoid casual discovery β aggressive mode finds them.
Scanning a subnet:
nmap -p 502 --script modbus-discover 192.168.1.0/24 -oN modbus-scan.txt
Combining with service detection:
nmap -p 502 -sV --script modbus-discover <target>
-sV adds Nmap's own service fingerprinting, which may identify the vendor independently of the NSE script.
Wireshark Analysis
When you have a packet capture from a network tap, SPAN port, or recorded PCAP from a lab, Wireshark decodes Modbus TCP natively.
Capture filter (use at capture time to reduce file size):
tcp port 502
Display filter (apply after capture):
modbus
or
tcp.port == 502
Wireshark decodes the MBAP header fields and the PDU. For a FC03 response you will see: - Transaction Identifier - Protocol Identifier (always 0) - Length - Unit Identifier - Function Code: Read Holding Registers (3) - Byte Count - Register values (as 16-bit words)
Following a write operation: Filter on modbus.func_code == 6 for Write Single Register or modbus.func_code == 16 for Write Multiple Registers. Right-click a packet and select "Follow TCP Stream" to see the complete request/response exchange.
Extracting all register writes from a PCAP using tshark:
tshark -r capture.pcap -Y "modbus.func_code == 6 or modbus.func_code == 16" \
-T fields -e frame.time -e ip.src -e modbus.reference_num -e modbus.regval_uint16
This gives you a timestamped log of every register write: who wrote it, to which address, and what value.
Understanding What You Found
When you locate an exposed Modbus device, you need to answer several questions before touching it:
What is it? FC43 response gives you vendor and model. A Schneider M340 is a general-purpose PLC. A Schneider Sepam is a protection relay for power systems. A Wago 750-352 is a fieldbus coupler. The model determines what the registers control.
What does it control? Context from org name, hostname, and geographic location. A device owned by a water utility in a rural area is likely a pump station controller. A device on a hospital network controls HVAC or UPS systems.
Who else is talking to it? In a PCAP, look for other IP addresses sending FC03/FC06 requests. The SCADA master will poll the device on a regular interval β usually every 1β10 seconds. The traffic pattern tells you the polling rate and which registers the SCADA system is reading.
What does the register map look like? Without a vendor datasheet, you map it empirically: read all registers, note which ones change over time (sensor values), which ones are static (configuration), and which ones cause a response when written.
Legal Boundary
Passive Shodan queries: legal everywhere. You are querying Shodan's database, not sending packets to industrial devices.
Running nmap or pymodbus against a device you do not own or have explicit written authorization to test: illegal in every jurisdiction that has computer crime laws. In the EU this falls under the NIS2 Directive framework and domestic computer crime statutes (France: LCEN / Code PΓ©nal art. 323-1). In the US: CFAA. In the UK: Computer Misuse Act.
The practical consequence: unauthorized access to a PLC controlling critical infrastructure will be prosecuted as interference with critical national infrastructure, not just simple unauthorized computer access. The sentences are substantially higher.
Use Shodan for passive research. Build your lab environment for active testing. The next lesson uses a local Docker-based Modbus simulator β not real infrastructure.
Key Takeaways
- Shodan has 90,000+ Modbus-exposed devices indexed; passive querying is legal
port:502 modbusis the baseline query; refine with country, org, and vendor strings- FC43 data in Shodan banners gives you vendor/model/firmware for vulnerability mapping
nmap --script modbus-discoverenumerates unit IDs and extracts device identification- Wireshark
modbusdisplay filter decodes all fields;tsharkcan extract write operations from PCAPs - Active scanning requires written authorization β this is critical infrastructure, not CTF servers