Namanbhatt-01/ics-defensive-parser

GitHub: Namanbhatt-01/ics-defensive-parser

一个被动式的多协议 ICS/SCADA 网络日志合规审计引擎,通过离线解析工业遥测日志检测运营异常并映射至 NCIIPC 合规框架。

Stars: 0 | Forks: 0

# 多协议 ICS/SCADA 网络合规性审计器 一个模块化、轻量级、被动的安全合规性审计引擎,旨在分析 Modbus TCP、DNP3、Siemens S7Comm 和 IEC 60870-5-104 (IEC 104) 网络遥测日志,用于运营异常检测以及在 NCIIPC 指南下的监管合规性。 [![CI 构建与测试状态](https://static.pigsec.cn/wp-content/uploads/repos/2026/06/6aa3461505162907.svg)](https://github.com/Namanbhatt-01/ics-defensive-parser/actions) [![代码覆盖率](https://img.shields.io/badge/coverage-88%25-green.svg)](https://codecov.io/gh/Namanbhatt-01/ics-defensive-parser) [![MIT 许可证](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![安全政策](https://img.shields.io/badge/Security-Policy-brightgreen.svg)](SECURITY.md) ## 📌 项目概述 关键信息基础设施(CII)资产(如电网、水处理厂、电信网络和制造工厂)依赖于旧版的运营技术(OT)协议。由于传统的工业协议缺乏原生的安全特性(如加密或访问控制),因此对其遥测数据进行审计至关重要。 本项目是一个**被动式多协议 ICS 日志审计器**,旨在解析存储的网络事务日志,并根据可配置的合规性基准定义(`rules.json`)对它们进行审计。它会标记未授权的操作——例如来自未授权源 IP 地址的远程状态修改(Write 命令)、格式错误的协议头或越界的功能码——并将它们直接映射到**国家关键信息基础设施保护中心(NCIIPC)**的合规指南。 ### 核心功能 * 🛡️ **零网络入侵:** 完全被动的离线解析,没有破坏精密的 PLC/RTU 硬件的风险。 * ⚡ **四协议支持:** 集成对 **Modbus TCP**、**DNP3**、**Siemens S7comm** 和 **IEC 104** 的支持。 * 🛡️ **深度头部与地址异常解析:** * 检查 DNP3 起始字节同步头(`0x0564`)。 * 检查 IEC 104 APCI 起始字节同步头(`0x68`)。 * 标记指向网络广播地址端点(`255.255.255.255`)的控制命令。 * 强制执行 DNP3 功能码范围界限验证($0 \le \text{FC} \le 131$)。 * 📋 **合规性映射:** 将记录的异常直接与 NCIIPC 指南对齐(例如,访问控制、审计日志、协议验证、固件完整性)。 * ⚙️ **可配置的基准:** 声明式规则 schema 允许安全运维人员轻松定义授权的工程工作站。 * 📊 **审计轨迹生成:** 创建清晰、易读的文本日志,捕获 payload 签名、严重性级别和威胁解决状态。 ## 📁 仓库结构 ``` ics-defensive-parser/ ├── .github/ │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ └── feature_request.md │ └── workflows/ │ ├── test.yml │ └── dependabot.yml ├── ics_defensive_parser/ ← Core engine package │ ├── __init__.py │ ├── main.py ← Entry point / audit engine │ ├── utils.py ← Input validation helpers │ └── parsers/ │ ├── __init__.py │ ├── dnp3_parser.py │ ├── iec104_parser.py │ ├── modbus_parser.py │ └── s7_parser.py ├── data/ ← Configuration & mock data │ ├── mock_logs.json │ └── rules.json ├── tests/ ← Automated zone-based test suite │ ├── __init__.py │ └── run_compliance_tests.py ├── .gitignore ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Dockerfile ← Docker build context at repo root ├── LICENSE ├── Makefile ├── README.md ← This file ├── requirements.txt └── SECURITY.md ``` ## 📊 性能指标与基准测试 经过优化,以最低的内存开销解析和过滤工业数据包日志: * **吞吐量:** 在标准的单核执行块上每秒处理约 **75,000 个日志帧**。 * **测试环境:** 基准测试是在运行 Ubuntu 22.04 LTS 的 **Intel Xeon E-2288G CPU (3.70GHz, 8 核 / 16 线程) 及 32 GB DDR4 内存**环境下生成的。 * **复杂度:** $\mathcal{O}(N)$ 的解析时间和 $\mathcal{O}(1)$ 的静态内存分配,确保在低功耗的运营网关中的适用性。 ## 🗺️ 系统架构 ``` graph TD A[mock_logs.json] --> B[main.py Engine] C[rules.json Baseline] --> B B --> D{Protocol Router} D -- ModbusTCP --> E[parsers/modbus_parser.py] D -- DNP3 --> F[parsers/dnp3_parser.py] D -- S7Comm --> G[parsers/s7_parser.py] D -- IEC104 --> H[parsers/iec104_parser.py] E & F & G & H --> I[Input Validation & Regex Sanity] I --> J{Policy Decision Engine} J -- Violation Found --> K[Console CLI Alert] J -- Violation Found --> L[audit_report.txt Ledger] J -- Normal Transaction --> M[Allowed Log Event] ``` ## 📋 配置和日志格式示例 ### 1. 合规性基准定义(`rules.json`) 声明式配置定义了授权的工程工作站 IP,并将协议码映射到 NCIIPC 章节: ``` { "authorized_engineering_workstations": [ "192.168.1.50" ], "Modbus": { "allowed_read_function_codes": [1, 2, 3, 4, 43], "monitored_write_function_codes": [5, 6, 15, 16], "compliance_mapping": { "unauthorized_write_attempt": { "severity": "CRITICAL", "nciipc_control": "Sec 6.2 - Access Control & Authorization", "description": "A write command was issued to an ICS Modbus PLC endpoint from an unauthorized source IP address." } } } } ``` ### 2. 网络遥测事件(`mock_logs.json`) 遥测日志帧存储底层数据包字段,包括单元标识符、功能码和十六进制编码的 payload: ``` [ { "timestamp": "2026-06-19T09:31:12Z", "source_ip": "192.168.1.215", "destination_ip": "192.168.1.5", "protocol": "ModbusTCP", "unit_id": 1, "function_code": 5, "payload": "00020000000601050010ff00", "notes": "Unauthorized client attempted to force coil 16 (potentially tripping safety breaker)." } ] ``` ## 🛡️ NCIIPC 合规性与 MITRE ATT&CK 映射 我们的审计引擎使用以下合规性和威胁框架映射来评估日志异常: | 事件类型 / 协议码 | 严重性 | 目标 NCIIPC 控制点 | MITRE ATT&CK for ICS ID | 描述与缓解意图 | | :--- | :--- | :--- | :--- | :--- | | **`unauthorized_write_attempt`** | `CRITICAL` | **Sec 6.2 - 访问控制** | **T0836** - 修改参数 | 严格限制 PLC 配置更改权限仅授予定义的 IP 租约或物理工作站。 | | **`authorized_write_activity`** | `INFO` | **Sec 6.4 - 审计日志** | N/A | 为配置管理保留常规管理更新的永久痕迹。 | | **`unknown_function_code`** | `WARNING` | **Sec 6.1 - 协议验证** | **T0886** - 伪造报告消息 | 标记意外的消息类型,缓解缓冲区溢出攻击或自定义命令探测。 | | **`dnp3_start_byte_anomaly`** | `CRITICAL` | **Sec 6.1 - 协议验证** | **T0886** - 伪造报告消息 | 标记缺少 DNP3 `0x0564` 同步头的帧,这表明存在模糊测试的 payload 或遥测数据损坏。 | | **`iec104_start_byte_anomaly`** | `CRITICAL` | **Sec 6.1 - 协议验证** | **T0886** - 伪造报告消息 | 标记缺少 IEC 104 `0x68` 同步头的帧,这表明存在格式错误的传输帧。 | | **`dnp3_broadcast_anomaly`** | `CRITICAL` | **Sec 6.1 - 协议验证** | **T0816** - 设备识别 | 标记发送到广播目标(`255.255.255.255`)的命令,这些命令绕过了安全边界。 | | **`DNP3 - 27 (删除文件)`** | `CRITICAL` | **Sec 6.2 - 访问控制** | **T0848** - 程序上传/下载 | 监视试图在远程终端文件系统上删除文件的远程操作。 | | **`S7comm - 26 (下载)`** | `CRITICAL` | **Sec 6.3 - 固件完整性** | **T0848** - 程序上传/下载 | 审计固件更新或块代码下载,以维护 PLC 内存完整性。 | | **`S7comm - 41 (PLC 停止)`** | `CRITICAL` | **Sec 6.2 - 访问控制** | **T0805** - 损坏财产 | 标记停止 PLC 程序循环并关闭物理过程的 STOP 请求。 | | **`IEC104 - 46 (双命令)`**| `CRITICAL` | **Sec 6.2 - 访问控制** | **T0836** - 修改参数 | 记录并验证为断开/闭合传输线而执行的双命令(Type ID 46)。 | ## 🚨 审计警告输出示例(`audit_report.txt`) 当合规性决策引擎拦截到未授权的控制操作时,它会向持久化日志文件中写入一条结构化的取证审计记录: ``` [2026-06-19T09:31:45Z] SEVERITY: CRITICAL | NCIIPC Control: Sec 6.2 - Access Control & Authorization | Protocol: DNP3 Event Type : unauthorized_write_attempt Details : CRITICAL: Unauthorized DNP3 control action (Select (Select Before Operate)) attempted on outstation from non-workstation IP 192.168.1.215. Source IP : 192.168.1.215 -> Destination IP: 192.168.1.12 Payload : 05640bc20300000000000c012801000100070101 Log Note : Unauthorized IP issuing DNP3 Select command to arm a remote trip breaker. Resolution : A DNP3 control action (Write/Select/Operate/Reset) was attempted from an unauthorized source IP address. -------------------------------------------------------------------------------- ``` ## 🛠️ 如何扩展规则(`rules.json`) 要为新的遥测功能码添加监控映射(例如,为 S7Comm CPU 重启尝试添加警告,功能码 `42`): 1. 打开 `rules.json` 并定位到目标协议部分(例如,`"S7Comm"`)。 2. 将目标功能码追加到 `"monitored_write_function_codes"` 列表中。 3. 在 `"compliance_mapping"` 部分定义警报行为: "42": { "name": "PLC 运行 (启动进程)", "severity": "WARNING", "nciipc_control": "Sec 6.2 - 访问控制与授权", "description": "发出 S7comm 请求命令,将 PLC 状态从 STOP 转换为 RUN 执行模式。" } ## 🔎 蓝队防御与检测说明 ### 指纹分析 作为一个 **100% 被动、离线的解析引擎**,此工具生成: * 在目标 OT 局域网上**零网络流量**。 * 在目标 PLC、RTU 或 IED 上**无审计日志痕迹**。 * **本地足迹**仅限于运行时执行期间的标准 CPU/内存分配以及对输出审计日志文件 `audit_report.txt` 的顺序更新。 ### 如何检测未授权的审计器执行 如果一台未授权的主机在工程工作站上本地执行此引擎: 1. **基于主机的审计轨迹:** 通过端点检测工具(EDR)或 auditd 监视针对 `mock_logs.json` 或 `rules.json` 的文件读取操作。 2. **进程监控:** 审计进程创建日志,查找从目标工作区目录(例如,`/opt/ics_defensive_parser`)执行的意外 python 运行时。 ## 🖥️ 可视化演示 实时会话展示 `make test`(10/10 通过),随后执行 `make run` 并在所有 4 种 ICS 协议中触发真实的 CRITICAL/WARNING/INFO 警报: [![Asciicast 演示运行](https://asciinema.org/a/E6tI26ZkbH3MZDgT.svg)](https://asciinema.org/a/E6tI26ZkbH3MZDgT) ## 🚀 快速开始 ### 前置条件 * Python 3.x(无需第三方包;使用标准库) ### 选项 A:本地执行 从仓库根目录使用提供的 `Makefile` 快捷方式运行审计引擎: ``` # 运行 compliance auditor make run # 运行自动化单元测试 make test ``` 或者,导航到 `ics_defensive_parser/` 目录并直接运行 python 脚本: ``` cd ics_defensive_parser python3 main.py ``` ### 选项 B:Docker 容器化执行 你可以使用 Docker 在隔离的容器环境中运行该工具。`Dockerfile` 位于**仓库根目录**,并正确捆绑了引擎包和 `data/` 目录: ``` # 构建 Docker 容器镜像(从 repo 根目录运行) docker build -t ics-auditor . # 运行 auditor 容器 docker run --rm ics-auditor # 或者使用 Makefile 快捷方式: make docker-build && make docker-run ``` ## 🧪 自动化测试与验证 本项目包含一个自动化的、基于区域的测试套件(`tests/run_compliance_tests.py`),用于在四个不同的合规性验证区域系统地验证我们的解析器和规则引擎: 1. **区域 1:标准运营遥测基准** * 验证允许的轮询事务(Modbus FC 3,S7Comm FC 240)绕过警报升级。 * 验证映射的读取操作(Modbus FC 43 设备 ID 扫描)能正确触发与 NCIIPC Sec 6.4 对齐的 INFO 警报。 2. **区域 2:协议头完整性检查** * 验证 DNP3 魔术起始字节检查(`0x0564`)。 * 验证 IEC 104 APCI 起始字节检查(`0x68`)。 * 强制执行 DNP3 越界功能码验证警告。 3. **区域 3:访问控制与逻辑边界** * 验证 S7 PLC Stop 命令块和 DNP3 文件删除尝试。 * 断言来自未授权 IP 的请求会触发 CRITICAL 警告,而经过验证的工程工作站(`192.168.1.50`)作为 INFO 日志通过。 4. **区域 4:子网段隔离** * 通过监控广播目标,验证子网隔离检查。 ### 运行测试套件 从仓库根目录执行测试运行脚本: ``` python3 tests/run_compliance_tests.py ```
标签:PKINIT, SCADA, 哈希传递, 工控安全, 异常检测, 网络审计, 请求拦截, 逆向工具, 防御绕过