# Implementing Ot Incident Response Playbook

> 按照SANS PICERL框架、IEC 62443和NIST SP 800-82，开发并实施OT专用事件响应剧本，解决包括安全关键系统、有限停机容忍度以及IT SOC、OT工程和工厂运营团队协调等ICS特有挑战。

- Skill: `killvxk/implementing-ot-incident-response-playbook` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add killvxk/implementing-ot-incident-response-playbook`
- Raw SKILL.md: https://api.skillmd.com/api/skills/killvxk/implementing-ot-incident-response-playbook/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Coding & Dev Tools
- License: Apache-2.0
- Author: killvxk (https://skillmd.com/u/killvxk)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/killvxk/implementing-ot-incident-response-playbook

---


# 实施OT事件响应剧本

## 适用场景

- 首次为OT构建专用事件响应程序
- 现有IT IR剧本未涵盖ICS/SCADA特定要求
- 准备应对EKANS或LockerGoga等OT勒索软件场景
- 将IR程序与IEC 62443和NERC CIP事件报告要求对齐
- 进行事件后审查以提升OT IR能力

**不适用于**无OT组件的纯IT事件响应（使用标准NIST 800-61剧本）、日常OT安全监控（参见implementing-dragos-platform-for-ot-monitoring），或桌面推演设计（参见performing-ics-tabletop-exercise）。

## 前置条件

- 带关键性评级和安全系统识别的OT资产清单
- 已定义的角色：OT IR负责人、IT SOC分析师、工厂运营经理、过程安全工程师
- 通信计划，包括带外通道（OT事件可能影响IT通信）
- PLC程序、HMI配置和历史数据的已知良好备份
- ICS供应商、Dragos/Claroty支持和CISA ICS-CERT的联系信息

## 工作流程

### 步骤 1：定义OT特定事件分类和响应程序

```python
#!/usr/bin/env python3
"""OT事件响应剧本引擎。

按照SANS PICERL生命周期，针对安全性、
可用性和跨团队协调的ICS特定考虑因素，
实施结构化的OT事件响应程序。
"""

import json
import sys
from datetime import datetime
from enum import Enum
from typing import Dict, List, Optional


class OTIncidentSeverity(Enum):
    SEV1_SAFETY = "SEV1-SAFETY"  # 安全系统受损
    SEV2_PROCESS = "SEV2-PROCESS"  # 主动过程操控
    SEV3_ACCESS = "SEV3-ACCESS"  # 未授权OT访问
    SEV4_RECON = "SEV4-RECON"  # OT网络侦察
    SEV5_IT_SPILLOVER = "SEV5-IT-SPILLOVER"  # 有OT暴露的IT事件


class OTIncidentCategory(Enum):
    RANSOMWARE = "ransomware"
    MALWARE_ICS = "malware_ics_specific"
    UNAUTHORIZED_ACCESS = "unauthorized_ot_access"
    PROCESS_MANIPULATION = "process_manipulation"
    SIS_COMPROMISE = "safety_system_compromise"
    DATA_EXFILTRATION = "ot_data_exfiltration"
    SUPPLY_CHAIN = "supply_chain_compromise"
    INSIDER_THREAT = "insider_threat"


# OT的PICERL阶段定义
PICERL_PHASES = {
    "preparation": {
        "description": "事件发生前的准备工作",
        "ot_specific": [
            "维护所有PLC程序和HMI配置的离线备份",
            "记录每个过程区域的安全关闭程序",
            "建立带外通信（卫星电话、模拟无线电）",
            "预置适用于气隙OT网络的取证工具",
            "维护备用PLC和工程师工作站",
            "每季度进行OT桌面推演",
        ],
    },
    "identification": {
        "description": "检测并确认OT安全事件",
        "ot_specific": [
            "将OT IDS告警与历史数据中的过程异常相关联",
            "验证过程偏差是由网络攻击还是操作原因引起",
            "检查安全仪表系统（SIS）状态和完整性",
            "审查工程师工作站日志中的未授权访问",
            "检查PLC模式变化（RUN/STOP/PROGRAM转换）",
            "评估事件是否仅限于IT或已蔓延到OT",
        ],
    },
    "containment": {
        "description": "限制事件的蔓延和影响",
        "ot_specific": [
            "未经工厂运营批准，绝不关闭OT系统",
            "在工业防火墙处隔离受影响网段（而非断电）",
            "如怀疑远程操控，将PLC切换到本地/手动模式",
            "在维持OT内部通信的同时断开DMZ处的IT-OT管道",
            "在任何修复操作之前保留取证证据",
            "在整个遏制过程中维持安全系统运行",
        ],
    },
    "eradication": {
        "description": "从OT系统中清除威胁",
        "ot_specific": [
            "将运行中的PLC程序与已知良好备份进行比较",
            "从黄金镜像重建被攻陷的工程师工作站",
            "验证历史数据完整性以发现操控证据",
            "检查OT特定位置的持久化机制（HMI上的启动脚本、计划任务）",
            "验证PLC和RTU上的固件完整性",
            "如需根套件级别修复，与ICS供应商协调",
        ],
    },
    "recovery": {
        "description": "将OT运营恢复正常",
        "ot_specific": [
            "从经验证的离线备份恢复PLC程序",
            "在工程监督下分阶段重启过程",
            "在重启期间密切监控过程变量异常",
            "在恢复自动操作前验证安全系统功能",
            "仅在OT经验证清洁后重新启用IT-OT连接",
            "记录事件期间任何过程变量漂移",
        ],
    },
    "lessons_learned": {
        "description": "事件后审查和改进",
        "ot_specific": [
            "在2周内进行IT/OT联合事件后审查",
            "根据观察到的攻击技术更新检测规则",
            "如果横向移动成功，修订网络分段",
            "根据实际恢复时间更新PLC备份计划",
            "按要求向CISA ICS-CERT和行业ISAC报告",
            "在90天内测试更新后的剧本",
        ],
    },
}


class OTIncident:
    """表示一个活跃的OT安全事件。"""

    def __init__(self, title: str, severity: OTIncidentSeverity,
                 category: OTIncidentCategory, affected_systems: List[str]):
        self.id = f"OT-IR-{datetime.now().strftime('%Y%m%d-%H%M%S')}"
        self.title = title
        self.severity = severity
        self.category = category
        self.affected_systems = affected_systems
        self.created = datetime.now().isoformat()
        self.current_phase = "identification"
        self.timeline = []
        self.decisions = []
        self.containment_actions = []

    def log_event(self, phase: str, action: str, actor: str, notes: str = ""):
        """记录一个事件响应操作。"""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "phase": phase,
            "action": action,
            "actor": actor,
            "notes": notes,
        }
        self.timeline.append(entry)
        return entry

    def log_decision(self, decision: str, rationale: str, approved_by: str):
        """记录事件响应期间的关键决策。"""
        entry = {
            "timestamp": datetime.now().isoformat(),
            "decision": decision,
            "rationale": rationale,
            "approved_by": approved_by,
        }
        self.decisions.append(entry)
        return entry


class OTPlaybookEngine:
    """执行OT事件响应剧本。"""

    def __init__(self):
        self.playbooks = self._build_playbooks()

    def _build_playbooks(self) -> Dict:
        """构建特定类别的OT IR剧本。"""
        return {
            OTIncidentCategory.RANSOMWARE: {
                "name": "OT勒索软件响应",
                "reference": "SANS ICS勒索软件防御剧本",
                "immediate_actions": [
                    "未经管理层和法务批准，不得支付赎金",
                    "立即在DMZ防火墙处断开IT-OT管道",
                    "验证SIS/安全系统是否独立运行",
                    "将关键过程切换到手动/本地控制",
                    "保留勒索信和加密文件样本用于取证",
                    "评估勒索软件是否已到达2级或以下",
                ],
                "containment_steps": [
                    "通过禁用OT主机之间的SMB/RDP阻止横向移动",
                    "在维持关键过程通信的同时隔离受影响的VLAN",
                    "禁用OT环境的远程访问VPN",
                    "检查备份基础设施是否完好（勒索软件针对备份）",
                    "清点哪些OT系统被加密，哪些仍可运行",
                ],
                "recovery_priority": [
                    "1. 安全仪表系统（SIS）",
                    "2. 关键过程控制器（连续过程中的PLC）",
                    "3. 供操作员查看的HMI",
                    "4. 数据连续性历史服务器",
                    "5. 工程师工作站",
                    "6. IT-OT连接（最后）",
                ],
                "reporting": [
                    "CISA：按CIRCIA要求在72小时内报告",
                    "行业ISAC：在24小时内共享IOC",
                    "NERC（如适用）：对BES影响在1小时内报告",
                ],
            },
            OTIncidentCategory.SIS_COMPROMISE: {
                "name": "安全系统受损响应",
                "reference": "TRITON/TRISIS事件经验教训",
                "immediate_actions": [
                    "立即通知过程安全团队",
                    "验证物理安全装置功能正常（泄压阀、防爆片）",
                    "如SIS完整性不确定，考虑受控过程关闭",
                    "将SIS网络与所有其他网络隔离",
                    "检查SIS是否处于旁路模式或已被解除武装",
                    "联系SIS供应商紧急支持（Schneider Triconex、HIMA等）",
                ],
                "containment_steps": [
                    "将SIS工程师工作站从网络物理断开",
                    "采集SIS工程师工作站的取证镜像",
                    "根据出厂基线验证SIS控制器固件和逻辑",
                    "检查是否有未授权的TriStation/安全协议连接",
                    "检查所有工程师工作站的TRITON指标",
                ],
                "recovery_priority": [
                    "1. 验证所有物理安全屏障完好",
                    "2. 从离线备份（与供应商基线对比验证）重载SIS逻辑",
                    "3. 重新投用前进行完整的SIS验证测试",
                    "4. 由过程安全工程师进行独立验证",
                ],
                "reporting": [
                    "CISA ICS-CERT：针对SIS攻击立即通知",
                    "过程安全监管机构（OSHA、HSE）：按司法管辖区要求",
                    "SIS供应商：联系进行根本原因分析",
                ],
            },
        }

    def execute_playbook(self, incident: OTIncident):
        """为事件执行适当的剧本。"""
        playbook = self.playbooks.get(incident.category)
        if not playbook:
            print(f"[!] 没有针对 {incident.category.value} 的特定剧本。使用通用OT IR程序。")
            return

        print(f"\n{'='*70}")
        print(f"OT事件响应剧本已激活")
        print(f"{'='*70}")
        print(f"事件ID: {incident.id}")
        print(f"标题: {incident.title}")
        print(f"严重程度: {incident.severity.value}")
        print(f"类别: {incident.category.value}")
        print(f"剧本: {playbook['name']}")
        print(f"参考: {playbook['reference']}")
        print(f"激活时间: {incident.created}")
        print(f"受影响系统: {', '.join(incident.affected_systems)}")

        print(f"\n--- 即时行动（在前15分钟内执行）---")
        for i, action in enumerate(playbook["immediate_actions"], 1):
            print(f"  {i}. {action}")

        print(f"\n--- 遏制步骤 ---")
        for i, step in enumerate(playbook["containment_steps"], 1):
            print(f"  {i}. {step}")

        print(f"\n--- 恢复优先级顺序 ---")
        for item in playbook["recovery_priority"]:
            print(f"  {item}")

        print(f"\n--- 报告要求 ---")
        for req in playbook["reporting"]:
            print(f"  - {req}")

        # 打印PICERL阶段指引
        print(f"\n--- PICERL阶段检查清单 ---")
        for phase, info in PICERL_PHASES.items():
            print(f"\n  [{phase.upper()}] {info['description']}")
            for item in info["ot_specific"][:3]:
                print(f"    - {item}")


if __name__ == "__main__":
    engine = OTPlaybookEngine()

    # 示例：OT勒索软件事件
    incident = OTIncident(
        title="在3级历史服务器上检测到勒索软件",
        severity=OTIncidentSeverity.SEV2_PROCESS,
        category=OTIncidentCategory.RANSOMWARE,
        affected_systems=["HIST-01", "HIST-02", "ENG-WS-03", "HMI-AREA1"],
    )

    engine.execute_playbook(incident)
```

## 核心概念

| 术语 | 定义 |
|------|------|
| PICERL | SANS事件响应生命周期：准备（Preparation）、识别（Identification）、遏制（Containment）、清除（Eradication）、恢复（Recovery）、经验教训（Lessons Learned） |
| ICS4ICS | 工业控制系统事件指挥系统 - 将FEMA ICS适配到OT网络安全响应 |
| 安全仪表系统（SIS） | 防止危险条件的独立安全控制器；SIS被攻陷可能造成人身伤害 |
| 手动/本地模式（Manual/Local Mode） | 使用本地面板控制操作PLC而非远程SCADA；当远程访问被攻陷时使用 |
| CIRCIA | 关键基础设施网络事件报告法案，要求在72小时内向CISA报告 |
| 已知良好备份（Known-Good Backup） | 经验证的PLC程序和配置离线副本，用作恢复的可信基线 |

## 常见场景

### 场景：勒索软件从IT蔓延到OT 3级

**背景**：勒索软件加密企业IT系统，并通过防护不足的IT/OT管道蔓延到3级历史服务器。2级HMI开始显示连接错误。

**处理方法**：
1. 立即激活勒索软件OT IR剧本
2. 在DMZ防火墙处断开IT-OT连接（南北两侧防火墙）
3. 验证PLC仍在运行且过程稳定（PLC独立于IT运行）
4. 如果网络化HMI受影响，将操作员切换到本地HMI面板
5. 评估哪些2/3级系统被加密，哪些仍可运行
6. 优先恢复HMI可见性，然后是历史服务器，再是工程师工作站
7. 从离线备份恢复 — 未经沙箱测试，切勿尝试使用攻击者提供的工具解密
8. 按CIRCIA要求在72小时内向CISA报告

**注意事项**：不要关闭PLC来"保护"它们免受勒索软件影响 — PLC运行固件而非Windows，通常不受勒索软件影响。关闭PLC会中断物理过程。在IT侧完全修复之前，切勿重新连接IT-OT管道。

## 输出格式

```
OT事件响应报告
==============================
事件ID: OT-IR-YYYYMMDD-HHMMSS
严重程度: SEV[1-5]
类别: [类别]
状态: [活跃/已遏制/已清除/已恢复/已关闭]

时间线:
  [时间戳] - [阶段] - [操作] - [执行人]

受影响系统:
  安全系统: [状态]
  过程控制器: [状态]
  HMI/SCADA: [状态]
  历史服务器: [状态]

决策日志:
  [时间戳] - [决策] - [理由] - [批准人]

已采取的遏制措施:
  1. [操作和时间戳]

恢复状态:
  [系统] - [已恢复/待恢复] - [预计完成时间]
```

