SC-096: Industrial PLC Attack — Operation IRON FORGE¶
Scenario Overview¶
| Field | Detail |
|---|---|
| ID | SC-096 |
| Category | OT/ICS Security / Industrial Control Systems / Critical Infrastructure |
| Severity | Critical |
| ATT&CK Tactics | Initial Access, Execution, Persistence, Inhibit Response Function, Impair Process Control |
| ATT&CK Techniques | T1495 (Firmware Corruption), T0839 (Module Firmware — ICS), T0855 (Unauthorized Command Message — ICS), Custom ICS techniques for safety system bypass and HMI manipulation |
| Target Environment | Steel manufacturing facility with 48 PLCs, 12 HMI stations, 6 Safety Instrumented Systems (SIS), DCS, and Purdue Model Level 2-3 network segmentation supporting a facility with 850 employees |
| Difficulty | ★★★★★ |
| Duration | 4–6 hours |
| Estimated Impact | 6 PLCs compromised with modified ladder logic; 2 Safety Instrumented Systems bypassed; HMI operators presented with spoofed process values; blast furnace temperature control manipulated (simulated); 72-hour dwell time before anomaly detection; full remediation requiring PLC firmware reload from verified golden images and physical safety system validation |
Narrative¶
Ironclad Steelworks, a fictional integrated steel manufacturing facility at ironclad-steel.example.com, operates a modern production plant producing 2.4 million tons of steel annually. The facility employs 850 workers across three shifts and relies on an extensive industrial control system (ICS) infrastructure to manage blast furnaces, basic oxygen furnaces (BOF), continuous casting lines, and rolling mills.
The ICS architecture follows a modified Purdue Model with Level 0-1 (process control — PLCs, sensors, actuators), Level 2 (area supervisory — HMI stations, engineering workstations), Level 3 (site operations — historian, MES, OPC servers), and a Level 3.5 DMZ separating IT from OT networks. The facility operates 48 Allen-Bradley ControlLogix PLCs, 12 FactoryTalk View HMI stations, and 6 Triconex Safety Instrumented Systems (SIS) protecting critical safety functions including blast furnace over-temperature, BOF vessel overpressure, and emergency gas evacuation.
The OT security team has implemented network segmentation between Purdue levels, deployed an OT-specific network monitoring tool (passive DPI), and maintains offline PLC program backups. However, several engineering workstations at Level 2 have direct internet access for vendor support and software updates — a common configuration gap in manufacturing environments.
In April 2026, a nation-state threat actor group designated FOUNDRY GHOST — an ICS-focused APT with deep knowledge of industrial process control and safety systems — compromises the facility's control systems through a supply chain attack on a third-party remote access tool. The attack targets PLCs controlling the blast furnace process, manipulates safety system logic, and spoofs HMI displays to hide the unauthorized changes from operators.
Attack Flow¶
graph TD
A[Phase 1: Initial Access<br/>Supply chain compromise of remote access tool] --> B[Phase 2: IT-to-OT Pivot<br/>Traverse DMZ to Level 3 historian]
B --> C[Phase 3: OT Reconnaissance<br/>Enumerate PLCs, HMI, SIS, network topology]
C --> D[Phase 4: PLC Firmware Manipulation<br/>Upload modified firmware to blast furnace PLCs]
D --> E[Phase 5: Ladder Logic Injection<br/>Modify process control logic for temperature manipulation]
E --> F[Phase 6: Safety System Bypass<br/>Alter SIS logic to suppress protective shutdowns]
F --> G[Phase 7: HMI Spoofing<br/>Display false process values to operators]
G --> H[Phase 8: Detection & Response<br/>OT network anomaly + physical process deviation] Phase Details¶
Phase 1: Initial Access — Supply Chain Compromise¶
ATT&CK Technique: T1195.002 (Supply Chain Compromise: Compromise Software Supply Chain)
FOUNDRY GHOST compromises a legitimate third-party remote access tool used by Ironclad Steelworks' ICS vendor for remote maintenance and troubleshooting. The attacker injects a backdoor into a software update for the remote access agent installed on engineering workstations at Purdue Level 2. When the engineering workstations automatically update the remote access tool, the backdoor provides FOUNDRY GHOST with persistent access to the OT network.
# Simulated supply chain compromise (educational only)
# Attacker compromises a third-party remote access tool update
# The legitimate remote access tool is used by the ICS vendor
# for scheduled maintenance on engineering workstations
# Compromised update details (synthetic):
{
"software": "IndustrialRemote Pro v4.2.1",
"vendor": "remote-industrial.example.com",
"update_server": "updates.remote-industrial.example.com",
"compromised_version": "4.2.1-build-2026.03.15",
"backdoor_type": "Reverse shell via HTTPS callback",
"callback_host": "203.0.113.77",
"callback_interval": "300 seconds",
"affected_workstations": [
"EWS-BF01 (10.80.2.10) — Blast Furnace Engineering WS",
"EWS-BOF01 (10.80.2.20) — BOF Engineering WS",
"EWS-CAST01 (10.80.2.30) — Casting Line Engineering WS"
]
}
# The backdoor is activated when the update installs on March 15:
# EWS-BF01 calls back to C2 every 5 minutes via HTTPS
# The traffic blends with legitimate vendor support connections
# that also use HTTPS to external servers
# Attacker validates access to engineering workstation:
C2> session -i 1
[*] Starting interaction with session 1 (EWS-BF01)
> whoami
IRONCLAD\ews-bf-service
> ipconfig
Windows IP Configuration:
Ethernet adapter OT-Net:
IPv4 Address: 10.80.2.10
Subnet Mask: 255.255.0.0
Default Gateway: 10.80.0.1
> net localgroup "Administrators"
IRONCLAD\OT-Admins
IRONCLAD\ews-bf-service
BUILTIN\Administrators
# The engineering workstation service account has:
# - Local administrator access on the workstation
# - Network access to Level 1 PLCs and Level 2 HMI stations
# - Access to the ControlLogix programming software (RSLogix 5000)
# - The ability to download/upload PLC programs
Phase 2: IT-to-OT Pivot via DMZ¶
ATT&CK Technique: T1021 (Remote Services)
From the compromised engineering workstation, FOUNDRY GHOST maps the OT network architecture, identifies the Level 3/3.5 DMZ configuration, and discovers that the historian server at Level 3 has dual-homed connectivity to both the IT network (for data replication) and the OT network (for process data collection). The attacker also identifies that several engineering workstations can reach the internet directly for vendor support — the path the backdoor is using for C2.
# Simulated OT network reconnaissance (educational only)
# Attacker maps the Purdue Model architecture from Level 2
# Network topology discovered from engineering workstation:
> arp -a
Interface: 10.80.2.10 --- 0x3
10.80.0.1 AA-BB-CC-01-01-01 (L3 DMZ gateway)
10.80.1.10 AA-BB-CC-02-02-02 (HMI-BF01)
10.80.1.11 AA-BB-CC-02-02-03 (HMI-BF02)
10.80.1.20 AA-BB-CC-02-02-04 (HMI-BOF01)
10.80.3.10 AA-BB-CC-03-03-03 (OPC-Server-01)
10.80.3.20 AA-BB-CC-03-03-04 (Historian-01)
# Purdue Level mapping:
# Level 3 (Site Operations):
# 10.80.3.10 — OPC UA Server (process data aggregation)
# 10.80.3.20 — OSIsoft PI Historian (process data storage)
# 10.80.3.30 — MES Server (manufacturing execution)
#
# Level 2 (Area Supervisory):
# 10.80.2.10 — EWS-BF01 (Blast Furnace Engineering — COMPROMISED)
# 10.80.2.20 — EWS-BOF01 (BOF Engineering)
# 10.80.2.30 — EWS-CAST01 (Casting Line Engineering)
# 10.80.1.10 — HMI-BF01 (Blast Furnace Operator Station 1)
# 10.80.1.11 — HMI-BF02 (Blast Furnace Operator Station 2)
#
# Level 1 (Basic Control):
# 10.80.10.1-10 — Blast Furnace PLCs (ControlLogix)
# 10.80.10.11-20 — BOF PLCs (ControlLogix)
# 10.80.10.21-30 — Casting PLCs (ControlLogix)
#
# Level 0.5 (Safety):
# 10.80.20.1-2 — Blast Furnace SIS (Triconex)
# 10.80.20.3-4 — BOF SIS (Triconex)
# 10.80.20.5-6 — Gas Evacuation SIS (Triconex)
#
# Level 3.5 (DMZ):
# 10.80.0.0/24 — DMZ between IT and OT
# Firewall rules allow: Historian → IT (data replication only)
# Engineering WS → Internet (vendor support — VULNERABILITY)
# Scan Level 1 PLC network from engineering workstation
> nmap -sT -p 44818,2222 10.80.10.0/24
# Port 44818 = EtherNet/IP (CIP protocol for Allen-Bradley)
# Port 2222 = Triconex TSAA protocol
10.80.10.1 OPEN 44818 (PLC-BF-TEMP-01 — Blast Furnace Temperature)
10.80.10.2 OPEN 44818 (PLC-BF-TEMP-02 — Blast Furnace Temperature)
10.80.10.3 OPEN 44818 (PLC-BF-GAS-01 — Gas Flow Control)
10.80.10.4 OPEN 44818 (PLC-BF-CHARGE-01 — Charge Control)
10.80.10.5 OPEN 44818 (PLC-BF-COOL-01 — Cooling System)
10.80.10.6 OPEN 44818 (PLC-BF-COOL-02 — Cooling System)
10.80.20.1 OPEN 2222 (SIS-BF-01 — Blast Furnace Safety)
10.80.20.2 OPEN 2222 (SIS-BF-02 — Blast Furnace Safety)
Phase 3: OT Reconnaissance — PLC and Process Enumeration¶
ATT&CK Technique: T0855 (Unauthorized Command Message — ICS)
FOUNDRY GHOST uses the RSLogix 5000 programming software already installed on the engineering workstation to enumerate PLC configurations, read current ladder logic programs, and understand the blast furnace control process. The attacker also identifies tag names (process variables), setpoints, alarm limits, and the relationship between PLCs and the Safety Instrumented Systems.
# Simulated PLC reconnaissance (educational only)
# Attacker reads PLC configurations using legitimate engineering software
# Connect to PLC-BF-TEMP-01 via CIP (EtherNet/IP)
# Using RSLogix 5000 on the compromised engineering workstation
# PLC identity information:
{
"controller": "PLC-BF-TEMP-01",
"ip_address": "10.80.10.1",
"type": "1756-L83E/B ControlLogix 5580",
"firmware": "v33.011",
"serial": "SYNTH00001234",
"project_name": "BF1_TEMP_CTRL_R7",
"last_modified": "2025-11-15T14:30:00Z",
"key_switch": "REMOTE RUN",
"program_size": "245 KB"
}
# Read tag database (process variables):
TAG NAME TYPE VALUE DESCRIPTION
BF1_HotBlastTemp REAL 1180.5 Hot blast temperature (°C)
BF1_HotBlastTemp_SP REAL 1200.0 Hot blast setpoint (°C)
BF1_HotBlastTemp_HI REAL 1280.0 High alarm limit (°C)
BF1_HotBlastTemp_HIHI REAL 1350.0 High-high alarm (°C)
BF1_TopGasTemp REAL 245.3 Top gas temperature (°C)
BF1_TopGasTemp_HI REAL 320.0 Top gas high alarm (°C)
BF1_HearthTemp REAL 1520.4 Hearth temperature (°C)
BF1_HearthTemp_HIHI REAL 1650.0 Hearth high-high alarm (°C)
BF1_CoolWaterFlow REAL 2847.0 Cooling water flow (L/min)
BF1_CoolWaterFlow_LO REAL 2000.0 Low flow alarm (L/min)
BF1_SIS_TripEnabled BOOL 1 SIS trip function enabled
BF1_SIS_Status DINT 0 SIS status (0=normal)
BF1_EmergencyStop BOOL 0 Emergency stop status
# Ladder logic program structure:
# MainRoutine
# ├── Temperature_Control (PID loop for hot blast temp)
# ├── Gas_Flow_Control (gas flow regulation)
# ├── Cooling_Water_Monitor (cooling system interlock)
# ├── Alarm_Handler (process alarms to HMI)
# └── SIS_Interface (communication with Triconex SIS)
# The attacker now has complete understanding of:
# 1. Process control logic and setpoints
# 2. Alarm limits and safety trip points
# 3. Relationship between PLC and SIS
# 4. Tag names used for HMI display
Phase 4: PLC Firmware Manipulation¶
ATT&CK Technique: T1495 (Firmware Corruption), T0839 (Module Firmware — ICS)
FOUNDRY GHOST uploads modified firmware to two blast furnace temperature control PLCs. The modified firmware includes a rootkit-level capability that intercepts read requests from the HMI and engineering workstations, returning the original (expected) tag values while the actual process runs with modified setpoints. This is conceptually similar to how the Stuxnet attack reported process values back to operators while manipulating centrifuge speeds.
# Simulated PLC firmware manipulation (educational only)
# This demonstrates the CONCEPT of firmware-level attacks on PLCs
# No actual exploit code or working firmware is included
# FOUNDRY GHOST has developed custom firmware modifications
# for the ControlLogix 5580 platform (CONCEPTUAL ONLY)
# The modified firmware implements three capabilities:
# 1. Tag value interception: Returns expected values on read requests
# while actual process values differ
# 2. Logic injection: Adds hidden ladder logic rungs that execute
# alongside the legitimate program
# 3. Anti-forensics: Modified firmware reports original version
# string and checksum to engineering software
# Firmware upload process (CONCEPTUAL — not working code):
# Step 1: Put PLC in PROGRAM mode
# Step 2: Upload modified firmware via CIP protocol
# Step 3: Return PLC to RUN mode
# Simulated firmware upload log:
[2026-04-01 02:15:00] PLC-BF-TEMP-01 (10.80.10.1)
Action: Firmware upload initiated
Source: EWS-BF01 (10.80.2.10)
Protocol: CIP/EtherNet-IP
Original FW: v33.011
Modified FW: v33.011-GHOST (reports as v33.011)
Upload time: 47 seconds
PLC downtime: 52 seconds (PROGRAM mode)
Status: SUCCESS — PLC returned to RUN mode
[2026-04-01 02:16:30] PLC-BF-TEMP-02 (10.80.10.2)
Action: Firmware upload initiated
Source: EWS-BF01 (10.80.2.10)
Protocol: CIP/EtherNet-IP
Original FW: v33.011
Modified FW: v33.011-GHOST (reports as v33.011)
Upload time: 45 seconds
PLC downtime: 50 seconds (PROGRAM mode)
Status: SUCCESS — PLC returned to RUN mode
# The firmware upload occurs during the 2:00-3:00 AM maintenance
# window, when PLC mode changes are expected and less likely
# to trigger operator attention
# Anti-forensic capability:
# When engineering software queries the PLC firmware version:
> Read firmware version from PLC-BF-TEMP-01
Response: "v33.011" (SPOOFED — actual firmware is modified)
# When comparing PLC program to offline backup:
> Compare online program to backup
Response: "Programs match" (SPOOFED — comparison is intercepted)
Phase 5: Ladder Logic Injection — Process Manipulation¶
ATT&CK Technique: T0855 (Unauthorized Command Message — ICS)
FOUNDRY GHOST injects hidden ladder logic rungs into the blast furnace temperature control program. The injected logic gradually increases the hot blast temperature setpoint by 0.5°C every 30 minutes, eventually driving the furnace temperature above safe operating limits. The modification is designed to be slow enough to appear as normal process drift rather than an immediate step change that would trigger alarms.
# Simulated ladder logic injection (educational only)
# Attacker modifies process control logic to gradually increase temperature
# Normal Temperature_Control routine (simplified):
# Rung 1: PID_BF1_Temp
# Input: BF1_HotBlastTemp (process variable — actual temp)
# Setpoint: BF1_HotBlastTemp_SP (1200.0°C)
# Output: BF1_HotBlastValve (gas burner valve position)
# Tuning: Kp=2.5, Ki=0.8, Kd=0.1
# Injected ladder logic (CONCEPTUAL — educational only):
# Hidden Rung A: Slow Setpoint Ramp
# Timer: T_RAMP (30 minute interval)
# On timer done:
# BF1_HotBlastTemp_SP = BF1_HotBlastTemp_SP + 0.5
# Reset timer
# Condition: BF1_HotBlastTemp_SP < 1450.0 (stop at max target)
# Hidden Rung B: Alarm Suppression
# If BF1_HotBlastTemp > BF1_HotBlastTemp_HI:
# BF1_HotBlastTemp_HI = BF1_HotBlastTemp + 20.0
# (Move the alarm setpoint UP to prevent alarming)
# If BF1_HotBlastTemp > BF1_HotBlastTemp_HIHI:
# BF1_HotBlastTemp_HIHI = BF1_HotBlastTemp + 50.0
# (Move the safety trip point UP to prevent shutdown)
# Hidden Rung C: Tag Value Spoofing (to HMI)
# BF1_HotBlastTemp_DISPLAY = 1200.0 (constant — always shows normal)
# (HMI reads BF1_HotBlastTemp_DISPLAY instead of BF1_HotBlastTemp)
# (Actual temp is climbing while display shows constant 1200°C)
# Timeline of setpoint manipulation:
# T+0h (02:20): SP = 1200.0°C (normal)
# T+1h (03:20): SP = 1201.0°C (+1.0)
# T+2h (04:20): SP = 1202.0°C (+2.0)
# T+4h (06:20): SP = 1204.0°C (+4.0)
# T+8h (10:20): SP = 1208.0°C (+8.0)
# T+16h (18:20): SP = 1216.0°C (+16.0)
# T+24h (02:20): SP = 1224.0°C (+24.0)
# T+48h (02:20): SP = 1248.0°C (+48.0)
# T+72h (02:20): SP = 1272.0°C (+72.0) — APPROACHING DANGER ZONE
# The ramp rate of 0.5°C/30min = 1°C/hour
# This is slow enough to appear as normal furnace behavior
# Operators see 1200°C on HMI at all times (spoofed display)
# Alarm limits move up automatically (hidden rung B)
# Actual temperature is rising but all indicators show normal
Phase 6: Safety Instrumented System (SIS) Bypass¶
ATT&CK Technique: T0839 (Module Firmware — ICS)
The most critical phase of the attack targets the Triconex Safety Instrumented Systems. FOUNDRY GHOST modifies the SIS logic to raise the emergency shutdown trip point from 1350°C to 1600°C, effectively disabling the automatic safety shutdown that would normally prevent the blast furnace from reaching dangerous temperatures. The SIS modification requires a different attack path because Triconex controllers use a separate programming protocol and are isolated on their own network segment.
# Simulated SIS bypass (educational only)
# This demonstrates the CONCEPT of safety system manipulation
# Similar to TRITON/TRISIS attack methodology (2017)
# Triconex SIS configuration (synthetic):
{
"controller": "SIS-BF-01",
"ip_address": "10.80.20.1",
"type": "Tricon 3008 (Triple Modular Redundant)",
"firmware": "v10.5.0",
"program": "BF1_SAFETY_v2.1",
"key_switch": "REMOTE PROGRAM",
"safety_functions": [
{
"SIF": "SIF-001",
"description": "Blast Furnace Over-Temperature Shutdown",
"trip_point": "1350°C on BF1_HearthTemp",
"action": "Close gas supply, activate emergency cooling",
"SIL": "SIL-3",
"proof_test_interval": "12 months"
},
{
"SIF": "SIF-002",
"description": "Cooling Water Low-Flow Shutdown",
"trip_point": "1500 L/min on BF1_CoolWaterFlow",
"action": "Close gas supply, sound evacuation alarm",
"SIL": "SIL-3"
}
]
}
# FOUNDRY GHOST accesses the SIS from the compromised engineering WS
# The Triconex key switch is in REMOTE PROGRAM mode
# (a common finding — left in this position for maintenance convenience)
# SIS logic modification (CONCEPTUAL — educational only):
# Original SIF-001 logic:
# IF BF1_HearthTemp > 1350 THEN
# ACTIVATE emergency_gas_shutoff
# ACTIVATE emergency_cooling
# SET SIS_Trip_Active = TRUE
# Modified SIF-001 logic:
# IF BF1_HearthTemp > 1600 THEN ← TRIP POINT RAISED BY 250°C
# ACTIVATE emergency_gas_shutoff
# ACTIVATE emergency_cooling
# SET SIS_Trip_Active = TRUE
# The blast furnace can now reach 1600°C before safety shutdown
# This temperature could cause refractory damage and safety hazards
# Simulated SIS modification log:
[2026-04-01 02:25:00] SIS-BF-01 (10.80.20.1)
Action: Safety program download initiated
Source: EWS-BF01 (10.80.2.10)
Protocol: TSAA (TriStation Application Protocol)
Original program: BF1_SAFETY_v2.1
Modified program: BF1_SAFETY_v2.1-GHOST
Modification: SIF-001 trip point 1350→1600
Key switch state: REMOTE PROGRAM
Download time: 23 seconds
Status: SUCCESS — SIS in RUN with modified logic
# CRITICAL NOTE: In a real Triconex controller, the key switch
# should be in PROGRAM mode locally (physical key) for any
# program changes. REMOTE PROGRAM mode is a security risk.
# SIS controllers should NEVER have their key switch in
# REMOTE PROGRAM mode during normal operations.
Phase 7: HMI Spoofing — Operator Deception¶
ATT&CK Technique: T0855 (Unauthorized Command Message — ICS)
FOUNDRY GHOST completes the attack by ensuring HMI operators see normal process values even as the blast furnace temperature rises. The firmware-level tag interception (Phase 4) causes the HMI to display the spoofed temperature value (constant 1200°C) while the actual process temperature climbs. Additionally, the attacker modifies the historian data collection to record the spoofed values, preventing detection through trend analysis.
# Simulated HMI spoofing (educational only)
# Operators see normal values while actual process deviates
# HMI Display — What operators SEE (spoofed):
# ┌─────────────────────────────────────────────────┐
# │ BLAST FURNACE #1 — OVERVIEW │
# │ │
# │ Hot Blast Temperature: 1200.0°C [NORMAL] │
# │ Hot Blast Setpoint: 1200.0°C │
# │ Hearth Temperature: 1520.4°C [NORMAL] │
# │ Top Gas Temperature: 245.3°C [NORMAL] │
# │ Cooling Water Flow: 2847 L/min [NORMAL] │
# │ │
# │ SIS Status: NORMAL (green) │
# │ Active Alarms: 0 │
# │ Last Maintenance: 2026-03-15 │
# │ │
# │ ▀▀▀▀▀▀▀▀▀▀ Trend: Stable (24h) ▀▀▀▀▀▀▀▀▀▀ │
# └─────────────────────────────────────────────────┘
# HMI Display — What is ACTUALLY happening:
# ┌─────────────────────────────────────────────────┐
# │ BLAST FURNACE #1 — ACTUAL STATE │
# │ │
# │ Hot Blast Temperature: 1248.0°C [RISING!] │
# │ Hot Blast Setpoint: 1248.0°C [MODIFIED!] │
# │ Hearth Temperature: 1572.8°C [RISING!] │
# │ Top Gas Temperature: 287.1°C [ELEVATED] │
# │ Cooling Water Flow: 2847 L/min [NORMAL] │
# │ │
# │ SIS Status: MODIFIED (trip=1600°C) │
# │ Active Alarms: SUPPRESSED (hidden) │
# │ ACTUAL CONDITION: DANGEROUS │
# └─────────────────────────────────────────────────┘
# The historian also records spoofed values:
# PI Historian tag: BF1.HotBlastTemp
# Recorded values (last 48 hours): flat line at ~1200°C ± 2
# Actual values (from independent sensor): rising trend 1200→1248°C
# The deception holds because:
# 1. PLC firmware intercepts tag reads → returns spoofed values
# 2. HMI reads tags via CIP protocol → gets spoofed values
# 3. Historian collects via OPC UA → gets spoofed values
# 4. Alarm limits moved up dynamically → no alarm triggers
# 5. SIS trip point raised → no automatic shutdown
# Independent verification methods that WOULD detect the anomaly:
# - Physical temperature measurement (handheld pyrometer)
# - Independent safety sensors not connected to compromised PLC
# - Comparison of PLC output with independent sensor readings
# - Electrical power consumption analysis (higher temp = more gas)
# - Manual reading of PLC tag values directly via engineering SW
# (firmware intercepts standard reads, but deep memory dump reveals truth)
Phase 8: Detection & Response¶
The attack is detected through multiple channels, with physical process observation providing the first indicators:
Channel 1 (T+60 hours): Physical Observation — A furnace operator on the night shift notices that the blast furnace stoves show higher-than-normal skin temperature on the infrared camera, inconsistent with the 1200°C displayed on the HMI. The operator reports the discrepancy to the shift supervisor.
Channel 2 (T+64 hours): OT Network Monitoring — The passive OT network monitoring tool detects anomalous CIP traffic patterns. The firmware upload events from Phase 4 generated CIP packets with unusual service codes that differ from normal engineering operations. The monitoring tool had flagged these 64 hours earlier, but the alert was classified as low priority.
Channel 3 (T+68 hours): Gas Consumption Anomaly — The energy management system reports that natural gas consumption for Blast Furnace #1 has increased 18% over the last 48 hours without a corresponding increase in production output. The maintenance team opens an investigation.
Channel 4 (T+72 hours): Independent Safety Audit — The shift supervisor orders a manual verification using a portable pyrometer, which reads 1268°C on the hot blast — 68°C above the displayed value. This triggers an immediate emergency shutdown.
# Simulated detection timeline (educational only)
[2026-04-04 02:00:00 UTC] PHYSICAL OBSERVATION — THERMAL ANOMALY
Alert: OPERATOR_REPORT_THERMAL_DISCREPANCY
Details:
- Equipment: Blast Furnace #1
- Observation: Stove skin temperature elevated on IR camera
- HMI display: 1200°C (normal)
- IR camera: skin temp consistent with ~1260°C internal
- Reporter: Night shift furnace operator
Severity: MEDIUM (initially — thermal cameras are estimates)
Action: Shift supervisor notified, monitoring increased
[2026-04-04 06:00:00 UTC] OT NETWORK MONITORING — CIP ANOMALY (RETROACTIVE)
Alert: ANOMALOUS_CIP_SERVICE_CODES (originally flagged 64h earlier)
Details:
- Source: 10.80.2.10 (EWS-BF01)
- Destination: 10.80.10.1, 10.80.10.2 (BF Temperature PLCs)
- Service codes: 0x52 (Firmware Upload), 0x4B (Program Download)
- Timestamp: 2026-04-01 02:15:00-02:20:00 (maintenance window)
- TSAA traffic to 10.80.20.1 (SIS-BF-01) — CRITICAL
- Original priority: LOW (maintenance window expected activity)
Severity: CRITICAL (upon re-examination)
Action: Full OT forensic investigation initiated
[2026-04-04 10:00:00 UTC] ENERGY MANAGEMENT — GAS CONSUMPTION ANOMALY
Alert: BF1_GAS_CONSUMPTION_DEVIATION
Details:
- Equipment: Blast Furnace #1
- Gas consumption increase: +18% over 48 hours
- Production output: no corresponding increase
- Energy efficiency: declining trend
- Possible causes: process deviation, sensor error, or manipulation
Severity: MEDIUM
Action: Maintenance investigation opened
[2026-04-04 14:00:00 UTC] MANUAL VERIFICATION — TEMPERATURE DISCREPANCY
Alert: EMERGENCY_MANUAL_VERIFICATION
Details:
- Portable pyrometer reading: 1268°C (hot blast)
- HMI displayed value: 1200°C
- Delta: +68°C — CONFIRMED DISCREPANCY
- SIS trip point (should be): 1350°C
- Current temperature trajectory: +1°C/hour
- Time to original SIS trip: ~82 hours at current rate
- Time to modified SIS trip: ~332 hours at current rate
Severity: CRITICAL
Action: EMERGENCY SHUTDOWN INITIATED
Detection Queries:
// KQL — Detect PLC firmware upload events via OT network monitoring
OTNetworkTraffic
| where TimeGenerated > ago(7d)
| where Protocol == "CIP" or Protocol == "EtherNet/IP"
| where CIPServiceCode in (0x52, 0x53, 0x4B) // Firmware Upload, Program Download
| extend SourceDevice = tostring(parse_json(SourceContext).hostname)
| extend DestDevice = tostring(parse_json(DestContext).hostname)
| extend DestIP = DestinationIP
| where DestIP startswith "10.80.10." or DestIP startswith "10.80.20."
| project TimeGenerated, SourceIP, SourceDevice, DestIP, DestDevice,
CIPServiceCode, Protocol, PacketSize
// KQL — Detect SIS program modification via TSAA protocol
OTNetworkTraffic
| where TimeGenerated > ago(7d)
| where Protocol == "TSAA" or DestinationPort == 2222
| extend SourceDevice = tostring(parse_json(SourceContext).hostname)
| extend DestDevice = tostring(parse_json(DestContext).hostname)
| where DestinationIP startswith "10.80.20."
| summarize EventCount = count(),
TotalBytes = sum(PacketSize),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by SourceIP, DestinationIP, SourceDevice, DestDevice
| where EventCount > 5 or TotalBytes > 100000
| project SourceIP, DestinationIP, SourceDevice, DestDevice,
EventCount, TotalBytes, FirstSeen, LastSeen
// KQL — Detect engineering workstation anomalous outbound connections
OTNetworkTraffic
| where TimeGenerated > ago(7d)
| where SourceIP startswith "10.80.2." // Engineering workstations
| where not(DestinationIP startswith "10.80.") // External traffic
| where DestinationPort in (443, 80, 8080, 4443)
| extend DestGeoInfo = geo_info_from_ip_address(DestinationIP)
| summarize ConnectionCount = count(),
UniqueDestIPs = dcount(DestinationIP),
Destinations = make_set(DestinationIP),
TotalBytes = sum(PacketSize)
by SourceIP, bin(TimeGenerated, 1h)
| where ConnectionCount > 10 or UniqueDestIPs > 3
| project TimeGenerated, SourceIP, ConnectionCount, UniqueDestIPs,
Destinations, TotalBytes
// KQL — Detect process value deviation between historian and independent sensors
ProcessHistorianData
| where TimeGenerated > ago(7d)
| where TagName == "BF1.HotBlastTemp"
| extend HistorianValue = todouble(Value)
| join kind=inner (
IndependentSensorData
| where TimeGenerated > ago(7d)
| where SensorId == "BF1-TEMP-INDEPENDENT"
| extend IndependentValue = todouble(Value)
) on $left.TimeGenerated == $right.TimeGenerated
| extend Deviation = abs(HistorianValue - IndependentValue)
| where Deviation > 5.0 // More than 5°C difference
| project TimeGenerated, HistorianValue, IndependentValue, Deviation
# SPL — Detect PLC firmware upload events via OT network monitoring
index=ot_network sourcetype=ot:cip
(cip_service_code=0x52 OR cip_service_code=0x53 OR cip_service_code=0x4B)
| spath output=src_device path=source_context.hostname
| spath output=dst_device path=dest_context.hostname
| where match(dest_ip, "^10\.80\.(10|20)\.")
| table _time, src_ip, src_device, dest_ip, dst_device,
cip_service_code, protocol, packet_size
# SPL — Detect SIS program modification via TSAA protocol
index=ot_network sourcetype=ot:network
(protocol="TSAA" OR dest_port=2222)
| where match(dest_ip, "^10\.80\.20\.")
| spath output=src_device path=source_context.hostname
| spath output=dst_device path=dest_context.hostname
| stats count as event_count,
sum(packet_size) as total_bytes,
min(_time) as first_seen,
max(_time) as last_seen
by src_ip, dest_ip, src_device, dst_device
| where event_count > 5 OR total_bytes > 100000
| table src_ip, dest_ip, src_device, dst_device,
event_count, total_bytes, first_seen, last_seen
# SPL — Detect engineering workstation anomalous outbound connections
index=ot_network sourcetype=ot:network
src_ip="10.80.2.*" NOT dest_ip="10.80.*"
dest_port IN (443, 80, 8080, 4443)
| bin _time span=1h
| stats count as connection_count,
dc(dest_ip) as unique_dest_ips,
values(dest_ip) as destinations,
sum(packet_size) as total_bytes
by src_ip, _time
| where connection_count > 10 OR unique_dest_ips > 3
| table _time, src_ip, connection_count, unique_dest_ips,
destinations, total_bytes
# SPL — Detect process value deviation (historian vs independent sensor)
index=process_historian tag_name="BF1.HotBlastTemp"
| rename value as historian_value
| join _time [
search index=independent_sensors sensor_id="BF1-TEMP-INDEPENDENT"
| rename value as independent_value
]
| eval deviation = abs(historian_value - independent_value)
| where deviation > 5.0
| table _time, historian_value, independent_value, deviation
Incident Response:
# Simulated incident response (educational only)
[2026-04-04 14:15:00 UTC] ALERT: Industrial PLC Attack incident response activated
[2026-04-04 14:15:00 UTC] ACTION: Emergency process shutdown
- Blast Furnace #1 EMERGENCY SHUTDOWN initiated (manual)
- Gas supply CLOSED via manual isolation valves
- Emergency cooling system ACTIVATED
- All personnel EVACUATED from blast furnace area
- Physical safety systems (hardwired interlocks) VERIFIED operational
[2026-04-04 14:30:00 UTC] ACTION: OT network isolation
- Engineering workstation EWS-BF01 DISCONNECTED from network
- ALL engineering workstation internet access DISABLED at firewall
- Level 2 to Level 1 traffic BLOCKED (emergency firewall rules)
- Remote access tool UNINSTALLED from all engineering workstations
- OT DMZ firewall rules tightened: deny all non-essential traffic
[2026-04-04 15:00:00 UTC] ACTION: PLC and SIS recovery
- PLC-BF-TEMP-01 and PLC-BF-TEMP-02: FIRMWARE RELOADED from
verified golden image (offline USB, verified checksum)
- PLC programs RESTORED from offline backup (verified March 2025)
- SIS-BF-01: Safety program RESTORED from verified backup
- SIS key switch CHANGED to LOCAL PROGRAM (physical key secured)
- All 48 PLCs AUDITED: firmware checksums compared to golden images
- All 6 SIS controllers AUDITED: programs compared to validated backups
[2026-04-04 16:00:00 UTC] ACTION: Credential and access remediation
- All OT domain passwords RESET
- Third-party remote access tool REMOVED permanently
- VPN-based vendor access implemented (with MFA and session recording)
- Engineering workstation forensic images PRESERVED
[2026-04-04 18:00:00 UTC] ACTION: Impact assessment
PLCs with modified firmware: 2 (BF temperature controllers)
PLCs with injected ladder logic: 2 (same controllers)
SIS controllers with modified logic: 1 (BF safety system)
HMI operators deceived: All operators for 72 hours
Actual temperature deviation: +68°C above displayed value
Maximum temperature reached: 1268°C (safe limit: 1350°C)
Safety margin remaining: 82°C (without SIS modification: would have tripped)
Physical damage: None (detected before critical threshold)
Production impact: 5-day shutdown for full OT security audit
Dwell time: 72 hours (firmware upload to detection)
Root cause: Supply chain compromise + engineering WS internet access
Contributing factors: SIS key switch in REMOTE PROGRAM, no firmware
integrity monitoring, no independent process verification
Decision Points (Tabletop Exercise)¶
Decision Point 1 — OT Network Segmentation
Your engineering workstations have direct internet access for vendor support and software updates. How do you balance the operational need for vendor remote access with the risk of supply chain compromise? What architecture changes (jump servers, air-gapped update processes, vendor VPN) would mitigate this risk?
Decision Point 2 — Safety System Security
Your Triconex SIS controllers have their key switches in REMOTE PROGRAM mode for maintenance convenience. What is the operational impact of switching to LOCAL PROGRAM mode? How do you implement a key management process that balances maintenance needs with safety system integrity?
Decision Point 3 — Process Value Verification
The attacker spoofed HMI displays to hide the temperature manipulation. How do you implement independent verification of critical process values? What role do independent sensors, manual measurements, and cross-checks between related process variables play in detecting spoofed data?
Decision Point 4 — OT Incident Response
During the incident, you must decide between continuing production (to prevent economic loss from furnace shutdown) and performing an emergency shutdown (to prevent potential safety incidents). What criteria determine when to shut down? Who has the authority to make this decision, and what is the communication chain?
Lessons Learned¶
Key Takeaways
-
Engineering workstation internet access is a critical OT attack vector — Engineering workstations with direct internet access bypass all Purdue Model segmentation benefits. Supply chain compromises, watering hole attacks, and direct exploitation can pivot from internet to Level 2 with full PLC programming capability. All internet access for OT workstations should be through isolated, monitored jump servers.
-
Safety Instrumented Systems require physical key security — SIS controllers with key switches in REMOTE PROGRAM mode can be reprogrammed from the network, negating their safety function. SIS key switches should be in RUN or LOCAL PROGRAM mode during normal operations, with physical key custody procedures matching the SIL rating of the safety functions they protect.
-
PLC firmware integrity monitoring is essential — Modern PLCs can have their firmware modified to intercept tag reads and hide process manipulation. Organizations must implement firmware integrity monitoring through periodic offline verification against golden images, ideally using independent verification tools not installed on potentially compromised engineering workstations.
-
Independent process verification defeats HMI spoofing — When an attacker controls the PLC, all data flowing through it (to HMIs, historians, and SCADA) is potentially compromised. Independent sensors on separate controllers, manual field measurements, and cross-correlation of related process variables (temperature vs. gas consumption vs. electrical load) provide detection capability that cannot be spoofed through a single point of compromise.
-
OT network monitoring must understand industrial protocols — Generic network monitoring tools may not decode CIP, TSAA, Modbus, or OPC UA traffic at the application layer. OT-specific network monitoring that understands industrial protocol semantics can detect firmware uploads, program downloads, and anomalous command patterns that generic tools miss.
-
Slow process manipulation evades alarm-based detection — A gradual 0.5°C/30min ramp appears as normal process drift, not an alarm condition. OT security must include rate-of-change monitoring and cumulative deviation tracking in addition to static alarm thresholds. If a setpoint has drifted 48°C over 48 hours, something is wrong even if no individual change triggered an alarm.
MITRE ATT&CK / ICS Mapping¶
| Technique ID | Technique Name | Phase |
|---|---|---|
| T1195.002 | Supply Chain Compromise: Software Supply Chain | Initial Access |
| T1021 | Remote Services | Lateral Movement (IT-to-OT pivot) |
| T1495 | Firmware Corruption | Execution (PLC firmware modification) |
| T0839 | Module Firmware (ICS) | Persistence (firmware-level rootkit) |
| T0855 | Unauthorized Command Message (ICS) | Impact (ladder logic + SIS modification) |
| T0856 | Modify Reporting Settings (ICS) | Defense Evasion (HMI spoofing) |