Skip to main content

Active probing

Active mode sends protocol-native read-only queries to OT devices to enumerate identity, firmware, and configuration details that passive observation alone cannot reveal. Every active probe is designed to be non-destructive, but OT devices are notoriously fragile -- so active mode is gated behind an explicit confirmation flag.

Basic usage

sudo cyprobe active --targets 192.168.1.0/24 --active-confirm

Without --active-confirm, the command prints what it would do and exits. This is intentional -- you should review the probe plan before sending packets to production OT infrastructure.

Dry run (default)

sudo cyprobe active --targets 192.168.1.0/24

Output:

PROBE PLAN (dry run — pass --active-confirm to execute)
TARGET PROTOCOL PROBE RISK
192.168.1.10 Modbus TCP FC 0x2B Device ID low
192.168.1.20 S7comm SZL 0x0011 low
192.168.1.30 OPC UA GetEndpoints low
192.168.1.40 BACnet Who-Is low

4 probes planned. 0 targets on safelist. Pass --active-confirm to execute.

What each probe does

ProtocolProbeWhat it returnsRisk
Modbus TCPFC 0x2B (Device ID)Vendor name, product code, firmware versionLow
DNP3Data Link StatusOutstation address, link-layer configLow
S7commSZL request (0x0011)Module identification, firmware version, serialLow
OPC UAGetEndpointsEndpoint URLs, security modes, certificate infoLow
BACnetWho-Is + Read-PropertyDevice ID, object name, firmware, vendorLow
EtherNet/IPList IdentityVendor ID, device type, product name, serialLow
IEC 104STARTDTControl direction confirmation, link statusLow
MQTTCONNECT (no auth)Broker version, auth requirement, TLS supportLow

All probes are read-only. No writes, no configuration changes, no firmware uploads, no coil/register modifications.

Safety gates

--active-confirm

Required to actually send probes. Without it, cyprobe only prints the plan.

Rate limiting

sudo cyprobe active --targets 192.168.1.0/24 --active-confirm \
--rate-limit 10 \
--probe-timeout 5000
FlagDefaultDescription
--rate-limit10Maximum probes per second across all targets
--probe-timeout3000Per-probe timeout in milliseconds
--retries1Number of retries on timeout (0 = no retry)

The default rate of 10 probes/second is conservative. Most OT networks can handle more, but start low and increase only after validation.

Fragile device safelist

Some devices are known to misbehave when probed -- older PLCs that restart on unexpected packets, safety controllers that should never receive unsolicited traffic, etc.

Create a safelist file to exclude them:

# safelist.yml
- ip: 192.168.1.100
reason: "Safety PLC — do not probe"
- ip: 192.168.1.101
reason: "Legacy Modicon — crashes on Device ID request"
- cidr: 10.0.50.0/24
reason: "SIS network — no active probing allowed"
sudo cyprobe active --targets 192.168.1.0/24 --active-confirm \
--safelist safelist.yml

Safelisted targets are skipped entirely and noted in the output. The dry-run plan also flags them so you can verify coverage before executing.

Combining passive and active

A common workflow is to run passive discovery first, then target active probes only at the assets that were found:

# Step 1: passive discovery
sudo cyprobe passive --interface eth0 --duration 300 --format json > passive.json

# Step 2: active probes against discovered assets only
sudo cyprobe active --from-passive passive.json --active-confirm

The --from-passive flag reads the passive output and builds a target list from discovered IPs, automatically selecting the right protocol probes for each.

Output

Active mode produces the same output formats as passive mode (text, json, sarif) with additional fields for probe responses:

sudo cyprobe active --targets 192.168.1.0/24 --active-confirm \
--format json > active.json

Each asset object gains a probe_response field containing the raw structured data returned by the device.

Next step