Skip to content

Latest commit

 

History

141 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

OT-Security-Lab: Integrated Industrial Control System (ICS) Security Environment

Compliance Framework License: MIT CI Compliance Gate Site Contributing Security

Category Specification
Industry Water Treatment & Filtration
Frameworks IEC 62443, MITRE ATT&CK for ICS, ISA-95 Purdue Model
Environment 4-Zone Segmented Docker Lab (L1–L4) + simulated L0
Monitoring Protocol-aware anomaly detection (Modbus/TCP, DNP3, OPC UA, S7comm)
Evidence Verified Attack Simulation Logs

Project Overview

This repository contains a full-scale, simulated industrial environment designed to demonstrate the implementation of robust security controls within an Operational Technology (OT) context. The project encompasses the entire lifecycle of an IT/OT Security Engineer's responsibilities: from architectural design and network segmentation based on the Purdue Model, to threat modeling, detection engineering, and IEC 62443 compliance mapping.

The lab simulates a Water Treatment & Filtration Facility, facilitating a hands-on platform for validating security configurations and detection rules against realistic ICS attack vectors.


2. Architecture: The Purdue Model

The environment is segmented into logical levels according to the ISA-95 Purdue Model, ensuring strict isolation of critical control processes.

graph TD
    %% Level Definition
    subgraph L4_5 ["Level 4 & 5: Enterprise"]
        A[Attacker Simulation]
        B[Corporate Workstation]
    end

    subgraph DMZ ["Industrial DMZ"]
        JH[Jump Host / Bastion]
        RP[Reverse Proxy]
    end

    subgraph L3 ["Level 3: Operations"]
        C[Historian - InfluxDB]
        D[Engineering Workstation]
    end

    subgraph L2 ["Level 2: Supervisory"]
        E[SCADA / HMI Server]
    end

    subgraph L1 ["Level 1: Control"]
        F1[PLC-01: Intake]
        F2[PLC-02: Treatment]
        F3[PLC-03: Distribution]
    end

    subgraph L0 ["Level 0: Field Devices"]
        G[Sensors/Actuators]
    end

    %% Conduits
    B ---|VPN/HTTPS| JH
    JH ---|RDP/SSH| D
    D ---|S7/Modbus| F1
    E ---|Modbus/TCP| F1
    E ---|Modbus/TCP| F2
    E ---|Modbus/TCP| F3
    F1 ---|Process Flow| F2
    F2 ---|Process Flow| F3
    F3 ---|Hardwired| G

    %% Styling
    style DMZ fill:#fff2cc,stroke:#d6b656,stroke-width:2px
    style L1 fill:#fdb,stroke:#333,stroke-width:2px
Loading

Purdue Levels Mapping:

Note: the Industrial DMZ is implemented: a jump host/bastion (ot_bastion, SSH) and a reverse proxy (ot_reverse_proxy) publish the operator interface to the Enterprise zone, and a corporate workstation exercises the DMZ access path. The gateway enforces the DMZ conduits (C9/C10). L0 field devices are simulated by the controllers.

  • Level 4/5 (Enterprise): Corporate LAN, Attacker Simulation, Corporate Workstation.
  • Industrial DMZ: Broker for remote access (Jump Host) and data visualization (Proxy).
  • Level 3 (Operations): Historian (InfluxDB) and the segregated Engineering Workstation (EWS).
  • Level 2 (Supervisory): Centralized SCADA/HMI (Scada-LTS) for plant-wide visibility.
  • Level 1 (Control): Distributed Control via three PLCs (Intake, Treatment, Distribution).
  • Level 0 (Field): Physical process assets (Valves, Pumps, Flow Meters).

3. Table of Contents

  1. Architecture & Design
  2. Lab Environment
  3. Asset Inventory
  4. Threat Model & Risk Analysis
  5. Detection & Monitoring

Physics-Aware Violation Demo

* [Modbus Anomaly Detection](./detection/rules/modbus_anomaly.py)
* [**Physics-Aware Safety Monitor**](./detection/rules/process_safety_violation.py)
* [Cross-Zone Traffic Alerter](./detection/rules/cross_zone_traffic.py)
*   [Brute Force Detection](./detection/rules/ot_brute_force.py)
*   [DNP3 Telemetry & Detections](./detection/rules/dnp3_dpi.py) — real opendnp3 outstation
*   [OPC UA Telemetry & Detections](./detection/rules/opcua_dpi.py) — real asyncua server
*   [S7comm Telemetry & Detections](./detection/rules/s7comm_dpi.py) — real S7 server
*   [**Live Detection Evidence (JSON Logs)**](./detection/logs/alerts.json) — refreshed automatically by the Compliance Gate on every green run
  1. Hardening & Compliance
  2. Incident Response
  3. Engineering Post-Mortem

Integrated SIEM Dashboard (Loki & Grafana)

SOC Overview Dashboard

Forensic Log Analysis (MITRE ATT&CK Mapping)

Loki Raw Logs

The images above are illustrative UI snapshots. The authoritative runtime evidence is evidence/runtime_evidence.json — machine-generated from the running lab (Loki alert counts by type, ruler rule states, Grafana datasources, historian last values) by governance/testing/capture_evidence.py. Regenerate it after make up.


4. Governance, Risk & Compliance (GRC)

To bridge the gap between technical implementation and industrial standards (Exceltic/ISA-62443 requirements), this lab includes formal documentation:


5. Scalability & Protocol Realities

The lab implements Modbus/TCP, DNP3, OPC UA and S7comm with protocol-aware detection on real endpoints. In a production rollout (e.g., Railway/Transportation):

  • Protocols: Additional protocols (PROFINET, EtherNet/IP) would be added as modular dissectors alongside the existing ones.
  • Asset Discovery: Manual inventory would be replaced by continuous passive monitoring (e.g., Zeek/Nozomi) linked to the asset_inventory.csv.
  • Scale: The normalization/SIEM pipeline is protocol-agnostic and would be extended to large tag counts across distributed controllers.

6. Key Findings & Engineering Judgments

  • Tiered Data Architecture (ADR-02): By isolating the Historian in Level 3 (Operations) rather than Level 2 (Supervisory), we create a unidirectional data flow that prevents corporate IT users from ever reaching the control network directly. This fulfills the IEC 62443 requirement for restricted data access between functional zones.
  • Chokepoint Enforcement (ADR-05): Utilizing a dedicated Linux gateway running iptables instead of standard Docker bridge networking allows for granular L3/L4 traffic control. This architecture ensures that every inter-zone conduit is explicitly authorized, mirroring the functionality of industrial-grade firewalls.
  • Availability-First Detection: Our custom detection rules prioritize high-signal industrial anomalies (e.g., Modbus writes from unauthorized IPs) over generic signature matching. This approach minimizes false positives, ensuring that security monitoring does not interfere with the availability of critical industrial processes.

7. Getting Started

To spin up the entire simulated environment (OpenPLC, HMI, Historian, and Firewall):

# Clone the repository
git clone https://github.com/LiamCarPer/OT-Security-Lab.git
cd ot-security-lab

# Start the environment (firewall rules and IDS rules apply automatically)
make up

# Validate the environment: simulate attacks and assert detection
make compliance

The gateway container applies the IEC 62443 zone firewall on boot and launches all custom detection rules as persistent services (make up is sufficient; no manual docker cp/docker exec steps are required).

The OpenPLC runtimes are headless: each runs a committed program.zip under plc/programs/, built automatically by plc/build.sh from the ST sources with the STruC++ toolchain (no desktop editor required), then uploaded at boot by the EWS bootstrap service. The controllers run real IEC 61131-3 logic and serve the canonical register map over Modbus/TCP; the physics-aware detection therefore observes the live process. See plc/programs/README.md.

Run in Codespaces (one click)

No local Docker required — the whole lab runs in your browser:

  1. Open the repository → Code → Codespaces → Create codespace on main.
  2. Pick the 4-core / 8GB machine type (the stack consumes ~4.3GB RAM).
  3. Wait for the automatic build and boot (first time ~5-10 min; progress is visible in the terminal). The devcontainer forwards: Grafana :3000 · SCADA HMI :8080 (via the DMZ reverse proxy) · Bastion SSH :2222 · Alertmanager :9093. (The PLC runtime API is internal to the Control zone and reached by the EWS, so it is not host-published.)
  4. Validate the environment:
    make compliance
    This replays all attack simulations and asserts detection, then commits the fresh evidence back to detection/logs/alerts.json — which you can watch update live in the editor.

8. Technologies Used

  • Virtualization: Docker, Docker Compose V2 (pinned images, resource limits, restart policies)
  • Industrial: OpenPLC Runtime (v4.2.2, pinned by digest) running committed program.zip bundles built by plc/build.sh (STruC++ toolchain), Scada-LTS v2.8 HMI as a real Modbus/TCP master, MySQL 8.0 config store, InfluxDB 1.8.10 (Historian)
  • Multi-Protocol Endpoints: real DNP3 outstation (opendnp3 via dnp3-python), OPC UA server (asyncua), S7comm server (python-snap7), each exercised by real client emulation from a compromised EWS
  • Historian Data Path (L1→L2→L3): an L2 collector (historian-poller, pymodbus) reads the controllers over conduit C1 and writes InfluxDB in L3 northbound over C3, with a 30-day retention policy; Grafana (L4) visualizes it through C4. The collector prefers the OpenPLC controllers and falls back to a documented Modbus process stand-in only when a controller is unprogrammed or unreachable.
  • Security Infrastructure: iptables (Zone Firewall), Scapy (Custom IDS), iputils-ping, nmap
  • Frameworks: IEC 62443-3-2 (Zones/Conduits), MITRE ATT&CK for ICS, ISA-95 Purdue Model
  • Monitoring: Grafana 11 + Loki 3 (SIEM), Promtail (log shipping), centralized JSON logging
  • DevSecOps: GitHub Actions (CI + Compliance Gate + Release), ruff, bandit, shellcheck, gitleaks, pip-audit, checkov, Trivy, pytest, OPA/conftest (policy-as-code), Syft SBOMs with keyless Sigstore signing, pre-commit hooks, Dependabot

8.1 CI/CD & Supply Chain

  • CI (ci.yml): 11 gates — lint & SAST (ruff/bandit), unit tests (pytest), shellcheck, gitleaks, pip-audit, checkov, Trivy, OPA policy enforcement on the compose stack, pre-commit hooks, PLC bundle reproducibility (plc/check_bundles.py), and SBOM generation with keyless Sigstore signing and a provenance attestation.
  • Compliance Gate (compliance-gate.yml): boots the full lab, replays all attack simulations, asserts detection, and commits the fresh alert evidence back to detection/logs/alerts.json — the repository always shows current, machine-generated evidence.
  • Release (release.yml): tagged releases (v*) with a git-cliff changelog and evidence screenshots attached.
  • Dependabot: weekly dependency updates for pip, GitHub Actions, and the lab Dockerfiles.

9. Known Limitations & Future Work

Current Limitations:

  • Logical vs. Physical Data Diode: Unidirectional flow is enforced via iptables. High-consequence sites require hardware-based optical data diodes.
  • Protocol Scope: Detection is implemented for Modbus/TCP, DNP3, OPC UA and S7comm (see detection/rules/*_dpi.py and the generated siem/rules/ot_*.yaml). The DNP3 emulation drives the real outstation with a raw master because the dnp3-python master aborts headless (see LESSONS_LEARNED.md §9.4).
  • Simulation vs. Emulation: PLCs are software-simulated (OpenPLC) rather than hardware-emulated.

Future Roadmap:

  • EDR Integration: Wazuh agent on the Engineering Workstation, correlated with network alerts in the SIEM.
  • Suricata: Deploy gateway-side Suricata (config and rules exist in siem/suricata/) with the ET ICS ruleset alongside the custom Scapy rules.
  • Automation: SOAR containment is implemented gateway-side (detection/rules/responder.py drops repeat unauthorized-write sources; dry-run by default, armed with OT_RESPONDER_ENFORCE=1), with the Alertmanager webhook receiver and host-side playbook in automation/.

10. Compliance Mapping

  • IEC 62443-3-2: Zones and Conduits implemented.
  • MITRE ATT&CK for ICS: Tactics T0800–T0890 mapped in threat model.

About

Simulated OT/ICS security lab for a water treatment facility: Purdue Model segmentation, protocol-aware detection (Modbus/DNP3), physics-aware safety monitoring, Grafana/Loki SIEM, policy-as-code, and a fully CI-verified DevSecOps pipeline.

Topics

Resources

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages