Passive OT Asset Discovery with Wireshark: Finding Every Device Without Sending a Packet

Ask an industrial site for its asset inventory and you will usually be handed a spreadsheet. Ask when it was last verified against the network and the answer is often a shrug, or a date that predates the last two upgrade projects.

That gap matters more in operational technology than almost anywhere else. You cannot patch what you do not know about, you cannot segment a network whose devices you cannot name, and you cannot detect an unauthorised device on a network you have never characterised. Yet the obvious remedy – point a scanner at it – is the one technique in OT that carries genuine operational risk.

Passive discovery approaches the problem from the opposite direction. Instead of asking devices what they are, you listen to what they say to each other and infer the rest. Done properly it produces an inventory that is not only safe to build on a live plant network, but frequently more accurate than an active scan, because it records what devices actually do rather than which ports happen to be open.

This walkthrough uses the environment from How to Build a Safe OT Cybersecurity Lab. If you have not built it, everything here applies equally to any capture file you already hold.

Safety classification: Green. Every technique below is receive-only. Your analysis interface transmits nothing. This is the one discovery method that can be run on a live production network during normal operations without a maintenance window – provided the capture is set up correctly, which turns out to be less obvious than it sounds.

Why scanning is the wrong reflex

In IT, scanning is routine to the point of being unremarkable. In OT it is the technique most likely to end a conversation with a plant manager, and the reasons are worth understanding properly rather than accepting as folklore.

Embedded controllers have small, fragile network stacks. A PLC is a real-time control device with a network interface bolted on, not a server. Connection tables may hold only a handful of simultaneous sessions. Older controllers have been documented failing under nothing more exotic than a full TCP connect scan – not because of a vulnerability, but because the scan exhausted resources the device needed for its control task. The failure mode is not a crashed service you can restart. It is a controller that stops controlling.

Industrial protocols also have no authentication worth the name. Modbus/TCP, DNP3 and their contemporaries were designed for serial links inside locked cabinets, at a time when physical access was the security model. A read request is indistinguishable from a legitimate poll and a write request is indistinguishable from a legitimate command. Active discovery tools that “just query the device” are speaking the control protocol, and the distance between reading a register and writing one is a single function code.

Then there is the simple matter of priorities. Even a successful scan that causes no failure has consumed controller CPU during a scan cycle. On a system with a ten-millisecond scan time and a safety function attached, that is not a theoretical concern.

Passive analysis sidesteps all three, and it has an underrated advantage besides. An active scan tells you a device has port 502 open. A passive capture tells you that this specific HMI polls that specific PLC every 500 milliseconds for holding registers, that it occasionally writes a coil, and that nothing else on the network ever speaks to it at all. The second answer is far more useful – for segmentation design, for firewall rules, and for knowing what an anomaly would look like.

Capturing traffic without becoming part of it

Your inventory is only as good as your capture point, and this is where most passive assessments quietly go wrong.

A SPAN or mirror port on a managed switch is the standard approach: configure the switch to copy control VLAN traffic to a monitor port and connect your analysis machine there. A network TAP is better where one is available, because a passive optical or copper TAP is physically incapable of transmitting. That is a meaningful assurance on a production network – SPAN sessions drop frames under load and are configured in software that someone could get wrong, whereas a TAP cannot inject even if your analysis machine is compromised. In the lab, a monitoring VM interface attached to the OT Control segment in promiscuous mode fills the same role.

Here is the detail that catches people out: an interface in promiscuous mode still transmits. Left alone, it will send ARP replies, DHCP requests, IPv6 router solicitations, mDNS announcements and NetBIOS chatter. On a production OT network those packets are precisely what you promised not to send, and if anyone is monitoring, your “passive” assessment will show up in their logs.

Configure the capture interface with no IP address at all, and disable IPv6 on it:

sudo ip link set eth1 down
sudo ip addr flush dev eth1
sudo ip link set eth1 promisc on
sudo ip link set eth1 up
sudo sysctl -w net.ipv6.conf.eth1.disable_ipv6=1

Then prove it rather than assuming it. Capture on the interface and filter for anything originating from your own MAC address:

sudo tcpdump -i eth1 -e ether src aa:bb:cc:dd:ee:ff

Zero packets is the only acceptable result. If anything appears, find the service producing it and stop it before you go anywhere near a plant network. Avahi and the Windows browser service are the usual culprits.

Capture for longer than feels necessary. Industrial networks run on cycles that a short capture will miss entirely. Fifteen minutes gives you continuous polling and the primary HMI-to-PLC relationships. Four hours adds shift changes and operator logins. Twenty-four hours brings in nightly backups, batch jobs and time synchronisation. A full week catches weekly maintenance, historian archiving and vendor remote access – and a device that only appears during Tuesday-night maintenance is exactly the device you most want in your inventory.

For anything beyond a quick look, split the capture across multiple files:

sudo tcpdump -i eth1 -s 0 -G 3600 -W 24 \
  -w 'ot-discovery-%Y%m%d-%H%M.pcap'

The -G 3600 starts a new file every hour, with the filename passed through strftime to timestamp it. The -W 24 caps the run at twenty-four files, after which tcpdump exits cleanly – so this is a fixed twenty-four-hour capture that stops on its own rather than a rolling buffer. That is usually what you want for an assessment, because the capture window becomes a defined, reportable period.

If you need to monitor indefinitely and simply cannot allow the disk to fill, pair -W with -C instead. Size-based rotation is the only combination that genuinely overwrites the oldest file:

sudo tcpdump -i eth1 -s 0 -C 500 -W 20 \
  -w /var/captures/ot-discovery.pcap

That holds twenty files of 500 MB each – roughly 10 GB – and recycles them in place.

The -s 0 in both captures whole packets rather than truncated headers. Modern tcpdump defaults to a full snapshot length anyway, but stating it explicitly costs nothing and matters on older builds, where the default of 68 bytes would strip away exactly the payloads you need for the device-identification work later.

First pass: who is on this network?

Open the capture in Wireshark and go to Statistics, then Endpoints, and sort the IPv4 tab by packet count.

This is your raw host list, but before refining it, look at the shape of the distribution rather than just the names. Control networks are characteristically top-heavy: a small number of hosts exchanging an enormous number of packets, because polling dominates everything else. A long tail of hosts with a handful of packets each is where the surprises live, and it deserves more attention than the busy hosts at the top.

Now switch to the Ethernet tab. Wireshark resolves the first three bytes of each MAC address to a manufacturer, and in an industrial environment that single column is remarkably informative. Siemens, Rockwell, Schneider, Omron and Mitsubishi prefixes point at controllers. Moxa, Advantech, Phoenix Contact and Beckhoff suggest serial gateways, I/O modules and industrial PCs. Hirschmann, Westermo, Ruggedcom and Cisco are network infrastructure. Dell, HP and Lenovo are workstations, HMI PCs and historians. VMware and Microsoft prefixes are virtual machines – including, in the lab, your own.

Treat the vendor prefix as strong evidence rather than proof. It identifies the manufacturer of the network interface, which is not always the manufacturer of the device wrapped around it.

From the command line, tshark gives you the same information in a form you can paste into a spreadsheet:

tshark -r ot-discovery.pcap -q -z endpoints,ip
tshark -r ot-discovery.pcap -q -z endpoints,eth

What an inventory actually needs is the IP and MAC paired together, and ARP is the most reliable source of that mapping because it is link-local and every active host generates it:

tshark -r ot-discovery.pcap -Y "arp" -T fields \
  -e arp.src.proto_ipv4 -e arp.src.hw_mac | sort -u

One cross-check is worth running immediately. Any IP address that appears in ARP requests but never in your endpoint list is a host that was addressed but never answered. That is either a decommissioned device still referenced in somebody’s configuration, or a device that is currently down. Both are findings, and both tend to be news to the site.

Second pass: what does each device do?

A host list is not an inventory. Role is what makes it useful, and role emerges from behaviour.

In Modbus/TCP the roles are unambiguous once you know where to look. The master – usually an HMI, SCADA server or historian – initiates the TCP connection to port 502. The slave, meaning the PLC or field device, listens on 502 and only ever responds. Two display filters separate them cleanly:

mbtcp && tcp.dstport == 502     requests, so the source is a master
mbtcp && tcp.srcport == 502     responses, so the source is a slave

Every source address in the first filter is a master; every source in the second is a controller or field device. In the lab this immediately identifies the HMI at 192.168.30.10 as master and OpenPLC at 192.168.30.20 as slave.

Adding the function code sharpens the picture considerably, and this is the step that produces the single most valuable artefact of the whole exercise:

tshark -r ot-discovery.pcap -Y "modbus" -T fields \
  -e ip.src -e ip.dst -e modbus.func_code \
  | sort | uniq -c | sort -rn

The output tells you not merely which devices talk, but what they are permitted in practice to do to each other. Function codes 1 through 4 are reads. Codes 5, 6, 15 and 16 are writes, and writes change the process. A master that only ever issues code 3 is a monitoring system – a historian or a read-only dashboard. A master that issues codes 5 and 16 is a control system with the authority to start a pump.

That distinction drives everything downstream. It defines which firewall rules are genuinely required, which hosts belong in which zone, and what an unauthorised write will look like the day you need to recognise one.

Timing is the other behavioural signal, and industrial traffic is periodic in a way IT traffic never is. Use the IO Graph under Statistics, or measure the intervals directly:

tshark -r ot-discovery.pcap -Y "mbtcp && tcp.dstport==502" \
  -T fields -e frame.time_relative -e ip.src | head -40

Consistent sub-second intervals indicate an HMI polling to keep a display current. Intervals of thirty seconds to several minutes suggest a historian collecting trend data. Irregular, bursty traffic alongside Windows service chatter usually means an engineering workstation, which is to say a human clicking things rather than a program running a loop. Record the interval for each relationship: a polling cycle that later changes rate is either a reconfiguration you should know about or something you very much should.

Third pass: pulling detail out of payloads

Vendor and role are good. Model and firmware are better, because they let you cross-reference the inventory against advisories – and all of it is still available without transmitting.

Modbus function code 43 with MEI type 14 is the Read Device Identification request, and where a master already issues it the response carries vendor name, product code and revision in plain text. Filter on modbus.func_code == 43 and see whether you are lucky. Many masters never ask, but when the exchange is present it hands you inventory data directly.

Other protocols leak other things. CDP and LLDP multicast frames advertise switch names, models, firmware versions, port assignments and VLAN membership, because network devices are designed to announce themselves. That one filter will often populate the entire network-infrastructure section of your inventory:

lldp || cdp

S7comm on TCP/102 reveals Siemens CPU type and rack-and-slot addressing. EtherNet/IP on TCP/44818 and UDP/2222 carries Rockwell identity objects with product names. BACnet on UDP/47808 gives device names and instance numbers. HTTP server headers and page titles from embedded web interfaces on ports 80 and 8080 are often more specific than anything else you will find. And Windows engineering workstations announce their hostnames constantly:

tshark -r ot-discovery.pcap -Y "nbns || mdns || dhcp" \
  -T fields -e ip.src -e nbns.name -e dhcp.option.hostname | sort -u

Scaling beyond what Wireshark can show you

Wireshark is the right tool for understanding a capture and the wrong tool for a week of traffic, because nobody scrolls through forty million packets.

Zeek converts packets into structured logs and does the aggregation for you:

zeek -r ot-discovery.pcap
cat known_services.log | zeek-cut host port_num service | sort -u
cat modbus.log | zeek-cut id.orig_h id.resp_h func | sort | uniq -c | sort -rn

That last command produces, in a single line, the master-slave-function matrix that the previous section built up by hand. On a real capture it is the difference between an afternoon and five minutes. Run Zeek live on the monitoring interface rather than against a file and the same logs become the input to detection rules – which is where this lab is heading next.

Being honest about the limits

Stating what the method cannot do is what makes the rest of it credible.

Silent devices stay invisible. A device that is powered on but never transmits during your capture window does not exist as far as passive analysis is concerned, and cold standby units, spare controllers and equipment on a maintenance VLAN routinely fall into that category.

Your view is also bounded by your capture point. A SPAN port on one switch shows you one switch’s traffic; devices communicating entirely within another segment are simply out of scope. This is the most common reason a passive inventory comes back incomplete, and it is worth confirming exactly what the SPAN session is configured to copy rather than assuming it covers everything. Unicast traffic between two other hosts may not reach you at all on a switched network unless the mirror was set up to include it.

Encrypted and proprietary payloads limit how much detail you can extract – you will see that a conversation happened and how often, but not always what it contained. And passive traffic will not tell you patch level. You may learn a device model and sometimes a firmware version, but not which vulnerabilities are actually present on it.

The professional answer is to treat passive discovery as the safe first layer and then close the gaps deliberately: reconcile findings against engineering drawings and switch MAC address tables, interview site engineers about equipment you never saw, and reserve any active technique for specific devices where the risk has been assessed and the work explicitly authorised.

Before you write up the inventory, work through the essentials. The capture interface transmitted nothing and IPv6 was disabled on it. The capture ran long enough to cover a full operational cycle. Full packets were captured rather than truncated headers. Every endpoint has an IP, a MAC and a resolved vendor. Every Modbus relationship is classified as master or slave, with function codes recorded and writes flagged separately. Polling intervals are measured. LLDP and CDP were checked. Addresses seen in ARP but never answering have been investigated. And the limitations of the capture point are documented alongside the findings rather than left implicit.

What comes next

The inventory produced here is the input to everything that follows: understanding Modbus/TCP traffic in depth, safely testing IT-to-OT segmentation, detecting unauthorised Modbus commands, and building a full traffic baseline. That last one matters most, because you cannot write a detection rule for an unauthorised write until you can state, with evidence, which hosts were ever authorised to write in the first place.


Does your asset inventory match what is actually on the network?

Most industrial sites have an inventory. Fewer have one verified against observed traffic, and fewer still can say with confidence which devices are able to write to a controller.

CyberLabs OT security assessments build verified asset inventories from passive traffic analysis, then examine network segmentation, remote-access pathways, industrial device exposure and monitoring controls – while accounting for operational availability and recovery requirements.