Repository navigation
v2.3.0 — APT lateral-movement & C2 plugin
marlinspike-apt — Tier 1/2 APT detection plugin
New sidecar plugin auto-runs after every scan and emits an APT findings artifact alongside the engine report. Six detector classes covering lateral movement, OT reconnaissance, anomalous host protocol initiation, and C2 beaconing.
Detectors
| Category | Trigger | ATT&CK |
|---|---|---|
APT_LATERAL_MOVEMENT_SMB |
One src talks SMB (445/139) to N+ distinct dst | T1021.002, T1570 |
APT_LATERAL_MOVEMENT_RDP |
RDP fan-out from a non-jump-host source | T1021.001 |
APT_LATERAL_MOVEMENT_WINRM |
WSMAN/WinRM (5985/5986) fan-out | T1021.006 |
APT_OT_RECONNAISSANCE |
Broad OT-protocol fan-out from a single src | T0840, T0842, T0888 |
APT_NEW_HOST_PROTOCOL |
Host initiates a protocol outside its role's expected family | T1018, T1046 |
APT_C2_BEACON |
High-regularity periodic outbound conversation to external dst | T1071, T1102, T1573 |
All detectors operate on existing report fields with no engine widening. The C2 beacon detector consumes the engine's beacon_score / beacon_interval / beacon_jitter per conversation.
Plugin findings → engine risk_findings
Plugin-emitted findings (APT this release, ARP from v2.2.0) are now translated into the engine's risk_findings schema and merged into the report. Result: APT findings drive dashboard severity counts, top-findings lists, priority-node attribution, and per-node _riskFindings views — not just the workbench panel.
Site tuning
rules/apt/base.yaml — per-rule enable/disable, thresholds, and:
jump_hosts: []— suppress RDP/WinRM lateral-movement for known jump hostsot_polling_source_allowlist: []— suppress OT recon for known polling sourcespolling_source_roles:— role allowlist (HMI, Historian, Engineering Workstation, Network Infrastructure, Network Switch, Router, Industrial Gateway)- C2 beacon:
min_score,min_interval_s,max_interval_s,min_packet_count,external_dst_only,excluded_protocols(OT control protocols + DNS/NTP/etc. excluded by default)
FP reduction
- Industrial transit devices (network switch/router/industrial gateway) excluded from
new_host_protocolrole expectations - Same roles added to the OT-recon polling-source allowlist by default
- Engine field interop fix: plugin reads conversation
port(engine canonical) withdst_portfallback
Validation
- 24 unit tests across all six detectors, rule-pack overrides, allowlists, role suppressions, and the port-field alias regression
- End-to-end on synthetic scapy PCAP: 6 findings across 5 detectors, 0 false categories
- End-to-end on 4SICS real OT capture: 0 findings, 0 false positives