- name:
- ics-ctf
- description:
- Lab/CTF: ICS/OT protocol challenges; Modbus, DNP3, BACnet, S7, OPC UA, MQTT, PLC/HMI data, registers/coils, safe read-only reasoning.
- license:
- MIT
- compatibility:
- AgentSkills-compatible agents; local artifacts; authorized isolated lab environments.
- author:
- AeonDave
- version:
- 1.8
- category:
- ctf-solving
ICS CTF
Solve industrial-control and OT protocol lab tasks by treating traffic and process state as evidence first, then selecting the smallest safe action that proves the objective.
When this skill applies
- PCAPs, logs, register dumps, historian exports, or remote services involving PLC, HMI, RTU, engineering workstation, SCADA, or process-control wording.
- Protocol cues: Modbus/TCP, DNP3, BACnet, S7comm, EtherNet/IP/CIP, OPC UA, MQTT, Profinet, CAN, CANopen, serial fieldbus, coils, holding registers, function codes, setpoints, or actuator state.
- Tasks requiring traffic baselining, protocol-state reconstruction, register decoding, anomaly identification, or cautious interaction with an isolated lab service.
Operating model
- Preserve and identify the artifact: hash files, list ports, extract timestamps, and record protocol guesses with evidence.
- Separate roles before payloads: identify HMI, PLC, RTU, historian, engineering workstation, gateway, broker, and attacker-like clients.
- Baseline normal behavior: polling interval, read/write ratio, function codes, register ranges, topics, tags, and repeated process cycles.
- Decode semantics: map coils/registers/tags to values, infer endian/scaling, correlate writes with observed physical or process changes.
- Prefer read-only validation. Only write or send commands when the target is clearly an isolated lab and the success oracle requires it.
- Prove the result with a minimal, replayable signal: decoded secret, anomalous write, state transition, topic payload, register value, or process timeline.
Technique integration
Load these as decision engines when their domain appears:
network-technique for PCAP, protocol, and service exposure analysis.
forensic-technique for evidence handling, timelines, and artifact preservation.
wireless-technique for RF, serial-over-radio, or fieldbus captures crossing into wireless analysis.
reversing-technique for PLC program blocks, firmware, protocol clients, or custom encoders.
python-patterns for parsers, register decoders, and safe replay harnesses.
Tool routing
Use tool families based on the evidence, not habit:
wireshark, tcpdump, tshark, and zeek for protocol carving, conversations, timing, display filters (modbus.func_code, s7comm, dnp3, bacapp, cip, opcua, mqtt), and CSV/JSON field export.
pymodbus, modbus-cli, mbtget, QModMaster, and ModbusPal for Modbus read/write, function-code abuse (FC 1–6, 15, 16, 8, 43), coil/register sweeps, and lab simulation.
python-snap7, snap7-server, plcscan, and s7scan for Siemens S7 enumeration (rack/slot, SZL, DB reads) and lab targets.
opcua-asyncio, FreeOpcUa, and OPCUaScanner for OPC UA endpoint enumeration, anonymous-policy detection, node browse, and read/write.
mosquitto_pub/mosquitto_sub, mqtt-pwn, mosquitto-clients, MQTT Explorer/MQTTX, Scapy MQTT layer, MQTTSA, and the Wireshark mqtt + sparkplug dissectors for topic enumeration (#, $SYS/#), retained-message inspection, Sparkplug B (Eclipse Tahu / pysparkplug) decoding, broker fingerprinting (Mosquitto/EMQX/HiveMQ/VerneMQ/NanoMQ) and auth probing. Always pair with the adjacent dashboard port (EMQX 18083, HiveMQ 8080, Node-RED 1880, OpenPLC 8080, Home Assistant 8123) — it is usually the real entry point.
can-utils (candump, cansniffer, cansend, cangen) for CAN bus capture, periodic-frame analysis, and replay against virtual vcan interfaces.
- CyberChef,
jq, pandas, and Python scripts for endian, scaling, timestamp, register-table transformations, and CSV-from-pcap decoding pipelines.
nmap OT NSE scripts (modbus-discover, s7-info, enip-info, bacnet-info, mqtt-subscribe, opcua-info) only against authorized isolated labs; passive PCAP analysis is preferred when artifacts are enough.
binwalk, ghidra, radare2, and strings when the task includes PLC firmware, engineering-project exports, or custom protocol binaries.
saleae-logic-2 when a capture includes serial, CAN, or fieldbus waveforms rather than decoded network traffic.
- Known lab engineering-software (OpenPLC runtime/editor, Codesys, ScadaBR, Node-RED, ConPot honeypot, MiniCPS, ICSsim) often expose web panels and scripting hooks that pair with protocol access; treat them as separate pivot targets when ports such as 1880, 8080, 8443, 11502, or vendor-specific HTTP appear.
Safety and scope gates
- Treat real-world ICS/OT writes as unsafe by default. In lab tasks, document why the environment is isolated before any write.
- Never reset, stop, upload firmware, or mass-write registers unless the prompt explicitly defines an isolated target and the objective requires that exact action.
- Keep a pivot ledger: protocol hypothesis, field evidence, decoded meaning, validation signal, and next safest step.
- If traffic looks malformed, first test endian, scaling, segmentation, custom function codes, or encapsulation before assuming exploitation.
- Report uncertainty: process semantics are inferred unless confirmed by labels, HMI screens, historian tags, or repeated cause-effect evidence.
Quick pivots
- Modbus: map unit IDs, function codes (FC 1/2 read coils/discrete, FC 3/4 read holding/input, FC 5/6 single write, FC 15/16 multi write, FC 8 diagnostics, FC 43 device ID), coil/register ranges, write events, byte order, and byte-vs-word counts. Wireshark filter:
modbus.func_code == 16 for write-multiple-registers events. Check BOTH register/reference number AND register value fields — flag-style data is often hidden in the address, transaction ID, or unit ID instead of the value.
- DNP3: inspect objects, variations, unsolicited responses, control relay outputs (group 12), and outstation/master roles. Filter:
dnp3.
- BACnet: enumerate devices, objects, properties, write-property events, and broadcast discovery (
Who-Is/I-Am). Filter: bacapp plus service choice.
- S7comm: identify rack/slot, SZL reads, data block accesses, and program/block transfer indicators. Filter:
s7comm plus s7comm.param.func. Pair with plcscan/s7scan for lab enumeration and python-snap7 for DB reads.
- EtherNet/IP/CIP: decode sessions, class/instance/attribute paths, tag names, and explicit messaging. Filter:
enip and cip.
- OPC UA: walk endpoint discovery, security policies (note
None policy = anonymous), node IDs, and Browse/Read/Write services. Filter: opcua.
- MQTT: reconstruct topics/nodes, retained messages, client IDs, will payloads, and process-state deltas. Filter:
mqtt. Try wildcard subscriptions # and $SYS/# when broker access is authorized; grab $SYS/broker/version + clients/total + retained messages/count first.
- Sparkplug B / MQTT-bridge pivot: topic prefix
spBv1.0/<group>/<NBIRTH|NDATA|NCMD|DBIRTH|DDATA|DCMD>/<edge>[/<device>] with Protobuf payload signals an Ignition / Cirrus Link / EMQX Neuron / Node-RED bridge. Capture an NBIRTH/DBIRTH first to resolve alias→tag, then treat DCMD writes as actuator writes (Modbus FC 5/6 equivalent). Bridges (Cirrus Link, EMQX Neuron, Node-RED, OpenPLC MQTT, Advantech/Moxa/HMS gateways) round-trip MQTT writes into Modbus/S7/OPC-UA — confirm with state-topic lag (~1 s) before assuming raw broker access reaches the PLC.
- Mosquitto pivot: pull
mosquitto.conf and passwd_file if a host is in scope (auth_plugin, bridge_*, acl_file, allow_anonymous); hashes crack with hashcat (PBKDF2-SHA512 mode for 2.x, legacy SHA512+salt for 1.x). Pin findings to $SYS/broker/version and check vendor advisories (Mosquitto CVE-2017-7650 ACL pattern bypass, CVE-2024-3935 TLS DoS; EMQX/HiveMQ/VerneMQ banners similarly).
- CAN/CANopen: infer arbitration IDs, periodic frames, PDO/SDO patterns, endian, counters, and checksum bytes; use
candump/cansniffer for live data.
- Historian/log exports: normalize timestamps, recover tag/value/unit columns, identify sparse writes, and correlate alarm rows with process deltas.
- Project exports/firmware: extract symbols, comments, ladder/ST strings, tag databases, constants, network configuration, and custom encoders before dynamic interaction.
- Serial/fieldbus captures: identify baud/framing, address fields, checksums, counters, and periodic control loops before replaying frames.
- Engineering-software pivot: when an OpenPLC/Codesys/ScadaBR/Node-RED web panel sits next to the PLC port, check default credentials, scripting hooks (OpenPLC PSM module, Node-RED function nodes), and known CVEs for that specific runtime before scripting writes against the protocol.
- Process-state pivot: pressure/temperature/level registers near safety thresholds, coils tied to pumps/valves/cooling, and setpoint registers driving alarms are common objectives; correlate writes to expected physical effect and verify by read-back or HMI state, not by assumption.
- Purdue-model pivot: map each host to L0 (sensors/actuators), L1 (PLC/RTU), L2 (HMI/SCADA), L3 (historian, engineering workstation, MES) before choosing a target; the shortest path to objective is often an L2/L3 host (HMI web, RDP, historian DB, project files) rather than direct L1 protocol abuse.
- Engineering-workstation pivot: project files on the engineering workstation (
.acd/.l5x RSLogix/Studio 5000, .ap14/.zap14 TIA Portal, .pro/.projectarchive Codesys, .s7p/.ap13 Step7) carry ladder/ST source, tag names, network configuration, and sometimes credentials — grab them before native protocol attacks when the workstation is in scope.
- Race-condition / False Data Injection (FDI) pivot: when a master polls a PLC on a fixed cycle (e.g. every 1–3 s), writes inside the cycle window can flip coils/registers between the PLC update and the next master read; build the write loop tighter than the poll interval and verify the master observes the desynced state.
- L2/MITM pivot in flat OT networks: ARP poisoning between HMI and PLC (or between two PLCs on a Device-Level Ring) lets you rewrite Modbus/EtherNet/IP/S7 in flight with
ettercap/bettercap + NetfilterQueue + Scapy filters — useful when direct write is logged but rewrite-in-transit is not.
- HMI-side pivot: HMI panels often expose VNC (5900) without auth, vendor web UIs with default credentials, or shared SMB folders containing PLC project archives, recipe files, and screenshots that label tag meanings.
- Historian pivot: PI Server, FactoryTalk Historian, WinCC, and Wonderware historians (MSSQL/proprietary on 1433, 5450, 5460) carry long timeseries of every tag and often default/weak SQL credentials — they are an alternative to live PLC read for proving a process anomaly.
- Scan-cycle awareness: writes to the output image (
%Q/coils) are overwritten next PLC scan; setpoint writes (%M/holding registers consumed by ladder) persist. Forces override both regardless of ladder. Mode transitions (STOP/RUN/PROG/FAULT) are high-signal events — search PCAPs for them before chasing register writes.
- Signal decoding pivot: raw register ≠ engineering value. Guess byte/word order (
ABCD/CDAB/BADC/DCBA) by checking which order yields a plausible temperature/pressure/level, then solve EU = raw*scale + offset from two known HMI/historian points. Status registers pack 16 alarm bits — map each bit before claiming meaning.
- Test-cycle discipline: every write goes through baseline (3+ snapshots, diff to identify live vs static registers) → minimal write (one bit/register, smallest FC) → read-back → side-channel verification (HMI/historian/oracle, not just read-back) → hold for ≥ N polling cycles → restore. Read-back alone is insufficient evidence.
- IT→OT chain pivot: realistic OT compromise starts in IT (Responder/SMB-relay, AS-REP/Kerberoast, ADCS ESC1) → DA → OT-DMZ jump (backup script creds, KeePass dump CVE-2023-32784, reused local-admin) → engineering workstation (vendor IDE + project files + saved PLC creds) → PLC setpoint/logic. PLC default passwords often arrive via photos and panel stickers on file shares, not live enumeration. Budget ~60 % IT/AD, ~25 % DMZ pivot, ~15 % PLC interaction; never touch SIS (Triconex/HIMA/GuardLogix).
- Priority frame: OT inverts CIA into Safety > Availability > Integrity > Confidentiality; reject findings/recommendations that raise confidentiality at the cost of safety or availability, and frame impact in operator-visible terms (alarm row, HMI banner, historian sample) rather than CVE wording.
- TIA Portal project pivot: when given a
.zap1x/.ap1x/.s7p archive, treat it like source code. Match TIA Portal major version + HSP to the CPU firmware, dump PLC + HMI tag tables to CSV, reverse OB1 networks in order, then load into PLCSim Advanced to drive inputs and watch DB/M evolution offline. The DB area is the cleanest write surface (setpoint changes leave no Q-image footprint); HMI buttons are usually thin proxies onto M bits. Basic/Comfort panels archive analog tags to internal SD and to the back-USB stick — pull both when you have physical access.
- Real-world archetype pivot: map the artifact to a known OT chain before improvising. Use references/incidents.md for vendor/CVE landing pads and pattern cards such as FrostyGoop-style setpoint flips, BAUXITE/Unitronics defaults, Volt/Sylvanite IT→OT pivots, MQTT-to-gauge IOCONTROL footprints, and Static Tundra-style destructive chains.
Resources
- references/ot-protocol-workflow.md — protocol triage, field extraction, anomaly workflow, and validation cues.
- references/plc-interaction-recipes.md — read-only-first interaction recipes for Modbus, S7, OPC UA, MQTT, and CAN against authorized lab targets, plus engineering-software pivot patterns.
- references/attack-patterns.md — Purdue-model mapping, engineering-workstation pivots, project-file formats, race-condition / FDI writes, L2 MITM in flat OT segments, HMI/historian pivots, and operational-impact reasoning.
- references/signal-decoding-and-testing.md — PLC scan cycle and memory areas, Modbus/CIP/S7/DNP3/BACnet decoding cues, integer/float/BCD/string/time encodings, byte-and-word order resolution, CAN signal decoding, the baseline → write → verify → restore test cycle, and a final validation checklist.
- references/fundamentals-and-it-to-ot-chain.md — OT priority model, asset taxonomy, Purdue recap, and a realistic IT→OT pivot chain for scoping and target selection.
- references/tia-portal-and-plc-fundamentals.md — Siemens S7-1500 / TIA Portal toolchain (project archives, HSP versioning, PLCSim Advanced offline simulation), OB/FB/FC/DB block taxonomy, S7-1500 memory areas (I/Q/M/DB/L), HMI tag binding, PROFINET DCP cell layout, and a step-by-step workflow for analyzing a seized project archive.
- references/incidents.md — OT incident pattern cards, vendor/CVE landing pads, and attack-path templates useful for recognizing or modeling realistic ICS-style tasks.
- references/mqtt-iot-ics-bridges.md — MQTT broker triage (
$SYS fingerprinting, anonymous/retained/LWT/ACL probing), Sparkplug B topic + payload model (Eclipse Tahu), Mosquitto/EMQX/HiveMQ/VerneMQ/NanoMQ specifics with CVE references, MQTT-to-PLC bridge stacks (Cirrus Link Ignition modules, EMQX Neuron, Node-RED, OpenPLC, Advantech/Moxa/HMS gateways), tool chain (mqtt-pwn, mosquitto-clients, MQTT Explorer/MQTTX, MQTTSA, Scapy, Cotopaxi), recurring broker-challenge and home-automation attack patterns, and vendor/research case material (Akamai, Trend Micro, HiveMQ, Claroty Team82, CISA ICS advisories).