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
| Protocol | Probe | What it returns | Risk |
|---|---|---|---|
| Modbus TCP | FC 0x2B (Device ID) | Vendor name, product code, firmware version | Low |
| DNP3 | Data Link Status | Outstation address, link-layer config | Low |
| S7comm | SZL request (0x0011) | Module identification, firmware version, serial | Low |
| OPC UA | GetEndpoints | Endpoint URLs, security modes, certificate info | Low |
| BACnet | Who-Is + Read-Property | Device ID, object name, firmware, vendor | Low |
| EtherNet/IP | List Identity | Vendor ID, device type, product name, serial | Low |
| IEC 104 | STARTDT | Control direction confirmation, link status | Low |
| MQTT | CONNECT (no auth) | Broker version, auth requirement, TLS support | Low |
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
| Flag | Default | Description |
|---|---|---|
--rate-limit | 10 | Maximum probes per second across all targets |
--probe-timeout | 3000 | Per-probe timeout in milliseconds |
--retries | 1 | Number 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
- Rules -- run posture checks against discovered assets
- Platform integration -- upload results to the Cybrium asset graph