ICS-Security Bundle
The artifacts that come out of a Virtual-SCADA run with ics_security_enabled. Each file is the real bytes the platform produces — none of it is template output.
Labelled data
| Artifact | Format | What’s in it |
|---|---|---|
| scada_telemetry | JSON array | Per-tick rows with true_value, measured_value, reported_value. Attacked rows have labels.anomaly set to the MITRE technique id. |
| commands | JSON array | Operator + supervisor + watchdog + attacker writes. Write-side attack rows carry ground_truth="control_attack" and a technique_id. |
| alarms | JSON array | Alarms triggered by the attacked process state (high-high temperatures, pressure loss, interlock trips). |
| ics_security | NDJSON | Campaign events: start / end windows, technique ids, target signals, and the effect parameters. |
Wire captures
The traffic_pcapng artifact captures every packet produced during the attack window. Because the pcapng is real TCP/IP/Ethernet framing, it loads directly in Wireshark / Zeek / Suricata. Reconnaissance activity from T0846 shows up as real scan signatures; T0857 firmware-manipulation behaviour produces a corresponding firmware-load protocol exchange on the wire.
Using the bundle
from radmah_sdk import RadMah
sdk = RadMah(api_key="...", base_url="https://api.radmah.ai")
job = sdk.jobs.create(
kind="simulate",
engine="virtual_scada",
seed=42,
options={
"description": (
"11 kV distribution substation with two protective relays, one RTU, "
"one breaker, one metering panel. Inject a command-manipulation "
"campaign mid-run."
),
"total_seconds": 120,
"protocols": ["iec61850", "dnp3", "modbus"],
"ics_security_enabled": True,
},
)
# poll until succeeded
for art in sdk.list_artifacts(job.id):
if art.name == "scada_telemetry":
rows = json.loads(sdk.download_artifact(job.id, art.id))
for r in rows:
if r["labels"].get("anomaly", "none") != "none":
# attacked row — feed to IDS training pipeline
...Quality
The run is only released if the Validation Gate passes with attacks included — including the label_score dimension that specifically penalises runs where attacks were requested but no rows got labelled. See Validation Gate.