Slackpartistic/CCTI
GitHub: Slackpartistic/CCTI
一款通过组织画像对 MISP 威胁情报进行评分和个性化推荐的端到端 CTI 处理 pipeline。
Stars: 0 | Forks: 0
# CCTI — 精选网络威胁情报
各组织常常被大量对自身并不适用的威胁情报所淹没。CCTI 通过构建一个端到端的 pipeline 来解决这个问题:它从 MISP 获取实时威胁数据,提取有意义的实体,根据各组织的特定配置画像对每个威胁进行评分,并通过 Web 仪表板和 REST API 呈现最相关的威胁。
## 工作原理
系统作为一个九步 pipeline 运行:
1. **获取** — 从 MISP REST API 拉取实时事件
2. **过滤** — 从可用的 CTI 数据集中剔除重复项、原始指标和低信号噪声
3. **格式化** — 将过滤后的属性转换为支持 NER 的文本记录
4. **NER** — 使用 spaCy + SecBERT 的混合 pipeline 提取命名实体。实体包括:威胁行为者、恶意软件、攻击技术、技术栈、行业、CVE 和 IOC
5. **标准化** — 将自由文本的 MITRE 技术名称映射到官方 T-codes
6. **STIX** — 将 NER 输出转换为 STIX 2.1 bundle 以实现互操作性
7. **推荐** — 使用 TF-IDF 余弦相似度 + CPE 资产匹配 + MITRE ATT&CK 重叠度,针对每个组织的配置画像对所有威胁进行评分
8. **评估** — 自动化质量检查:MITRE 覆盖率、跨组织区分度
9. **接入** — 将 STIX bundle 和推荐结果加载到 ChromaDB 中,以支持基于 RAG 的自然语言查询
评分公式:
```
Final Score = (TF-IDF cosine + CPE boost + MITRE bonus) × severity_multiplier × 100
```
来自 NER 步骤的实体置信度分数会被传递到评分中 — 通过正则表达式提取的 T-codes(置信度 0.98)比 spaCy 的推测(0.75)贡献更大。
## 前置条件
在运行任何操作之前,您需要:
1. **一个 MISP 实例** — pipeline 会从我们基于官方 MISP 指南部署和配置的云端托管 MISP 实例中获取实时威胁数据。在本项目中,使用 `misp.cti-lab.me` 作为 CTI 数据源。要使用您自己的实例,请在 `.env` 中设置 `MISP_BASE_URL`。
2. **MISP API 密钥** — 在您的 `.env` 文件中设置 `MISP_API_KEY`(从 `.env.example` 复制)。
- 打开 `https://misp.cti-lab.me`。
- 使用课程或实验室主管提供的管理员凭据登录。
- 转到 **Admin → Auth keys → Add authentication key**。
- 将生成的密钥复制到 `.env` 中:
MISP_API_KEY=replace-with-your-misp-api-key
3. **SecBERT 模型权重** — `model.safetensors` (331MB) 由于体积过大而被排除在代码库之外。如果要使用 `--use-secbert`,请重新训练模型或获取该权重文件并将其放在 `Machine learning/secbert_cti_model_final/` 目录中。如果没有它,pipeline 仅使用 spaCy 也能正常运行。
4. **Groq API 密钥** *(可选 — 用于启用 SOC AI Chat)* — 仪表板包含一个由 Groq 提供支持的、基于 RAG 的 SOC AI Chat 面板。如果没有密钥,仪表板仍然可以正常工作;只是聊天面板会被禁用。
- 在 [console.groq.com](https://console.groq.com) 创建一个 API 密钥。
- 创建一个 API 密钥并将其添加到您的 `.env` 中:
GROQ_API_KEY=replace-with-your-groq-api-key
- 之所以选择 Groq 而不是自托管模型(例如 Ollama),是为了让 `docker compose up` 无需下载大模型,从而保持部署的轻量化,并适用于任何客户端机器。
## 运行 pipeline
### Docker(推荐 — 自动处理所有依赖)
```
cp .env.example .env # fill in MISP_API_KEY
./deploy.sh # build image, run pipeline, start API
# → http://localhost:8000
```
要在部署期间启用可选的 SecBERT 提取层:
```
PIPELINE_ARGS="--use-secbert" ./deploy.sh
```
要使用现有的 pipeline 数据启动 API 和仪表板:
```
docker compose up -d api
```
### 本地(开发环境)
```
cp .env.example .env
pip install -r requirements.txt
python -m spacy download en_core_web_sm
python pipeline.py # full run (all 9 steps)
python pipeline.py --skip-fetch # use existing MISP data
python pipeline.py --skip-recommend # steps 1-5 only
python pipeline.py --use-secbert # enable SecBERT NER layer
cd cti_microservice_v1
python dashboard_only.py # dashboard and REST endpoints, fast startup
python api.py # dashboard, REST endpoints, and RAG Q&A
# → http://localhost:8000
```
### 测试
```
pytest # run all tests
pytest filtering/tests/
pytest cti_microservice_v1/tests/
pytest tests/
```
### 迁移到其他服务器或本地机器
只要谨慎迁移配置文件和生成的运行时数据,该项目就是可移植的:
1. 在新机器上克隆该代码库。
2. 将 `.env.example` 复制到 `.env` 并重新设置所需的值。不要通过 Git 提交或复制旧的密钥。
3. 如果您想保留当前的演示数据,请从旧服务器复制以下生成的文件夹/文件:
- `data/misp/`
- `data/cleaned/`
- `data/recommendations/`
- `ner/ner_results_v3.json`
- `ner/ner_results_v3_normalised.json`
- `cti_microservice_v1/curated_threats_stix3.json`
- `cti_microservice_v1/vector_store/`
4. 如果要重复使用加密文件,请将相同的 `CCTI_ENCRYPTION_KEY` 复制到新的 `.env` 中。如果没有原始密钥,将无法读取加密的 JSON 文件。
5. 重新构建并启动服务:
docker compose build
docker compose up -d api
6. 如果您不复制生成的数据,请运行全新的 pipeline:
./deploy.sh
对于云迁移,还需要更新 DNS、防火墙规则、HTTPS 反向代理设置,以及任何与旧主机绑定的外部 MISP/Groq 密钥。
## 项目结构
```
CCTI/
├── pipeline.py # Canonical 9-step pipeline entry point
├── recommendation_engine.py # TF-IDF + CPE + MITRE scoring engine
├── evaluation.py # Cross-org evaluation and ablation tests
├── normalise_techniques.py # MITRE T-code normalisation
├── stix_generator.py # STIX 2.1 bundle generation
├── crypto_utils.py # Fernet at-rest encryption utilities
├── encrypt_profiles.py # One-time org profile encryption script
│
├── filtering/ # Noise reduction pipeline
│ ├── cti_filter.py # Core filtering logic
│ ├── rules.json # Tunable filter rules
│ └── tests/ # Filter unit tests
│
├── ner/ # Named entity recognition
│ ├── ner_cti.py # spaCy + SecBERT hybrid extractor
│ ├── cti_data_formatting.py # Converts filtered CTI to NER input
│ ├── ner_results_v3.json # Raw NER output
│ └── ner_results_v3_normalised.json # Normalised NER output
│
├── Machine learning/ # SecBERT fine-tuning
│ ├── train_secbert.py # Fine-tune SecBERT on CTI NER data
│ ├── prepare_cyner.py # Convert CyNER dataset to training format
│ ├── rescue_aligner.py # BIO tag alignment for training data
│ ├── secbert_train_data.json # Original training data
│ ├── train_data/ # CyNER CoNLL files (train/valid/test)
│ └── secbert_cti_model_final/ # Trained model (model.safetensors gitignored)
│
├── cti_microservice_v1/ # FastAPI REST API + web dashboard
│ ├── api.py # Full API with RAG engine
│ ├── dashboard_only.py # Lightweight server (dashboard only)
│ ├── threats_endpoints.py # All REST endpoints
│ ├── rag_engine.py # RAG Q&A engine (two-pass retrieval: org metadata sort + semantic search)
│ ├── data_ingestor.py # Ingests STIX + recommendations into ChromaDB
│ ├── config.py # Environment-variable configuration
│ └── static/index.html # Frontend dashboard (Chart.js + Plotly; clickable threat cards with AI analysis)
│
├── Profiling/ # Organisation profiles
│ ├── Schemas/ # JSON schema for profiles
│ └── Instances/ # 12 org profiles across Finance, Healthcare, Energy, Other
│
├── data/ # CTI source data
│ ├── Feodo.json # C2 tracker feed
│ ├── Malware Bazaar.json # Malware samples feed
│ ├── OpenPhish.json # Phishing URLs
│ ├── URLHaus.json # Malicious URLs
│ ├── phishtank.json # Phishing database
│ ├── misp/ # Live MISP fetch output (gitignored)
│ ├── cleaned/ # Filter pipeline output (gitignored)
│ └── recommendations/ # Recommendation engine output (gitignored)
│
├── Dockerfile # Container image definition
├── docker-compose.yml # Two services: api (24/7) + pipeline (one-shot)
├── deploy.sh # Digital Ocean deployment script
├── .env.example # Environment variable template
└── requirements.txt # Python dependencies
```
## 评估结果
评估输出在第 8 步生成并写入:
```
data/recommendations/evaluation_report_.json
data/recommendations/evaluation_report_.txt
```
具体计数会因最新的 MISP 拉取、过滤输出、NER 结果和可用的推荐文件而有所不同。请使用带有最新时间戳的报告来查看当前运行情况。
**最新已验证运行的快照(2026 年 6 月):**
| 指标 | 结果 |
|--------|--------|
| 评估的组织 | 12 个(金融、医疗、能源、其他) |
| 评分的 CTI 事件 | 567 |
| MITRE 匹配度 | 全部 12 个组织 PASS,95–100% 的 top-N 命中 |
| 最大 MITRE 提升 | +47.5 分 (ORG-EN-001) |
| 跨组织区分度 | 能源与医疗重叠度:0% |
| 处理的 IoC | 669,274 |
| NER 丰富化记录 | 5,085 |
| 接入的 ChromaDB chunks | 14,429(STIX 指标 + 精选推荐) |
## 安全性
- MISP API 密钥存储在环境变量中,绝不存储在源代码中
- SSL 证书验证可通过 `MISP_VERIFY_SSL` / `MISP_CA_BUNDLE` 进行配置
- 对原始事件、过滤后的数据、推荐结果、评估报告和组织配置文件进行静态加密(AES-128 Fernet)— 由 `CCTI_ENCRYPTION_KEY` 控制
- 所有 API 响应中均已剔除内部 MISP 标识符
## NER 方法
NER pipeline 使用了两个模型的混合方案:
| 来源 | 模型 | 置信度 | 实体 |
|--------|-------|------------|---------|
| Regex | 模式匹配 | 0.95–0.98 | CVE、T-codes、IP、哈希值 |
| Dictionary | MITRE ATT&CK 查找 | 0.90 | 威胁行为者、技术 |
| spaCy | en_core_web_sm | 0.75 | 组织、产品 |
| SecBERT | 在 CyNER 上微调 | 0.80 | 行为者、TTP、技术、行业 |
SecBERT (`jackaduma/SecBERT`) 在由 4,856 个句子组成的混合数据集上进行了微调,这些句子来自 CyNER 语料库和现有的 CTI 训练数据。可通过 `--use-secbert` 启用。
## 技术栈
| 组件 | 技术 |
|-----------|-----------|
| 威胁情报源 | MISP REST API |
| NER | spaCy + SecBERT (HuggingFace Transformers) |
| 评分 | scikit-learn TF-IDF, MITRE ATT&CK |
| 加密 | cryptography (Fernet) |
| 威胁格式 | STIX 2.1 |
| 向量数据库 | ChromaDB + all-MiniLM-L6-v2 |
| RAG | LangChain + Groq (Llama 3.1) |
| API | FastAPI + Uvicorn |
| 前端 | Vanilla JS, Chart.js, Plotly |
| 部署 | Docker, Digital Ocean |
| 语言 | Python 3.11 |
## 团队成员
| 姓名 | 角色 |
|------|------|
| Maaz Arshad Beg | 技术负责人、系统集成、pipeline、安全 |
| Aini Li | 过滤优化、仪表板、部署 |
| Zexin Zhao | SecBERT 模型训练、ML pipeline |
| Jiarui Li | 组织配置画像、前端 |
| Freshin Francis | 推荐引擎、相似度匹配、前端开发 |
指导教师:Mamello Thinyane 教授,阿德莱德大学
标签:Web仪表盘, 威胁情报, 开发者工具, 数据管道, 网络安全, 请求拦截, 软件工程, 逆向工具, 隐私保护