anpa1200/operation-desert-hydra
GitHub: anpa1200/operation-desert-hydra
该项目将公开来源的 MuddyWater 威胁情报通过 OpenCTI 知识图谱转化为 SOC 可用的检测规则,并在 Windows 实验室环境中完成全链路验证。
Stars: 0 | Forks: 0
# 沙漠九头蛇行动
**公开来源 CTI → OpenCTI 知识图谱 → 检测工程 → 实验室验证**
这是一个完整且可复现的流水线,它获取关于 **MuddyWater / Seedworm** 的公开来源威胁情报——被政府和安全厂商广泛报告为与伊朗相关的、由 MOIS 背景的活动——并将其转化为经过分析师审核的、SOC 可用的检测工件。全部由版本控制管理。只需一次克隆即可部署。
**成果:** 10 个操作过程 · 21 个 ATT&CK 技术 · 11 条检测记录 · 16 项规则检查中 **14 项 PASS / 1 项 PARTIAL / 1 项 FAIL** · 12 张 Kibana 验证截图
## 招聘经理评估路径
如果您正在评估此项目以招聘 CTI 或检测工程岗位,请从这里开始:
1. **[Docusaurus 站点](https://1200km.com/operation-desert-hydra/)** — 概述与流水线结构
2. **[阶段 4:检测图谱](https://1200km.com/operation-desert-hydra/docs/phase-4-detection-atlas)** — 11 条检测记录,包含与 SIEM 无关的伪逻辑、覆盖评分、误报类别和设计依据
3. **[阶段 5:验证结果](https://1200km.com/operation-desert-hydra/docs/phase-5-results)** — 14 项 PASS / 1 项 PARTIAL / 1 项 FAIL,包含 Kibana 截图和针对失败项的根本原因文档
4. **[阶段 6:覆盖矩阵](https://1200km.com/operation-desert-hydra/docs/phase-6-coverage-matrix)** — 21 个 ATT&CK 技术、6 个能力关卡、差距分析、零覆盖说明
5. **[Medium 文章](https://medium.com/@1200km/operation-desert-hydra-ai-assisted-cti-pipeline-muddywater-to-kibana-34da7917acf0)** — 包含方法论依据的完整演练
如果想要复现这些结果,接着执行 `git clone` 并运行 `bash start.sh`。
## 流水线
```
Source review gate (71 candidates → 8 promoted)
│
▼
Claim extraction (evidence labels: Observed / Reported / Assessed)
│
▼
Procedure dataset (10 records, ATT&CK candidate mapping)
│
▼
OpenCTI 6.2 knowledge graph (MuddyWater intrusion set, 9 malware, 21 techniques)
│
▼
Detection atlas (11 records, SIEM-agnostic pseudologic, coverage scores)
│
▼
Benign lab simulation (Ansible → Windows 10 VM → Sysmon + Winlogbeat + Kibana)
│
▼
Kibana validation proofs (14 PASS / 1 PARTIAL / 1 FAIL across 16 rule checks)
│
▼
Coverage matrix (16/21 techniques (76%) fully validated, 6 capability gates)
```
## 本仓库包含的内容
```
operation-desert-hydra/
├── start.sh # Start everything (OpenCTI + Kibana + lab VM)
├── stop.sh # Stop everything (halt or destroy)
│
├── stack/ # Docker Compose stack (OpenCTI + Elasticsearch + Kibana)
│ ├── docker-compose.yml
│ ├── docker-compose.kibana.yml
│ └── .env.template # Copy to .env and fill secrets
│
├── lab/ # Detection validation lab
│ ├── Vagrantfile # Windows 10 VM (ws01)
│ ├── Makefile # make up / validate / down / destroy
│ └── ansible/
│ ├── playbooks/
│ │ ├── deploy.yml # Provision VM (Sysmon, PS logging, Winlogbeat)
│ │ └── validate.yml # Run 11 benign detection simulations
│ └── roles/ # sysmon / winlogbeat / audit_logging
│
├── data/ # Structured intelligence dataset (YAML)
│ ├── sources.yaml # Source register with confidence tiers
│ ├── procedures.yaml # 10 procedure records (proc_mw_0001–0010)
│ ├── detections.yaml # 11 detection records with coverage scores
│ └── validation-results.yaml # Phase 5 lab validation output
│
├── detections/ # Detection logic by format
│ ├── sigma/ # Sigma rules
│ ├── kql/ # Kibana KQL queries
│ ├── elastic/ # Elastic rule JSON
│ └── spl/ # Splunk SPL
│
├── docs/
│ ├── article-step-0-project-scenario.md # Full project walkthrough (Phases 1–8)
│ ├── medium-article.md # Publication-ready Medium article
│ └── proofs/
│ ├── phase-3/ # OpenCTI graph screenshots (Steps 10–19)
│ ├── phase-4/ # Detection atlas review screenshots (Step 20)
│ └── phase-5/ # Kibana validation proofs (Steps 21–31)
│
└── tools/ # OpenCTI import scripts
```
## 快速开始
### 前置条件
| 工具 | 版本 | 用途 |
|------|---------|---------|
| Docker + Compose 插件 | 24+ | OpenCTI + Kibana 技术栈 |
| VirtualBox | 7.x | 实验室虚拟机管理程序 |
| Vagrant | 2.4+ | 虚拟机生命周期管理 |
| Ansible | 9+ | 虚拟机配置 + 模拟 |
| Python 3 + pywinrm | 任意 | Ansible WinRM 传输 |
```
# Ubuntu / Debian
sudo apt install docker.io docker-compose-plugin virtualbox vagrant ansible
pip3 install pywinrm
```
### 部署
```
# 1. Clone
git clone https://github.com/anpa1200/operation-desert-hydra.git
cd operation-desert-hydra
# 2. 配置 secrets
cp stack/.env.template stack/.env
$EDITOR stack/.env # fill in passwords and tokens
# 3. 启动所有内容
bash start.sh
```
`start.sh` 执行的操作:
1. 创建 `opencti_network` Docker 网络
2. 启动 OpenCTI + Elasticsearch + Kibana + Redis + MinIO + RabbitMQ
3. 等待 Elasticsearch 变为健康状态
4. 启动 Windows 10 Vagrant 虚拟机 (`ws01`)
5. 通过 Ansible 进行配置(Sysmon 15.x、Script Block Logging、Winlogbeat 8.13)
6. 运行所有 11 个检测模拟并打印结果
### 选项
```
bash start.sh --skip-lab # Start OpenCTI stack only (no VM)
bash start.sh --skip-validate # Deploy VM but skip simulations
bash stop.sh # Halt VM, leave stack running
bash stop.sh --destroy-vm # Destroy VM disk
bash stop.sh --destroy-stack # Stop Docker stack too
```
## 实验室架构
```
┌─────────────────────────────────────────────────────────────────────────┐
│ HOST MACHINE (Linux) │
│ │
│ ┌──────────────────────────────────────────────────────────────────┐ │
│ │ Docker: opencti_network │ │
│ │ │ │
│ │ ┌─────────┐ ┌───────────────┐ ┌──────┐ ┌───────────┐ │ │
│ │ │ OpenCTI │──▶│ Elasticsearch │ │Redis │ │ RabbitMQ │ │ │
│ │ │ :8080 │ │ :9200 │ │:6379 │ │ :5672 │ │ │
│ │ └─────────┘ └──────┬────────┘ └──────┘ └───────────┘ │ │
│ │ │ │ │
│ │ ┌─────────┐ │ ┌───────┐ │ │
│ │ │ Kibana │──────────┤ │ MinIO │ │ │
│ │ │ :5601 │ │ │ :9001 │ │ │
│ │ └─────────┘ │ └───────┘ │ │
│ └────────────────────────┼─────────────────────────────────────────┘ │
│ │ port 9200 exposed to host │
│ │ │
│ ┌────────────────┴──────────────────────────────┐ │
│ │ VirtualBox NAT gateway: 10.0.2.2 │ │
│ │ │ │
│ │ ┌──────────────────────────────────────────┐ │ │
│ │ │ ws01 — Windows 10 │ │ │
│ │ │ hostname: DESERTWS01 │ │ │
│ │ │ │ │ │
│ │ │ Sysmon 15.x ──logs──▶ │ │ │
│ │ │ Winlogbeat 8.13 ──────▶ 10.0.2.2:9200 │
│ │ │ Script Block Logging (EID 4104 enabled) │ │ │
│ │ │ ProcessAccess (EID 10 for LSASS) │ │ │
│ │ │ ImageLoad (EID 7) │ │ │
│ │ │ DNS events (EID 22) │ │ │
│ │ │ │ │ │
│ │ │ WinRM :55985 ◀── Ansible (host) │ │ │
│ │ └──────────────────────────────────────────┘ │ │
│ └────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
```
### 组件角色
| 组件 | 角色 | URL / 端口 |
|-----------|------|-----------|
| OpenCTI 6.2 | CTI 知识图谱 — 入侵集合、攻击活动、恶意软件、ATT&CK 关系 | :8080 |
| Elasticsearch 8.13 | 日志存储 — 接收来自实验室虚拟机的 Winlogbeat 事件;同时也是 OpenCTI 后端 | :9200 |
| Kibana 8.13 | 检测验证 — 针对获取验证截图对 Winlogbeat 索引运行 KQL 查询 | :5601 |
| Redis 7.2 | OpenCTI 会话 / 队列后端 | :6379 |
| MinIO | OpenCTI 文件存储 | :9001 |
| RabbitMQ 3.13 | OpenCTI worker 消息总线 | :5672 |
| ws01 (Windows 10) | 受测端点 — 由 Ansible 安装 Sysmon + Winlogbeat | WinRM :55985 |
### 日志流
```
Windows Event Log (Sysmon EID 1/7/10/11/13/22, PS EID 4104)
│
Winlogbeat 8.13
│ HTTPS → 10.0.2.2:9200
▼
Elasticsearch ←→ Kibana (KQL detection queries)
│
OpenCTI (knowledge graph backend shares the same ES instance)
```
## 检测覆盖
| ID | 检测 | 评分 | ATT&CK |
|----|-----------|:-----:|--------|
| det_mw_0001 | 邮件投递 → 进程创建关联 | 5 | T1566.001, T1566.002 |
| det_mw_0002 | Web 服务启动解释器 shell | 5 | T1190 |
| det_mw_0003 | PowerShell 编码命令 / IEX 脚本块 | 5 | T1059.001, T1027 |
| det_mw_0004 | 已签名可执行文件加载未签名 DLL | 3 | T1574.002 |
| det_mw_0005 | 注册表 Run 键 / 启动文件夹持久化 | 5 | T1547.001 |
| det_mw_0006 | 计划任务 — 43 分钟间隔 | 4 | T1053.005 |
| det_mw_0007 | 源自用户可写路径的 RMM 二进制文件 | 5 | T1219 |
| det_mw_0008a | 非浏览器进程 → Telegram Bot API | 3 | T1071.001, T1102 |
| det_mw_0008b | DNS 隧道 — 请求量 / 标签熵 | 5 | T1572 |
| det_mw_0009 | PowerShell WMI 查询 SecurityCenter2 | 5 | T1047, T1082, T1016, T1033, T1518.001 |
| det_mw_0010 | LSASS 内存访问 / 凭据工具执行 | 5 | T1003.001, T1003.004, T1003.005 |
**评分:** 5 = 实验室已验证,多来源 | 4 = 实验室已验证,单来源 | 3 = 验证不完整或失败(附有文档说明的原因)
**实验室结果:** 16 项规则检查中 14 项 PASS / 1 项 PARTIAL / 1 项 FAIL
**局限性:** 实验室模拟使用无害的 payload 来验证遥测数据的捕获——它们确认了检测技术栈能捕获到正确的事件,但并不代表规则能防范规避攻击。真实的攻击者工具包含了这些模拟中未涉及的混淆层。所有 ATT&CK 技术映射均属分析师候选评估,而非确证的攻击者归属。
## 验证证明
所有的 Kibana 截图均位于 `docs/proofs/phase-5/`:
| 文件 | 证明的内容 |
|------|---------------|
| step-21-det-mw-0001.png | EID 1 — wscript.exe → powershell.exe -EncodedCommand |
| step-22-det-mw-0002.png | EID 1 — wscript.exe → cmd.exe 侦察链 |
| step-23a-det-mw-0003-rule-a.png | EID 1 — powershell.exe -e + Base64 数据块 |
| step-23b-det-mw-0003-rule-b.png | EID 4104 — IEX + DownloadString |
| step-25a-det-mw-0005-rule-a.png | EID 13 — OutlookMicrosift Run 键 |
| step-25c-det-mw-0005-rule-c.png | EID 11 — 启动文件夹中的 WSF |
| step-26-det-mw-0006.png | EID 1 — schtasks.exe /mo 43 |
| step-27-det-mw-0007.png | EID 1 — 源自 \Temp\ 的 ScreenConnect.exe |
| step-29-det-mw-0008b.png | EID 22 — 180 次 DNS 查询,42 字符随机标签 |
| step-30a-det-mw-0009-rule-a.png | EID 4104 — SecurityCenter2 WMI 查询 |
| step-31a-det-mw-0010-rule-a.png | EID 10 — lsass.exe GrantedAccess 0x1400 |
| step-31c-det-mw-0010-rule-c.png | EID 11 — lsass_test.dmp 文件创建 |
## 项目阶段
| 阶段 | 交付物 | 状态 |
|-------|------------|--------|
| 1 | 来源登记表(8 个政府与厂商来源,按置信度分级) | 完成 |
| 2 | 操作过程数据集(10 条记录,已经过分析师审核) | 完成 |
| 3 | OpenCTI 知识图谱(入侵集合、攻击活动、恶意软件、ATT&CK) | 完成 |
| 4 | 检测图谱(11 个包含伪逻辑、误报(FP)、创建逻辑的检测项) | 完成 |
| 5 | 安全验证实验室(Ansible playbook,12 张 Kibana 验证) | 完成 |
| 6 | 覆盖矩阵(21 个操作过程技术 + 7 个来源集合技术,6 个能力关卡,差距分析) | 完成 |
| 7 | 最终报告(方法论 → 来源基础 → 覆盖范围 → 局限性 → 后续工作) | 完成 |
| 8 | 执行摘要(面向防御者的优先事项和遥测差距) | 完成 |
完整演练:[`docs/medium-article.md`](docs/medium-article.md)
**已发布于 Medium:**[沙漠九头蛇行动 — AI 辅助 CTI 流水线:从 MuddyWater 到 Kibana](https://medium.com/@1200km/operation-desert-hydra-ai-assisted-cti-pipeline-muddywater-to-kibana-34da7917acf0)
## 数据流水线 — 真实记录
本项目中的每一项主张都可以从原始来源追溯到最终的检测。该流水线为:
```
sources.yaml → claims.yaml → procedures.yaml → detections.yaml
```
**来源记录** (`data/sources.yaml`) — 每个采纳的来源对应一条记录,包含可靠性和可信度评级:
```
- id: src_usgov_aa22_055a_pdf_mirror
title: "AA22-055A: Iranian Government-Sponsored Actors Conduct Cyber Operations..."
publisher: "CISA / FBI / CNMF / NCSC-UK / NSA"
url: "https://media.defense.gov/2022/Feb/24/2002944274/-1/-1/0/CSA_AA22-055A..."
local_files:
raw: "docs/source-gathering/raw-sources/07-.../source.pdf"
text: "docs/source-gathering/raw-sources/07-.../source.txt"
source_type: "government_advisory"
source_reliability: "A"
information_credibility: 2
evidence_support: ["Reported", "Assessed"]
actor_claims: ["MuddyWater", "Seedworm", "Static Kitten", "TEMP.Zagros", "Iran MOIS"]
candidate_attck_techniques: ["T1566", "T1190", "T1574", "T1059.001", "T1219"]
promotion_decision: "promote"
```
**主张记录** (`data/claims.yaml`) — 绑定来源的原子级主张,带有证据标签:
```
- id: clm_mw_0006
source_id: src_usgov_aa22_055a_pdf_mirror
claim: >
MuddyWater spearphishing campaigns have used ZIP files containing either
malicious macro-enabled Excel files or PDFs that drop malicious files.
evidence_label: "Reported"
confidence: "High"
source_reliability: "A"
information_credibility: 2
technique_refs: ["T1566.001"]
supports:
procedure: true
detection: true
```
**操作过程记录** (`data/procedures.yaml`) — 从主张中提取的行为,包含遥测数据和检测思路:
```
- id: proc_mw_0006
title: "Persistence via Scheduled Task"
evidence_label: "Observed"
confidence: "High"
source_refs: ["src_incd_muddywater_2024_evolution"]
attck_candidates:
- technique: "T1053.005"
notes: "BugSleep creates a scheduled task triggered every 43 minutes for C2 beaconing"
procedure_summary: >
BugSleep establishes persistence and C2 beaconing regularity by creating
a Windows scheduled task triggered every 43 minutes.
required_telemetry:
- "Windows Security Event ID 4698 (scheduled task created)"
- "Sysmon Event ID 1: schtasks.exe with /create arguments"
detection_idea: >
Alert on tasks with repetition intervals not matching standard software
patterns (e.g., 43 minutes) with actions pointing to user-writable paths.
```
**检测记录** (`data/detections.yaml`) — 可部署的伪逻辑,包含覆盖评分和分析师创建逻辑:
```
- id: det_mw_0006
title: "Scheduled Task Created with Anomalous Short Repetition Interval"
techniques: ["T1053.005"]
coverage_score: 4
validation_status: lab_validated
pseudologic: |
# Rule A — Specific: PT43M interval (BugSleep artifact) — immediate alert
event_type = scheduled_task_created AND
task_trigger_repetition_interval = "PT43M"
# Rule B — Behavioral: short interval + suspicious action path
event_type = scheduled_task_created AND
task_trigger_repetition_interval_minutes < 60 AND
task_action_path MATCHES "(\\AppData\\|\\Temp\\|\\ProgramData\\)"
# Rule C — Sysmon fallback (many envs don't forward Task Scheduler logs)
event_type = process_create AND
image ENDSWITH "schtasks.exe" AND
command_line MATCHES "/create" AND
command_line MATCHES "(AppData|Temp|ProgramData)"
creation_logic: >
The 43-minute interval is the single most precise artifact in the dataset,
documented as BugSleep's specific C2 beacon interval in INCD 2024.
Rule A fires with near-zero false positives. Rule C is the telemetry
fallback when Task Scheduler event logs are not forwarded to SIEM.
```
**原始来源获取** (`docs/source-gathering/raw-sources/`) — 71 个候选来源中的每一个都已被获取并连同其元数据一起存储:
```
{
"number": 7,
"url": "https://media.defense.gov/2022/Feb/.../CSA_AA22-055A_...PDF",
"http_status": "200",
"kind": "pdf",
"size_bytes": 1220598,
"saved": true,
"raw_file": "docs/source-gathering/raw-sources/07-.../source.pdf",
"text_file": "docs/source-gathering/raw-sources/07-.../source.txt"
}
```
## 防御性用途与局限性
本项目的范围和目的均限于防御。
**实验室执行的操作:**
- 使用标准系统工具和 PowerShell 脚本运行无害的模拟
- 没有活跃的恶意软件、没有真实的 C2、没有凭据外泄
- 在 LSASS 模拟(步骤 31)期间创建的 `.dmp` 文件会在事件确认后立即删除
- 虚拟机不连接到真实的外部服务(Telegram 等)
- 所有 payload 均记录在 `lab/ansible/playbooks/validate.yml` 中
**验证证明了什么以及未证明什么:**
- 实验室结果确认了检测技术栈能够为每种行为捕获正确的遥测事件
- 它们并不能证明规则能防范规避攻击 — 真实的攻击者工具使用了这些模拟中不存在的混淆、时间变化和 LOLBins
- 所有 ATT&CK 技术映射都是基于公开来源主张的分析师候选评估,而非确证的攻击者归属
- 覆盖评分是保守的:评分 5 需要提供 Kibana 截图,而不仅仅是通过的伪逻辑
**已知失败项:**
- `det_mw_0008a`(Telegram Bot API):FAIL — VirtualBox NAT 转换了外部连接;Sysmon 看到的是 10.0.2.2,而不是 api.telegram.org。规则正确;记录了实验室架构限制。
- `det_mw_0004`(DLL 侧加载):PARTIAL — 4 字节的 PE 存根在 EID 7 触发之前被 Windows 加载程序拒绝。规则正确;需要真实编译的 DLL 才能验证。
## 工作原则
- 仅使用公开来源的 CTI — 不包含任何机密或受限材料。
- ATT&CK 映射是候选映射,而不是归属证据。
- AI 辅助的研究在经过分析师审核之前均被视为不可信。
- 实验室中没有活跃的恶意软件、没有真实的 C2、没有凭据外泄。
- 所有 `.dmp` 文件在事件确认后立即删除。
- 覆盖评分是保守的 — 评分 5 需要 Kibana 证明,而不仅仅是通过的逻辑。
标签:OpenCanary, OpenCTI, 威胁情报, 安全知识图谱, 安全运营, 开发者工具, 扫描框架, 知识库安全, 系统提示词, 请求拦截, 越狱测试, 逆向工具