carbon-evolution/ot-nmap-blue-team

GitHub: carbon-evolution/ot-nmap-blue-team

一套面向工业控制系统(OT/ICS)蓝队安全评估的改进版Nmap NSE脚本集合,支持16种工业协议的只读设备发现与指纹识别。

Stars: 0 | Forks: 0

# OT Nmap Blue Team — 用于 OT/ICS 协议发现的改进版 NSE 脚本 [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](../../actions) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE) [![Honeypot-Grade](https://img.shields.io/badge/Honeypot-Grade-purple)](sandbox/) [![NSE](https://img.shields.io/badge/NSE-16%20scripts-blue)](improved-scripts/) [![Protocols](https://img.shields.io/badge/protocols-16%20families-orange)](OT-Port-Protocol-Matrix.md) [![Live PLC Health](https://img.shields.io/badge/plchealth-Modbus%20%7C%20S7%20%7C%20EtherNet%2FIP-brightgreen)](plc-health/)

OT Nmap Blue Team — Honeypot-Grade ICS Protocol Emulation

一个用于发现、指纹识别和审计 OT/ICS(操作技术 / 工业控制系统)协议的**改进版 Nmap NSE(脚本引擎)脚本**集合。专为**蓝队安全评估**、资产清单管理和漏洞管理而设计。 涵盖 **16 个协议族**,包括 DNP3、Modbus、Fox、PCWorx、HART-IP、IEC 61850 MMS、PROFINET、EtherNet/IP CIP、BACnet/IP、S7comm-plus、GE SRTP、OPC UA、MELSEC-Q、ProConOS、Red Lion Crimson 和 Foundation Fieldbus HSE。 ### 蓝队工作流 三个工具串联成一个 OT 评估闭环 — **发现**网络上的资产,结合 CVE 上下文进行**清单管理**,然后**监控**每个 PLC 的实时故障状态: ``` flowchart LR subgraph D["1 · Discover"] N["Improved NSE scripts
16 protocols"] M["Honeypot mocks
9 servers (safe lab)"] end subgraph I["2 · Inventory"] A["assetinv
nmap XML → normalized
+ offline CVE hints"] end subgraph H["3 · Live health"] P["plchealth
poll Modbus / S7 / EtherNet-IP
RUN·STOP·FAULT + diag buffer"] end N -->|"-oX scan.xml"| A A -->|"targets"| P M -.->|"test against"| N M -.->|"test against"| P P -->|"exit 0/1/2 · JSON/CSV"| R["Alerts / monitoring"] classDef box fill:#0d1117,stroke:#e0b83a,color:#f0f6fc; class N,M,A,P,R box; ``` ## 目录 - [快速入门](#-getting-started) - [蓝队目的](#-blue-team-purpose) - [脚本目录](#-script-catalog) - [这些脚本可以提取什么信息?](#-what-information-can-these-scripts-extract) - [不同操作系统的 Nmap 脚本位置](#-nmap-script-location-by-os) - [安装说明](#-installation) - [用法示例](#-usage-examples) - [使用模拟服务器进行测试](#-testing-with-mock-servers) - [自动化测试与 CI](#-automated-tests--ci) - [资产清单流水线](#-asset-inventory-pipeline) - [PLC 实时健康监控](#-live-plc-health-monitoring) - [方法论与安全](#-methodology--safety) - [项目结构](#-project-structure) - [更新日志](#-changelog) - [许可证](#-license) ## 🚦 快速入门 本仓库提供**三种可用功能**。请选择符合您目标的一项。 **前提条件:** `nmap` (7.9+), `python3` (3.8+)。无需安装任何 Python 包 — 全部使用标准库。`luac`/`lua5.4` 为可选项(仅用于语法检查)。 ``` git clone https://github.com/carbon-evolution/ot-nmap-blue-team.git cd ot-nmap-blue-team ``` ### 1. 扫描真实 OT 设备(NSE 脚本) 将这些改进版脚本指向某台设备或子网。所有操作都是 **T1 安全 / 只读** 的 — 仅限身份查询。请参阅 [安装说明](#-installation) 将脚本复制到 nmap 的搜索路径中,或者通过完整路径直接运行它们: ``` # 一个协议,一个 host nmap -p 44818 --script improved-scripts/enip-identity-improved.nse 192.168.1.50 # 一个 subnet 上的所有 16 个协议(完整 command 请参见 Usage Examples) nmap -sU -sT -p T:44818,502,102,1911,1962,5094,20000,5007,4840,18245,20547,1089,789,U:47808,34964 \ --script improved-scripts/,improved-scripts/lesser-known/ 192.168.1.0/24 ``` ### 2. 安全地针对蜜罐模拟进行测试(无需真实硬件) 每个脚本都配有 Python **蜜罐模拟**,让您可以在零风险的情况下查看其运行情况: ``` # Terminal A — 启动一个 mock device python3 sandbox/enip_mock_server.py --port 44818 --profile controllogix # Terminal B — 扫描它 nmap -p 44818 --script improved-scripts/enip-identity-improved.nse 127.0.0.1 ``` 请参阅 [使用模拟服务器进行测试](#-testing-with-mock-servers)。要运行完整的自动化测试套件,请参阅 [自动化测试与 CI](#-automated-tests--ci)。 ### 3. 构建资产清单(流水线) 将扫描结果转换为标准化、带有 CVE 标注的**资产清单** (JSON/CSV): ``` # 解析已保存的 nmap XML(使用以下命令捕获一个:nmap ... -oX scan.xml) python3 -m assetinv parse scan.xml --cve # 或者一步完成扫描和 inventory python3 -m assetinv scan 192.168.1.50 --ports 44818 \ --script improved-scripts/enip-identity-improved.nse --cve --format csv -o inventory.csv ``` 请参阅 [资产清单流水线](#-asset-inventory-pipeline)。在 `asset-inventory/` 目录下运行 `python3 -m assetinv`(或将其添加到 `PYTHONPATH` 中)。 ## 🛡 蓝队目的 这些脚本旨在用于**防御性安全目的**: - **资产清单**:发现并识别您网络上的 OT 设备 — PLC、RTU、HMI、IED 和历史数据库 - **漏洞管理**:识别固件版本和型号,以便与已知 CVE 进行关联比对 - **变更检测**:监控 OT 环境中未经授权的设备或配置更改 - **网络隔离验证**:确认从 IT 区域只能访问经授权的 OT 协议 - **事件响应**:在发生安全事件时快速对 OT 设备进行指纹识别 - **合规审计**:验证 OT 资产清单是否准确且为最新 ### ❌ 不可用于攻击用途 这些是查询设备身份信息的 **T1 安全(只读)** 脚本。它们绝不会: - 修改设备配置 - 写入设备内存 - 启动/停止工业过程 - 尝试绕过身份验证或进行漏洞利用 然而,任何网络扫描都带有内在风险。**请务必先在实验环境中进行测试。** ## 📜 脚本目录 ### 标准 OT 协议 (`improved-scripts/`) | 脚本 | 协议 | 端口 | 提取内容 | |--------|----------|------|----------| | `dnp3-advanced-info.nse` | DNP3 | TCP 20000 | 设备属性、DNP3 版本、应用层级、对象支持 | | `modbus-discover-improved.nse` | Modbus | TCP 502 | 设备 ID、供应商名称、产品代码、主/次修订版本 | | `fox-info-improved.nse` | Fox (Tunneling) | TCP 1911 | Fox 协议版本、设备名称、供应商 | | `pcworx-info-improved.nse` | PCWorx | TCP 1962 | PLC 型号、固件、runtime 版本 | | `hartip-info-improved.nse` | HART-IP | TCP 5094 | 设备类型、制造商 ID、HART 修订版本、设备 ID | | `iec61850-mms-improved.nse` | IEC 61850 MMS | TCP 102 | 逻辑设备节点、服务器身份、型号名称 | | `profinet-cm-lookup-improved.nse` | PROFINET CM | UDP 34964 | 站点名称、供应商、设备类型、IP 配置 | | `enip-identity-improved.nse` | EtherNet/IP CIP | TCP 44818 | 供应商、产品名称、序列号、设备类型、产品代码、修订版本、设备状态 | | `bacnet-discover-improved.nse` | BACnet/IP | UDP 47808 | 供应商(名称 + ID)、型号名称、固件、应用软件、对象名称、位置、描述 | | `s7comm-plus-info-improved.nse` | S7comm-plus (S7-1200/1500) | TCP 102 | 模块(订货号/MLFB)、模块类型、固件版本、序列号、系统名称 | ### 小众 OT 协议 (`improved-scripts/lesser-known/`) | 脚本 | 协议 | 端口 | 提取内容 | |--------|----------|------|----------| | `gesrtp-info-improved.nse` | GE SRTP | TCP 18245 | PLC 型号(例如 IC695CPE302)、固件版本(例如 V9.50)、CPU 类型、状态 | | `opcua-discovery-improved.nse` | OPC UA | TCP 4840 | 应用程序名称、应用程序 URI、产品 URI、网关服务器 URI、发现 profile、可用 endpoint | | `melsecq-info-improved.nse` | MELSEC-Q | TCP 5007 | PLC 类型(例如 Q03UDVCPU)、系列名称、固件版本 | | `proconos-info-improved.nse` | ProConOS | TCP 20547 | runtime 版本(例如 ProConOS V3.0.1040)、PLC 型号(例如 ADAM5510KW)、项目名称、源代码状态 | | `ff-hse-discover-improved.nse` | FF HSE | TCP 1089 | 设备名称、供应商名称、设备标签、HSE 版本、软件修订版本、协议栈版本、MAC 地址 | | `redlion-cr3-info-improved.nse` | Red Lion Crimson | TCP 789 | 型号(例如 G310C2)、固件(例如 Crimson 3.2)、部件编号、供应商名称 | ## 🔍 这些脚本可以提取什么信息? | 脚本 | 输出字段 | |--------|---------------| | `dnp3-advanced-info` | 设备属性、DNP3 版本、对象类型、应用层信息、支持的函数 | | `modbus-discover-improved` | 设备 ID、供应商、产品代码、主/次修订版本 | | `fox-info-improved` | 协议版本、设备名称、供应商 | | `pcworx-info-improved` | PLC 型号、固件、Runtime | | `hartip-info-improved` | 设备类型、制造商、HART 修订版本、设备 ID | | `iec61850-mms-improved` | 逻辑设备节点、服务器身份、型号 | | `profinet-cm-lookup-improved` | 站点名称、供应商、设备类型、IP 配置 | | `enip-identity-improved` | **供应商**、**产品名称**、**序列号**、**设备类型**、**产品代码**、**修订版本**、**设备状态** | | `bacnet-discover-improved` | **供应商**、**型号名称**、**固件**、**应用软件**、**对象名称**、**位置**、**描述** | | `s7comm-plus-info-improved` | **模块**、**模块类型**、**版本**、**序列号**、**系统名称** | | `gesrtp-info-improved` | **PLC 型号**、**固件版本**、**CPU 类型**、**PLC 状态** | | `opcua-discovery-improved` | **应用程序名称**、**应用程序 URI**、**产品 URI**、**Endpoint** | | `melsecq-info-improved` | **PLC 类型**、**系列**、**固件** | | `proconos-info-improved` | **Runtime**、**PLC 型号**、**项目名称**、**源状态** | | `ff-hse-discover-improved` | **设备名称**、**供应商**、**设备标签**、**HSE 版本**、**软件修订版**、**协议栈** | | `redlion-cr3-info-improved` | **型号**、**固件**、**部件编号**、**供应商** | ## 📂 不同操作系统的 Nmap 脚本位置 ### Linux (Debian/Ubuntu) ``` # System-wide 安装(需要 root) /usr/share/nmap/scripts/ # User-local 安装 ~/.nmap/scripts/ ``` ### Linux (Red Hat / Fedora / CentOS) ``` # System-wide 安装(需要 root) /usr/share/nmap/scripts/ # User-local 安装 ~/.nmap/scripts/ ``` ### macOS (Homebrew) ``` # System-wide 安装 /opt/homebrew/share/nmap/scripts/ # Apple Silicon (M1/M2/M3/M4) /usr/local/share/nmap/scripts/ # Intel # User-local 安装 ~/.nmap/scripts/ ``` ### Windows ``` :: System-wide (Nmap installed in Program Files) C:\Program Files\Nmap\scripts\ :: User-local %USERPROFILE%\.nmap\scripts\ ``` ## 📥 安装说明 ### 选项 1:快速复制(推荐) ``` # Clone 该 repo git clone https://github.com/carbon-evolution/ot-nmap-blue-team.git cd ot-nmap-blue-team # 复制 scripts 到 nmap 目录 # Linux: cp improved-scripts/*.nse ~/.nmap/scripts/ cp improved-scripts/lesser-known/*.nse ~/.nmap/scripts/ # macOS (Apple Silicon): cp improved-scripts/*.nse ~/.nmap/scripts/ cp improved-scripts/lesser-known/*.nse ~/.nmap/scripts/ # 更新 script database nmap --script-updatedb # 验证安装 nmap --script-help dnp3-advanced-info ``` ### 选项 2:直接运行(无需安装) ``` # 无需复制即可运行(指定完整 path) nmap -p 502 --script /path/to/modbus-discover-improved.nse ``` ## 🚀 用法示例 ### 基础主机扫描 ``` # 扫描单个 host 的所有 16 个受支持的 OT 协议(TCP + UDP)。 # UDP scan (-sU) 和特权 ports(<1024)需要 root/sudo。 sudo nmap -sT -sU \ -p T:502,1911,1962,5094,102,20000,44818,18245,20547,1089,789,4840,5007,U:47808,34964 \ --script improved-scripts/,improved-scripts/lesser-known/ \ ``` ### 扫描特定协议 ``` # OPC UA discovery nmap -p 4840 --script opcua-discovery-improved.nse 192.168.1.100 # GE SRTP PLC identification nmap -p 18245 --script gesrtp-info-improved.nse 192.168.1.100 # MELSEC-Q PLC info nmap -p 5007 --script melsecq-info-improved.nse 192.168.1.100 ``` ### 子网扫描 ``` # 扫描整个 OT subnet;-oA 保存 normal/grepable/XML(ot-scan.xml 提供给 # 下方的 asset-inventory pipeline)。 sudo nmap -sT -sU \ -p T:502,1911,1962,5094,102,20000,44818,18245,20547,1089,789,4840,5007,U:47808,34964 \ --script improved-scripts/,improved-scripts/lesser-known/ \ --open -oA ot-scan \ 192.168.1.0/24 # 然后从 nmap 刚写入的 XML 构建 inventory: python3 -m assetinv parse ot-scan.xml --cve -o inventory.json ``` ### 示例输出 ``` PORT STATE SERVICE 4840/tcp open opcua-tcp | opcua-discovery-improved: | Application Name: OPC UA Mock Server | Application URI: urn:OPCUA:MockServer | Product URI: urn:OPCUA:MockServer:product | Gateway Server URI: urn:OPCUA:MockServer:gateway | Discovery Profile: http://opcfoundation.org/UA-Profile/Discovery/Register |_ Endpoints available: 2 PORT STATE SERVICE 18245/tcp open ge-srtp | gesrtp-info-improved: | PLC Model: GE PACSystems RX3i | Firmware Version: V9.50 | CPU Type: IC695CPE302 |_ PLC Status: Running PORT STATE SERVICE 789/tcp open redlion-crimson | redlion-cr3-info-improved: | Model: G310C2 | Firmware: Crimson 3.2 | Part Number: MNGR-BASE |_ Vendor: Red Lion Controls ``` ## 🧪 使用模拟服务器进行测试 本仓库包含了每个 NSE 脚本对应的 Python 模拟服务器,从而无需连接到真实的 OT 设备即可进行安全的测试。 ### 前置条件 ``` python3 # Any recent Python 3.x nmap # For running the NSE scripts ``` ### 快速测试 ``` cd sandbox/ # 启动 6 个鲜为人知的 honeypot servers # 注意:Red Lion 监听 TCP 789(一个特权 port),因此其 server # 必须使用 sudo 启动。NSE portrule 固定为 789。 python3 melsecq_mock_server.py --port 5007 & python3 opcua_mock_server.py --port 4840 --profile siemens_s7 & python3 gesrtp_mock_server.py --port 18245 --profile rx3i & sudo python3 redlion_mock_server.py --port 789 --model G310C2 & python3 ffhse_mock_server.py --port 1089 --profile flow & python3 proconos_mock_server.py --port 20547 & # 在另一个 terminal 中,针对所有 6 个运行 NSE 测试 nmap -p 5007 --script ../improved-scripts/lesser-known/melsecq-info-improved.nse 127.0.0.1 nmap -p 4840 --script ../improved-scripts/lesser-known/opcua-discovery-improved.nse 127.0.0.1 nmap -p 18245 --script ../improved-scripts/lesser-known/gesrtp-info-improved.nse 127.0.0.1 nmap -p 789 --script ../improved-scripts/lesser-known/redlion-cr3-info-improved.nse 127.0.0.1 nmap -p 1089 --script ../improved-scripts/lesser-known/ff-hse-discover-improved.nse 127.0.0.1 nmap -p 20547 --script ../improved-scripts/lesser-known/proconos-info-improved.nse 127.0.0.1 # 清理 kill %1 %2 %3 %4 %5 %6 ``` ### 模拟服务器参考 所有 9 个独立协议服务器均达到**蜜罐级**水平 — 它们超越了静态响应,提供了逼真的状态机、基于 profile 的设备身份、检测日志记录以及扫描延迟模拟。 | 模拟服务器 | 协议 | 端口 | 蜜罐功能 | 备注 | |-------------|----------|------|-------------------|-------| | `ot_mock_servers.py` | 所有标准协议 | 各种 | — | 多合一服务器(轻量/旧版) | | `melsecq_mock_server.py` | MELSEC-Q | 5007 | Profile、检测日志记录、扫描延迟 | 独立运行 | | `opcua_mock_server.py` | OPC UA | 4840 | 完整的 HEL→ACK→OPN→MSG→CLO 状态机,FindServers/GetEndpoints/Read/Browse/Write 处理程序,3 种 profile,地址空间,检测日志记录 | 独立运行 | | `proconos_mock_server.py` | ProConOS | 20547 | Profile、检测日志记录、扫描延迟 | 独立运行 | | `gesrtp_mock_server.py` | GE SRTP | 18245 | 完整的 INIT→REQ 状态机,SSTAT/LSTAT/CONFIG_INFO/MEM_READ/MEM_WRITE 服务,3 种 profile,连接跟踪,检测日志记录,支持 UDP | 独立运行 | | `ffhse_mock_server.py` | FF H | 1089 | SM_IDENTIFY/MA_IDENTIFY/LREQ/LRES/LFIN/FMS_READ 处理程序,告警引擎,PV 漂移模拟,4 种 profile,检测日志记录 | 独立运行 | | `redlion_mock_server.py` | Red Lion | 789 | 基于 profile 的设备身份 + 标签数据库,STX 命令集(读写标签、登录、配置),写标签日志记录 (0x12),扫描延迟,4 种 profile | 需要 root 权限 (<1024) | | `enip_mock_server.py` | EtherNet/IP CIP | 44818 | ListIdentity (0x0063) CPF Identity 响应,3 种 profile (ControlLogix/Micro850/OMRON NX),检测日志记录,扫描延迟,SIGTERM 关闭 | 独立运行 | | `bacnet_mock_server.py` | BACnet/IP | 47808/udp | 针对 8 个 Device-object 身份属性的 ReadProperty 应答(char-string + unsigned 标签),3 种 BAS profile,TCP 就绪监听器,检测日志记录 | 独立运行 (UDP) | | `s7commplus_mock_server.py` | S7comm-plus | 102 | COTP CR/CC + S7comm 设置 + 固定偏移量下的 SZL 0x11/0x1C 身份响应,2 种 profile (S7-1200/1500),检测日志记录 | 需要 root 权限 (<1024) | ### 为什么它们能达到蜜罐级水平 这 9 个独立服务器远远超越了简单的预设响应: | 能力 | 含义 | |------------|---------------| | **完整的协议状态机** | 多消息握手(OPC UA: HEL→ACK→OPN→MSG→CLO,GE SRTP: INIT→REQ→ACK,FF HSE: LREQ→LRES→LFIN),而不仅仅是单次回复 | | **基于 profile 的设备身份** | 每个 `--profile` 都会更改设备型号、供应商、固件、序列号、MAC 地址 — 模拟不同的真实产品 | | **内存和寄存器读写** | GE SRTP 的 MEM_READ/MEM_WRITE(服务 15/16),OPC UA 的 Read/Browse/Write(服务 631/525/634),Red Lion 的标签读写(命令 0x02/0x12) | | **基于 profile 的标签数据库** | Red Lion 拥有 4 套特定于 profile 的 HMI 标签集(TankLevel, PumpSpeed, Temperature 等),并带有逼真的 float/int/bool 值 | | **告警引擎** | FF HSE 生成模拟的过程告警(HI_TEMP, HH_PRESSURE, SENSOR_FAIL),具有加权严重性,并通过 LRES 报告活动告警 | | **检测日志记录** | 每个连接、探测、服务请求和标签读写都带有时间戳并被记录,严重级别为 DETECTION — 随时准备供 SIEM 提取 | | **扫描延迟模拟** | 每个协议随机具有 5–200 毫秒的响应抖动,以避免带有脚本特征的即时回复,从而暴露模拟服务器 | | **优雅降级** | TCP 分片处理(`recv_exactly`),连接重置恢复,对无效请求返回正确的错误代码 — 表现得像真实设备一样 | ### 测试结果 所有 16 个脚本都已经过对应模拟服务器的测试。有关详细输出,请参阅 `sandbox/test-results/README.md`。 ### ✅ 自动化测试与 CI `sandbox/tests/` 中的 `pytest` 测试套件将每个模拟服务器作为子进程启动,使用真实的 `nmap` 对其运行匹配的 NSE 脚本,并断言脚本能提取出预期的命名字段 — 而且对于支持 profile 的设备,还会验证不同的设备 profile 是否会产生不同的输出。GitHub Actions 会在每次推送和拉取请求时对所有 16 个脚本运行 `luac -p` 语法检查以及完整的测试套件。 ``` cd sandbox/tests pip install -r requirements.txt python3 -m pytest -m "not privileged" -v # scripts on ports > 1024, no root needed sudo python3 -m pytest -m privileged -v # Red Lion (789), Modbus (502), MMS (102) ``` 标记为 `privileged` 的测试会绑定 1024 以下的端口或需要进行 UDP 扫描(`nmap -sU`),除非以 root 身份运行否则将跳过(它们在 CI 中以 root 身份运行) — 这涵盖了 Red Lion、Modbus、IEC 61850 MMS、S7comm-plus(TCP < 1024)和 BACnet/IP(UDP)。少数标准协议测试被声明为 `xfail` 并带有明确原因 — HART-IP 和 MMS 是因为公开的模拟/脚本 payload 已作涂黑处理;DNP3 在多合一模拟中没有实现模拟;而 PROFINET-CM 是因为其 NSE 解析的是 pcap 第三层(layer-3)帧,而多合一模拟是在 payload 相对偏移量处编码字段(字节偏移量不匹配)。这 16 个脚本都有对应的测试,因此一旦出现解析器退化或字段标签不匹配,就会导致 CI 运行变红(失败)。 ## 📋 资产清单流水线 [`asset-inventory/`](asset-inventory/) 包(`assetinv`)将这 16 个脚本的原始扫描结果转换为标准化的、带有 CVE 标注的**资产清单** — 格式为 JSON 或 CSV。它解析 nmap 的 `-oX` XML,将每个脚本的字段映射到规范的设备 schema 中,并(可选)与离线整理的 ICS-CVE 数据包进行比对。仅使用标准库。 ``` # 将捕获的 nmap XML 解析为带 CVE 注释的 inventory python3 -m assetinv parse scan.xml --cve # 或者运行端到端的 live scan python3 -m assetinv scan 10.0.0.5 --ports 44818 \ --script improved-scripts/enip-identity-improved.nse --cve --format csv -o inventory.csv ``` CVE 提示是**非权威性的**(“需对照供应商/CISA 通告进行验证”),并且源自捆绑的、可编辑的 JSON 文件。有关 schema、数据包格式以及如何更新它,请参阅 [asset-inventory README](asset-inventory/README.md)。这是项目的第三阶段。 ## 🩺 PLC 实时健康监控 当 NSE 脚本和 `assetinv` 在*发现时*读取设备状态时,[`plc-health/`](plc-health/) 包(`plchealth`)通过原生协议读取 PLC 的**实时故障/诊断状态** — 这是扫描时工具无法看到的运行时健康状况。仅使用标准库,只读(绝不向 PLC 写入或控制 PLC)。 ``` cd plc-health python3 -m plchealth poll 10.0.0.5 # auto-detect protocol python3 -m plchealth poll 10.0.0.5 --proto s7 # Siemens S7-1200/1500 python3 -m plchealth poll 10.0.0.5 --proto modbus --modbus-fault-bit 0 python3 -m plchealth poll 10.0.0.5 --json health.json # machine-readable ``` | 协议 | 端口 | 解码的健康信号 | |----------|------|-----------------------| | **Modbus TCP** | 502 | Modbus 异常代码 + 可配置的状态/故障寄存器 | | **S7comm** | 102 | 通过 SZL 0x0424 获取的 CPU 状态 (RUN/STOP/DEFECT/HOLD) + 诊断缓冲区 SZL 0x00A0 | | **EtherNet/IP** | 44818 | CIP Identity 状态字 + 状态字节(被占用/故障,次要/主要故障) | 退出代码使其可通过脚本进行持续监控:**`0`** 健康,**`1`** 故障/降级,**`2`** 无法访问。已通过两种方式进行测试 — 在 CI 中针对捆绑的 `sandbox` 蜜罐模拟进行了 29 项测试,以及针对真实模拟器(pymodbus / python-snap7 / cpppo)的可选受控交叉检查。请参阅 [plc-health README](plc-health/README.md)。这是项目的第四阶段。 ## 🧭 方法论与安全 ### 威胁等级分类 | 等级 | 描述 | 这些脚本是否允许 | |-------|-------------|-------------------------| | **T1(基础读取)** | 仅读取设备身份 | ✅ 是 — 所有脚本均为 T1 安全 | | **T2(高级读取)** | 读取配置、日志 | ❌ 否 | | **T3(基础写入)** | 修改非关键设置 | ❌ 否 | | **T4(高级写入)** | 修改关键参数 | ❌ 否 | ### OT 扫描最佳实践 1. **先进行测试**:在任何实时扫描之前,务必先针对(包含的)模拟服务器运行脚本 2. **从小范围开始**:首先扫描单个主机、单个协议,以验证预期输出 3. **速率限制**:使用 `--max-rate 10 --scan-delay 1s` 避免使设备过载 4. **记录所有内容**:务必使用 `-oA ` 保存结果 5. **协调**:在进行任何扫描之前通知 OT 利益相关者 6. **记录归档**:保留有关扫描内容、时间及原因的记录 ``` # Safe scan template nmap -p --script --max-rate 10 --scan-delay 1s -oA ot-scan ``` ## 📁 项目结构 ``` ot-nmap-blue-team/ ├── LICENSE # MIT License ├── README.md # This file ├── .gitignore ├── .github/workflows/ci.yml # GitHub Actions: luac gate + pytest suites │ ├── improved-scripts/ # 16 NSE scripts (standard protocols) │ ├── dnp3-advanced-info.nse │ ├── modbus-discover-improved.nse │ ├── fox-info-improved.nse │ ├── pcworx-info-improved.nse │ ├── hartip-info-improved.nse │ ├── iec61850-mms-improved.nse │ ├── profinet-cm-lookup-improved.nse │ ├── enip-identity-improved.nse # Phase 2: EtherNet/IP CIP │ ├── bacnet-discover-improved.nse # Phase 2: BACnet/IP │ ├── s7comm-plus-info-improved.nse # Phase 2: S7comm-plus │ │ │ └── lesser-known/ # NSE scripts (lesser-known protocols) │ ├── gesrtp-info-improved.nse │ ├── opcua-discovery-improved.nse │ ├── melsecq-info-improved.nse │ ├── proconos-info-improved.nse │ ├── ff-hse-discover-improved.nse │ └── redlion-cr3-info-improved.nse │ ├── sandbox/ # Honeypot mock servers + pytest harness │ ├── ot_mock_servers.py # all-in-one (standard protocols) │ ├── melsecq_mock_server.py # 9 standalone honeypot mocks: │ ├── opcua_mock_server.py │ ├── proconos_mock_server.py │ ├── gesrtp_mock_server.py │ ├── ffhse_mock_server.py │ ├── redlion_mock_server.py │ ├── enip_mock_server.py # Phase 2 (+ Phase 4 fault fields) │ ├── bacnet_mock_server.py # Phase 2 │ ├── s7commplus_mock_server.py # Phase 2 (+ Phase 4 SZL diagnostics) │ ├── modbus_mock_server.py # Phase 4: Modbus TCP fault/exception mock │ └── tests/ # Phase 1: pytest mock-driven suite │ ├── conftest.py # mock_server + nmap_scan fixtures │ └── test_*.py # one per script │ ├── asset-inventory/ # Phase 3: scan -> inventory pipeline │ ├── assetinv/ # stdlib package (runner/parser/normalizer/ │ │ └── data/ics_cve_hints.json # cve/export/cli) + offline CVE bundle │ ├── tests/ # unit + end-to-end integration tests │ └── README.md │ ├── plc-health/ # Phase 4: live PLC fault reader │ ├── plchealth/ # stdlib package (probes/{modbus,s7,enip} → │ │ # model/faultcodes/poller/cli) │ ├── tests/ # mock-driven tests + gated sim/ cross-checks │ └── README.md │ ├── docs/superpowers/ # Design specs + implementation plans (per phase) │ ├── specs/ │ └── plans/ │ ├── scada-tools/ # Third-party SCADA tools (reference) ├── ICS-Discovery-Tools/ # Community ICS discovery scripts └── Redpoint/ # Redpoint OT security tools (upstream bases) ``` ## 📚 文档 - [OT-Nmap-Blue-Team-Reference.md](OT-Nmap-Blue-Team-Reference.md) — 全面的 OT 扫描参考 - [Lesser-Known-Protocols-Reference.md](Lesser-Known-Protocols-Reference.md) — 覆盖盲区与协议详情 - [NSE-Script-Catalog-Detailed.md](NSE-Script-Catalog-Detailed.md) — 完整的脚本目录 - [OT-Port-Protocol-Matrix.md](OT-Port-Protocol-Matrix.md) — 端口/协议映射矩阵 - [Blue-Team-Methodology-Research.md](Blue-Team-Methodology-Research.md) — OT 扫描方法论 - [DNP3-NSE-Deep-Dive.md](DNP3-NSE-Deep-Dive.md) — DNP3 协议深度剖析 - [DNP3-Advanced-Script-Report.md](DNP3-Advanced-Script-Report.md) — DNP3 脚本报告 - [NSE-Script-Code-Review.md](NSE-Script-Code-Review.md) — 第三方 NSE 脚本的代码审查 ## 📅 更新日志 本项目分阶段构建。每个阶段的设计规范和实施计划都存放在 [`docs/superpowers/`](docs/superpowers/) 中。 ### 第四阶段 — PLC 实时健康读取器 · 2026-07-19 - 添加了 [`plc-health/`](plc-health/) 包(`plchealth`,仅使用标准 库):通过 **Modbus TCP**、 **S7comm** 和 **EtherNet/IP** 轮询正在运行的 PLC 的实时故障/诊断状态, 解码 CPU/故障状态,并通过可编写脚本的退出代码(`0` 健康 / `1` 故障 / `2` 无法访问)进行报告。只读。 - 特定于协议的探测 → 通用的 `PLCHealth` 模型;带有协议自动检测功能的 `poller`;具有 JSON/CSV 输出的 `cli`;故障解码表。 - 使用 SZL 0x0424(CPU 状态)和 0x00A0(诊断缓冲区)扩展了 S7comm-plus 模拟, 使用可设置的状态/状态字节扩展了 EtherNet/IP 模拟,并添加了一个新的 Modbus TCP 模拟。在 CI 中针对捆绑的模拟进行了测试,并针对真实模拟器 (pymodbus/snap7/cpppo) 添加了受控的交叉检查。 ### 第三阶段 — 资产清单流水线 · 2026-07-12 - 添加了 [`asset-inventory/`](asset-inventory/) 包(`assetinv`,仅使用标准 库):一个将 NSE 扫描结果转化为标准化、带有 CVE 标注的资产清单的流水线 (JSON/CSV)。 - 模块:`runner` (nmap `-oX` 或保存的 XML) → `parser` → `normalizer` (将所有 16 个脚本的标签映射到一个规范的 `Asset` schema 中) → `cve` (离线整理的 ICS-CVE 数据包,非权威性提示) → `export` → `cli` (`scan` / `parse` 子命令)。 - 使用来自 CISA 通告的真实 CVE(Rockwell Logix, Siemens S7-1200/1500)初始化了 CVE 数据包。添加了完整的 pytest 套件,包括一个非特权端到端集成测试,并接入了 CI。 ### 第二阶段 — 三种新协议 · 2026-07-12 - 添加了 **EtherNet/IP CIP** (`enip-identity-improved`, TCP 44818), **BACnet/IP** (`bacnet-discover-improved`, UDP 47808), 和 **S7comm-plus** (`s7comm-plus-info-improved`, TCP 102) — 每个都带有蜜罐模拟和测试。 脚本数量从 **13 增至 16**;独立蜜罐模拟从 **6 增至 9**。 - 将新脚本从已移除的 nmap `bin` API 迁移至 `string.pack`/`string.unpack`。 - 使用 **UDP 扫描路径** (`nmap -sU`) 扩展了测试套件,以便可以测试 BACnet。PROFINET-CM 仍然是 `xfail`(记录在案的 mock/NSE 字节偏移量差异)。 ### 第一阶段 — 测试套件与 CI · 2026-07-11 → 2026-07-12 - 构建了一个 `pytest` **模拟驱动测试套件** (`sandbox/tests/`):启动每个模拟断言匹配的 NSE 提取出正确的字段,包括对 profile 差异的检查。 - 添加了 **GitHub Actions CI**:在每次推送/PR 时对每个脚本进行 `luac -p` 语法检查以及完整的测试套件运行。 - 修复了测试套件暴露出的真实 bug:4 个脚本在 nmap 7.9x/Lua 5.4 上运行时崩溃(移除了 `bin`/`bit32` API) — 已将其迁移;FF HSE 现在从其带标签的 banner 中提取命名的设备字段;OPC UA 模拟根据 profile 调整其 ACK;Modbus 测试已与模拟的真实输出保持一致。 ### 初始版本 · 2026-07-11 - 包含 13 个用于 OT/ICS 协议(DNP3, Modbus, Fox, PCWorx, HART-IP, IEC 61850 MMS, PROFINET, GE SRTP, OPC UA, MELSEC-Q, ProConOS, Red Lion Crimson, FF HSE)的改进版 NSE 发现脚本,6 个蜜罐级模拟服务器以及参考文档。 - 修复了 FF HSE 的 `string.unpack` 崩溃,并更正了 README 的快速测试启动命令。 ## 📄 许可证 本项目基于 MIT 许可证授权 — 有关详细信息,请参阅 [LICENSE](LICENSE) 文件。 ## 🤝 贡献 欢迎您的贡献!如果您想添加对额外 OT 协议的支持、改进现有脚本或修复 bug: 1. Fork 本仓库 2. 创建一个功能分支 3. 添加您的更改(包含用于测试的模拟服务器) 4. 提交一个 Pull Request ### 协议添加检查清单 - [ ] 遵循现有模式的 NSE 脚本(大端序网络格式,健壮的错误处理) - [ ] 用于测试的 Python 模拟服务器 - [ ] 存放在 `sandbox/test-results/` 中的测试结果 - [ ] 更新所有相关文档
标签:CTI, GPT, Nmap, OT安全, 工控协议, 插件系统, 漏洞管理, 虚拟驱动器