feat(ics): dynamic Modbus/TCP probe for PLC/SPS devices (#148)
CI / Check (pull_request) Failing after 4m3s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
CI / Check (pull_request) Failing after 4m3s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
Adds the first dynamic dimension to PLC/SPS targets: probe the running device over industrial protocols, complementing the static control-logic rules. - New ScanType::IcsProbe (+ phase), offered for PlcSps with a reachable endpoint (opt-in / default-off). - pipeline::ics::modbus — a minimal, read-only Modbus/TCP client: issues Read Holding Registers + Read Device Identification, never writes to the live process. Detects an endpoint that answers unauthenticated Modbus and reads its device identity (vendor/product/revision). - pipeline::ics::probe_target — emits findings: `ics-modbus-exposed` (Critical, CWE-306 — Modbus/TCP has no auth/encryption by protocol design) and `ics-device-disclosure` (Low, CWE-200). Targets the Modbus port (502) of the target's Live URL, independent of any WebVisu HTTP port. - orchestrator: a PLC/SPS target runs the ICS probe when planned (alongside the control-logic scan and DAST). Unit-tested against an in-process mock Modbus server + endpoint-parsing and device-id parsing tests. Docs: new "Dynamic testing — ICS protocol probe" section. First increment of #148 (soft-PLC + industrial-protocol probing); OPC UA / EtherNet-IP and the OpenPLC soft-PLC harness (orca-infra) follow. Tracker #167. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a3f3f1d4f5
commit
5e8250f7e9
@@ -24,6 +24,9 @@ pub enum ScanType {
|
||||
MobileStatic,
|
||||
/// Static analysis of a container image.
|
||||
ContainerScan,
|
||||
/// Dynamic probing of a running PLC/SPS device over industrial protocols
|
||||
/// (Modbus/TCP, OPC UA, …) for exposed/unauthenticated control access.
|
||||
IcsProbe,
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ScanType {
|
||||
@@ -43,6 +46,7 @@ impl std::fmt::Display for ScanType {
|
||||
Self::PlcControlLogic => write!(f, "plc_control_logic"),
|
||||
Self::MobileStatic => write!(f, "mobile_static"),
|
||||
Self::ContainerScan => write!(f, "container_scan"),
|
||||
Self::IcsProbe => write!(f, "ics_probe"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,6 +80,7 @@ pub enum ScanPhase {
|
||||
LlmTriage,
|
||||
IssueCreation,
|
||||
DastScanning,
|
||||
IcsProbe,
|
||||
Completed,
|
||||
}
|
||||
|
||||
|
||||
@@ -251,6 +251,12 @@ pub fn rules_for(target_type: TargetType) -> Vec<ScanRule> {
|
||||
"Dynamic scan of the running device (WebVisu / exposed services)",
|
||||
RunningUrl,
|
||||
),
|
||||
ScanRule::new(
|
||||
ScanType::IcsProbe,
|
||||
false,
|
||||
"Probe the running device over industrial protocols (Modbus/TCP, …)",
|
||||
RunningUrl,
|
||||
),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user