Mucahic/ntcip-1202-lab
GitHub: Mucahic/ntcip-1202-lab
一个将NTCIP 1202交通信号控制器模拟器与SUMO交通仿真结合的纯软件攻击实验平台,无需物理设备即可复现并可视化针对交通信号控制系统的SNMP攻击。
Stars: 0 | Forks: 0
# NTCIP 1202 交通信号攻击实验
一个独立的、纯软件的攻击性安全实验,它将模拟的
**NTCIP 1202** 交通信号控制器与 **Eclipse SUMO** 路口
仿真环境配对使用。真实的 `snmpset` 命令驱动真实的 SUMO-GUI 窗口,因此无需接触任何物理设备,即可端到端地观察每一次攻击。
伴随撰写文档 (土耳其语):**[mucahic.com/dossier-08.html](https://mucahic.com/dossier-08.html)**

## 这是什么
一个用于研究现代交通信号控制器如何通过其原生管理协议被操纵的纯软件工作台。该实验暴露了真实的 NTCIP 1202 / SNMPv2c 攻击面,并在 SUMO 仿真中呈现其后果,以便操作员可以看到队列积压、交通瘫痪蔓延以及自适应逻辑如何被伪造的传感器数据欺骗。
它**不是**一个生产级控制器,也不适用于公共网络上的任何设备。请用它来学习、演示和设计防御。
## 为什么存在这个项目
GitHub 上不乏 NTCIP 相关资料,但每个项目都只涉及其中一小部分:
| 项目 | 它的功能 | 它不是什么 |
| ------- | ------------ | -------------- |
| [`mnit-rtmc/ntcip`](https://github.com/mnit-rtmc/ntcip) | Rust 库,专注于 DMS | 不是 1202,不是服务器 |
| [`markashook/SharpNTCIP`](https://github.com/markashook/SharpNTCIP) | C# 协议库 | 仅限客户端,无模拟器 |
| [`usdot-fhwa-OPS/V2X-Hub`](https://github.com/usdot-fhwa-OPS/V2X-Hub) | NTCIP 1202 SPAT 插件 | 与真实控制器**通信** |
| [`mmitss/mmitss-az`](https://github.com/mmitss/mmitss-az) | 亚利桑那州 MMITSS V2I | 需要真实的信号硬件 |
| [`sumoITScontrol`](https://pypi.org/project/sumoITScontrol/) | SUMO 信号控制框架 | 仅限 TraCI/TCP,无 SNMP |
| [`Fortiphyd/GRFICSv3`](https://github.com/Fortiphyd/GRFICSv3) | OT 安全实验 | 化工流程,非交通 |
本实验填补了它们之间的空白:一个**在网络上直接处理 NTCIP 1202** 的模拟控制器,以及一个可视化的 SUMO 目标,让你能够看到 SET 请求生效后发生了什么。整个项目只需执行一次 `pip install` 和一次 `python` 命令,即可搭建好一个可用的攻击演练环境。
## 架构

```
┌──────────────┐ UDP/1161 (SNMP v2c) ┌────────────────────────────────┐
│ attacker │ ────────────────────────> │ controller.py │
│ snmpset │ │ ┌─────────────────────────┐ │
└──────────────┘ │ │ pysnmp agent thread │ │
│ │ - public (read) │ │
│ │ - private (write) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ ControllerState │ │
│ │ (thread-safe dict) │ │
│ └────────────┬────────────┘ │
│ │ │
│ ┌────────────▼────────────┐ │
│ │ TraCI bridge (main) │ │
│ │ every step: │ │
│ │ state -> SUMO TLS │ │
│ └────────────┬────────────┘ │
└───────────────┼────────────────┘
│ TCP / TraCI
▼
┌────────────┐
│ SUMO-GUI │
│ (intersect)│
└────────────┘
```
一个单一的 Python 进程敞开两扇大门。一扇门接收来自攻击者的 SNMP 数据包;另一扇门通过 TraCI 驱动 SUMO 仿真。这两个线程共享一个受锁保护的小型内存状态对象。这就是 SNMP 世界和仿真世界之间唯一的桥梁。
## MIB
供应商分支 `1.3.6.1.4.1.1206` (NTCIP 组织)。该实验暴露了一个刻意缩小的子集,涵盖了撰写文档中的攻击内容。
| OID | 字段 | 类型 | 备注 |
| ------------------------------------ | ----------------- | ----------- | ---------------------------------- |
| `.1.3.6.1.4.1.1206.4.2.1.1.1.0` | currentPhase | Integer32 | 1 = 南北绿灯, 2 = 东西绿灯 |
| `.1.3.6.1.4.1.1206.4.2.1.1.2.0` | greenTime | Integer32 | 秒 |
| `.1.3.6.1.4.1.1206.4.2.1.1.3.0` | forceAllRed | Integer32 | 1 = 全红交通瘫痪 |
| `.1.3.6.1.4.1.1206.4.2.1.1.4.0` | greenLockPhase | Integer32 | 0 / 1 / 2 (永久绿灯锁定) |
| `.1.3.6.1.4.1.1206.4.2.1.1.5.0` | preemptionPhase | Integer32 | 0 / 1 / 2 (伪造紧急车辆) |
| `.1.3.6.1.4.1.1206.4.2.1.1.6.0` | loopSpoofMask | Integer32 | 4位 (北=1, 东=2, 南=4, 西=8) |
| `.1.3.6.1.4.1.1206.4.2.1.1.99.0` | sysBanner | OctetString | 身份识别字符串 |
| `.1.3.6.1.4.1.1206.4.2.1.1.100.0` | screenshotRequest | OctetString | 写入文件名以捕获 SUMO 截图 |
团体字符串:`public` (RO) 和 `private` (RW)。这反映了至今仍在实际部署中发现的 NTCIP 1202 默认设置。
## 仓库布局
```
ntcip-1202-lab/
├── scenario/ SUMO network + routes (4-leg signalized intersection)
├── server/ NTCIP 1202 SNMP agent + TraCI bridge (single process)
├── attacks/ SNMP client, recon, attack CLI, demo orchestrator
├── diagrams/ Generators for the article diagrams (PIL/SVG)
├── README.md
├── LICENSE MIT
└── requirements.txt
```
`captures/` 在运行时创建,并已添加到 `.gitignore`。
## 系统要求
```
python -m pip install -r requirements.txt
```
`eclipse-sumo` 会将 SUMO 二进制文件 (`sumo`, `sumo-gui`, `netconvert`)
安装到当前活动 Python 环境的 `Scripts/` 目录中。`controller.py` 会自动扩展 `PATH`,因此无需手动设置步骤即可直接使用它们。
## 构建网络 (一次性操作)
```
netconvert \
--node-files scenario/network.nod.xml \
--edge-files scenario/network.edg.xml \
--output-file scenario/network.net.xml \
--tls.guess true --tls.default-type static
```
## 运行
终端 1 — SUMO-GUI + SNMP 代理 + TraCI 桥接:
```
python server/controller.py --mode full
```
终端 2 — 侦查和单独攻击:
```
python attacks/recon.py
python attacks/attack.py eternal-red
python attacks/attack.py green-forever --phase 1
python attacks/attack.py preemption --phase 2
python attacks/attack.py loop-spoof --mask 5
python attacks/attack.py reset
python attacks/attack.py screenshot --name eternal_red.png
```
或者运行自动化脚本,执行所有攻击并为每个场景截取一张屏幕截图:
```
python attacks/demo_all.py
```
## 使用真实的 Net-SNMP 客户端
该代理使用标准的 SNMPv2c 协议通信,因此任何支持 SNMP 协议的工具都可以对其进行操作。
该实验使用了与现场控制器相同的协议结构:
```
snmpwalk -v2c -c public 127.0.0.1:1161 .1.3.6.1.4.1.1206.4.2.1.1
snmpset -v2c -c private 127.0.0.1:1161 .1.3.6.1.4.1.1206.4.2.1.1.3.0 i 1
```
## 攻击
这四种攻击反映了伴随撰写文档中的类别。
1. **永恒红灯** — `forceAllRed = 1` 使所有方向保持红灯。
2. **永远绿灯** — `greenLockPhase = 1|2` 将某一轴向锁定为绿灯。
3. **抢占欺骗** — `preemptionPhase = 1|2` 模拟卡住的紧急车辆信号。
4. **线圈欺骗** — `loopSpoofMask` 在选定的进口道上注入幽灵车辆。
这些攻击中的每一个都只需执行**一次** `snmpset`,并会在 SUMO 中返回一个对应的场景。
## 防御措施 (使该实验对攻防双方都有用)
- 更改默认的团体字符串,不要使用 `public`/`private`。
- 将 SNMP 流量放入具有严格 L3 ACL 的管理 VLAN 中。
- 迁移至 SNMPv3 (auth + priv)。NTCIP 1218 已经倾向于这种做法。
- 验证硬件冲突监视器是否已校准并经过近期测试。
- 将供应商远程访问视为按需即时连接,而非始终在线。
- 锁定检测器接线箱的物理访问权限。
## 免责声明
专为它附带的仿真环境而设计。在作者所知的每个司法管辖区,未经书面授权向生产环境中的交通信号发送真实的 `snmpset` 流量都是违法的。请在您自己的实验环境中操作。
## 作者
**Mücahit İç (MUCAHIC)** — [mucahic.com](https://mucahic.com) · [LinkedIn](https://www.linkedin.com/in/mucahic/) · [GitHub](https://github.com/Mucahic)
标签:CPS安全, Eclipse SUMO, IoT安全, ITS, NTCIP 1202, OPA, OT安全, PKINIT, snmpset, SNMPv2c, SNMP模糊测试, SUMO, 交通仿真, 交通信号灯, 交通灯控制, 信号控制系统, 关键信息基础设施, 协议分析, 安全测试, 密码管理, 工控安全, 情报收集, 插件系统, 攻击性安全, 攻击模拟, 数据展示, 智慧交通, 智能交通系统, 权限提升, 漏洞研究, 物联网安全, 红队, 网络安全, 网络攻防, 逆向工具, 隐私保护, 靶场, 驱动签名利用