feat(ics): dynamic Modbus/TCP probe for PLC/SPS devices [#148] #172

Merged
sharang merged 2 commits from feat/ics-modbus-probe into main 2026-07-16 16:25:05 +00:00
Owner

First increment of #148 (PLC/SPS dynamic testing; tracker #167): probe the
running device over industrial protocols, complementing the static control-logic
rules.

Changes

  • ScanType::IcsProbe (+ phase) — offered for PlcSps targets with a reachable
    endpoint, opt-in (default-off).
  • pipeline::ics::modbus — a minimal, read-only Modbus/TCP client: Read
    Holding Registers + Read Device Identification; never writes to the live
    process.
  • pipeline::ics::probe_target — findings: ics-modbus-exposed (Critical,
    CWE-306 — Modbus/TCP has no auth/encryption by design) and ics-device-disclosure
    (Low, CWE-200). Targets the Modbus port (502) of the 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.

Tests

In-process mock Modbus server (detects the endpoint + reads device id),
unreachable-port, endpoint-parsing, and device-id parsing tests. Full core+agent
suites green; clippy (agent/mcp) clean; dashboard builds.

Follow-ons

  • OPC UA / EtherNet-IP probes.
  • OpenPLC soft-PLC harness in orca-infra (a real Modbus target to demo/validate
    against) — scaffolded separately; you deploy it.

🤖 Generated with Claude Code

First increment of **#148** (PLC/SPS dynamic testing; tracker **#167**): probe the *running* device over industrial protocols, complementing the static control-logic rules. ## Changes - **`ScanType::IcsProbe`** (+ phase) — offered for `PlcSps` targets with a reachable endpoint, **opt-in** (default-off). - **`pipeline::ics::modbus`** — a minimal, **read-only** Modbus/TCP client: Read Holding Registers + Read Device Identification; **never writes** to the live process. - **`pipeline::ics::probe_target`** — findings: `ics-modbus-exposed` (Critical, CWE-306 — Modbus/TCP has no auth/encryption by design) and `ics-device-disclosure` (Low, CWE-200). Targets the Modbus port (502) of the 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. ## Tests In-process **mock Modbus server** (detects the endpoint + reads device id), unreachable-port, endpoint-parsing, and device-id parsing tests. Full core+agent suites green; clippy (agent/mcp) clean; dashboard builds. ## Follow-ons - OPC UA / EtherNet-IP probes. - **OpenPLC soft-PLC harness** in orca-infra (a real Modbus target to demo/validate against) — scaffolded separately; you deploy it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
sharang added 1 commit 2026-07-16 16:05:51 +00:00
feat(ics): dynamic Modbus/TCP probe for PLC/SPS devices (#148)
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
5e8250f7e9
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>
sharang added 1 commit 2026-07-16 16:19:21 +00:00
fix(ics): drop test-only imports already provided by use super::*
CI / Check (pull_request) Successful in 5m21s
CI / Detect Changes (pull_request) Has been skipped
CI / Deploy Docs (pull_request) Has been skipped
CI / Deploy MCP (pull_request) Has been skipped
CI / Deploy Agent (pull_request) Has been skipped
CI / Deploy Dashboard (pull_request) Has been skipped
e59c8add18
CI compiles the test build with RUSTFLAGS=-D warnings; the two explicit
tokio::io trait imports in the modbus test module were redundant with
`use super::*` and failed the "Main Tests" step as unused imports.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
sharang merged commit 77eced8314 into main 2026-07-16 16:25:05 +00:00
sharang deleted branch feat/ics-modbus-probe 2026-07-16 16:25:05 +00:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sharang/compliance-scanner-agent#172