Mlassout/anssi-cve-analysis
GitHub: Mlassout/anssi-cve-analysis
一个用于自动化提取、富化并利用机器学习分析 ANSSI 安全公告中漏洞数据(CVE)的 Python 数据处理与分析流水线。
Stars: 0 | Forks: 0
# 结合 CVE 扩展分析 ANSSI 公告与警报
**EFREI 2026 — MasterCamp 网络安全**
Python 课程 · S. Chendeb 教授
## 团队成员
| 姓名 | 名字 | 参与度 |
|-----|--------|--------------|
| Martin | Lucas | 25% |
| Dubois | Sophie | 25% |
| Chen | Alexandre | 25% |
| Rousseau | Camille | 25% |
### 任务详细分配
**Lucas Martin (25%)**
- 实现 `src/extraction.py`:读取 ANSSI JSON 文件,通过 regex 识别 CVE
- 在 notebook 中开发 K-Means 聚类模块(无监督 ML 步骤)
- 审查并测试 DataFrame 的整合
**Sophie Dubois (25%)**
- 实现 `src/enrichissement.py`:提取 MITRE(CVSS、CWE)和 FIRST(EPSS)数据
- 处理异常并增强对不同 JSON 格式变体(cvssV3_0、cvssV3_1、cvssV4_0)的鲁棒性
- 实现 `src/alertes.py`:生成警报和电子邮件正文
**Alexandre Chen (25%)**
- 实现 `src/consolidation.py`:构建 Pandas DataFrame,规范化类型
- 在 notebook 中开发监督式 Random Forest 模型和交叉验证
- 构建主 pipeline `main.py`
**Camille Rousseau (25%)**
- 开发 notebook 中的所有可视化(10 个图表)
- 探索性数据分析与结果解释
- 编写 README,组织项目,清理数据
## 项目描述
本项目分析由 **ANSSI**(法国国家信息系统安全局)通过其 CERT-FR 发布的**安全公告**。目标是构建一个自动化的 pipeline,使其能够:
1. **提取** ANSSI 公报(公告和警报)中的数据
2. **识别** 公报中提到的 CVE 标识符
3. **扩展** CVE 的外部数据(通过 MITRE 获取的 CVSS 分数,通过 FIRST/EPSS 获取的利用概率)
4. **整合** 数据至 Pandas DataFrame 并导出为 CSV
5. **分析与可视化** 漏洞(分布、相关性、时间演变)
6. **应用机器学习模型** 进行细分和预测风险等级
7. **生成个性化警报**,针对受严重影响的产品
## 工作流程
```
Données locales (data/)
│
▼
[Étape 1+2] Extraction & Identification CVE
src/extraction.py
├── data/avis/ → 4 027 fichiers JSON
└── data/alertes/ → 78 fichiers JSON
│
▼
[Étape 3] Enrichissement CVE
src/enrichissement.py
├── data/mitre/ → Score CVSS, type CWE, description
└── data/first/ → Score EPSS (probabilité d'exploitation)
│
▼
[Étape 4] Consolidation DataFrame
src/consolidation.py
└── output/vulnerabilites_anssi.csv
│
▼
[Étape 5+6] Analyse, Visualisation & Machine Learning
analyse_vulnerabilites.ipynb
│
▼
[Étape 7] Génération d'alertes & Notifications
src/alertes.py
```
## 文件结构
```
Projet ANSSI/
├── data/
│ ├── avis/ # 4 027 fichiers JSON (bulletins avis CERT-FR)
│ ├── alertes/ # 78 fichiers JSON (bulletins alertes CERT-FR)
│ ├── mitre/ # 37 279 fichiers JSON (données CVE MITRE)
│ └── first/ # 37 279 fichiers JSON (scores EPSS FIRST)
├── src/
│ ├── __init__.py
│ ├── extraction.py # Étape 1+2 : extraction bulletins + CVE
│ ├── enrichissement.py # Étape 3 : enrichissement MITRE + EPSS
│ ├── consolidation.py # Étape 4 : DataFrame + export CSV
│ └── alertes.py # Étape 7 : alertes + email
├── output/
│ └── vulnerabilites_anssi.csv # Généré par main.py
├── main.py # Pipeline complet
├── analyse_vulnerabilites.ipynb # Notebook : analyse + ML
├── requirements.txt
└── README.md
```
## 安装与运行
### 前置条件
- Python 3.9 或更高版本
- pip
### 安装依赖项
```
pip install -r requirements.txt
```
### 运行 pipeline(生成 CSV)
```
python main.py
```
预期结果将保存在 `output/vulnerabilites_anssi.csv` 中。
### 打开分析 notebook
```
jupyter notebook analyse_vulnerabilites.ipynb
```
### 导出 notebook 为 HTML
```
jupyter nbconvert --to html --execute analyse_vulnerabilites.ipynb
```
## 数据说明
### 源数据(ANSSI CERT-FR)
| 文件夹 | 类型 | 数量 | 内容 |
|---------|------|--------|---------|
| `data/avis/` | 安全公告 | 4,027 个文件 | 已知漏洞 + 建议 |
| `data/alertes/` | 严重警报 | 78 个文件 | 正在被利用的漏洞 |
每个 JSON 文件包含:
- `reference`:ANSSI 标识符(例如 `CERTFR-2023-AVI-0001`)
- `title`:公报标题
- `summary`:漏洞摘要
- `cves`:引用的 CVE 列表 `[{name, url}]`
- `affected_systems`:受影响的产品 `[{product: {name, vendor}}]`
- `revisions`:版本历史,`revisions[0].revision_date` = 发布日期
- `risks`:相关风险
### 扩展数据
**MITRE CVE API** (`data/mitre/CVE-XXXX-XXXXX`):
- 通过 `containers.cna.metrics[].cvssV3_1.baseScore` 获取 CVSS 分数(0–10)
- 严重程度:`baseSeverity`(Critical / High / Medium / Low)
- CWE 类型:`containers.cna.problemTypes[].descriptions[].cweId`
- 描述、发布者、产品、受影响版本
**FIRST EPSS API** (`data/first/CVE-XXXX-XXXXX`):
- EPSS 分数(0–1):未来 30 天内的利用概率
- 百分位:在所有已知 CVE 中的排名
## 数据清理与处理
### 缺失值处理
| 问题 | 解决方案 |
|----------|---------|
| `mitre/` 文件夹中缺失 CVE | CVSS/CWE 使用 `None` 值,文本字段使用 `"Non disponible"` |
| `first/` 文件夹中缺失 CVE | EPSS 使用 `None` 值 |
| 日期缺失或格式错误 | `pd.to_datetime(..., errors='coerce')` → `NaT` |
| MITRE 中缺失 `metrics` 字段 | 多格式处理:`cvssV4_0` → `cvssV3_1` → `cvssV3_0` → `cvssV2_0` |
| 没有引用 CVE 的公报 | 保留该行并设 `CVE = "N/A"`(未识别出漏洞的公报) |
| 发布者/产品多值 | 拼接字符串 `"Microsoft, Apache"` — 为进行机器学习,使用 `str.split(',').str[0]` 进行清理 |
### 规范化
- **日期**:从 `revisions[0].revision_date`(ISO 格式)提取,转换为 `pd.Timestamp`
- **CVSS**:通过 `pd.to_numeric` 进行强制类型转换
- **EPSS**:介于 0 和 1 之间的浮点数 — 乘以 100 以百分比显示
- **严重程度**:统一化(`Critical` → `Critique`,`High` → `Élevée` 等)以适配法语可视化界面
- **CVE**:使用 regex `CVE-\d{4}-\d{4,7}` 进行验证,以消除误报
### 整合后的 DataFrame 结构
| 列名 | 类型 | 说明 |
|---------|------|-------------|
| `ID_ANSSI` | str | 公报引用(例如 `CERTFR-2023-AVI-0001`) |
| `Titre` | str | 公报标题 |
| `Type` | str | `Avis` 或 `Alerte` |
| `Date` | datetime | 首次发布日期 |
| `CVE` | str | CVE 标识符(例如 `CVE-2023-24488`) |
| `CVSS` | float | CVSS 分数 0–10 |
| `Base_Severity` | str | `Critical` / `High` / `Medium` / `Low` |
| `CWE` | str | CWE 标识符(例如 `CWE-79`) |
| `CWE_Description` | str | CWE 类型的文本说明 |
| `EPSS` | float | EPSS 分数 0–1 |
| `EPSS_Percentile` | float | EPSS 百分位 |
| `Lien` | str | 指向 CERT-FR 公报的 URL |
| `Description` | str | 漏洞描述 (MITRE) |
| `Editeur` | str | 受影响产品的发布者名称 |
| `Produit` | str | 受影响产品的名称 |
| `Versions_Affectees` | str | 受影响版本(列表) |
| `Risques` | str | ANSSI 公报中描述的风险 |
## 机器学习模型
### 无监督模型 — K-Means 聚类
**目标**:在没有预定义标签的情况下,按风险特征对 CVE 进行分组。
**模型选择**:由于数据(CVSS、EPSS)是数值且连续的,K-Means 非常适合。质心的可解释性使得为聚类打标签变得容易。
**特征**:`CVSS`、`EPSS`(通过 `StandardScaler` 进行标准化)
**K 值选择**:
- 基于组内平方误差和 (WCSS) 惯性的肘部法则
- 轮廓系数 评分用于验证组内聚度
**结果**:选定 K=3:
| 聚类 | 平均 CVSS | 平均 EPSS | 标签 |
|---------|-----------|-----------|-------|
| 0 | ~4.5 | ~0.02 | Risque faible |
| 1 | ~7.2 | ~0.08 | Risque modéré |
| 2 | ~8.9 | ~0.35 | Risque élevé |
**验证**:轮廓系数 > 0.45
### 监督模型 — Random Forest 分类器
**目标**:根据本身不需要 CVSS 分数的上下文数据,预测 CVE 是否属于高风险 (CVSS ≥ 7.0)。
**模型选择**:Random Forest 对缺失值具有鲁棒性,能很好地处理不平衡的数据集 (`class_weight='balanced'`),并且原生提供特征重要性。
**目标变量**:如果 CVSS ≥ 7.0,则 `Haut_Risque` = 1,否则为 0
**选定特征**:
| 特征 | 理由 |
|---------|---------------|
| `EPSS` | 实际利用情况的主要指标 |
| `Type_Enc` | 警报通常对应更高的风险 |
| `CWE_Code` | 某些 CWE 类别本身就更严重 |
| `Annee` | 近年来 CVSS 分数存在通货膨胀的趋势 |
**超参数**:
- `n_estimators=200`,`max_depth=8`,`min_samples_leaf=5`
- 80%/20% 分层划分
**验证**:
- 5 折分层交叉验证
- 指标:准确率、精确率、召回率、F1 分数
- ROC 曲线 / AUC
## 可视化结果(步骤 5)
1. **CVSS 分数直方图** + 按严重程度划分的分布
2. **EPSS 递减曲线** + 分布
3. **CWE 图表**:前 12 名柱状图 + 前 8 名饼图
4. **受影响最严重的主要发布者和产品**(水平柱状图)
5. **CVSS 与 EPSS 散点图**(按严重程度着色)+ 相关性热力图
6. **月度时间演变**(公告 vs 警报)+ 累积曲线
7. **按发布者划分的 CVSS 箱线图**(前 12 名)
8. **公告与警报对比**(平均 CVSS、平均 EPSS、分布)
9. **按年份和严重程度划分的堆叠柱状图** + 聚焦严重 CVE (CWE)
10. **按公报类型划分的发布者**(水平堆叠柱状图)
11. **肘部法则 + 轮廓系数** 用于 K 值选择
12. **按聚类着色的 K-Means 散点图** + 风险特征饼图
13. **混淆矩阵** + ROC 曲线 + 特征重要性
14. **5 折交叉验证** 按指标和按折数
## 警报和通知(步骤 7)
模块 `src/alertes.py` 会针对以下 CVE 生成个性化警报:
- CVSS 分数 ≥ 7.0(高危或严重漏洞)
- **或** EPSS 分数 ≥ 0.5(被活跃利用的高概率)
每个警报包含:
- ANSSI 公报引用和类型(公告/警报)
- CVE、CVSS 分数、EPSS 分数、CWE 类型
- 受影响的产品和发布者、受影响版本
- 漏洞说明
- 指向完整公报的链接
- 行动建议
**通过 SMTP 发送电子邮件是可选的**(在 `main.py` 中设置参数 `send=True`)。
即使不发送,系统也会生成并显示每封电子邮件的主题和正文。
## 负责任的外部访问管理
按照课程要求,本项目**完全使用本地存储的预下载数据**:
- 执行期间不向 ANSSI、MITRE 或 FIRST API 发送任何 HTTP 请求
- `data/mitre/` 和 `data/first/` 文件夹包含了 API 的 JSON 响应
- 如果本地数据中缺少某个 CVE,该值将被标记为 `None` / `"Non disponible"`,且不会报错
这种方法保护了外部服务器并保证了执行的可重复性。
## 交付成果
- [x] 可运行的 Python 代码(`src/`, `main.py`)
- [x] 整合的 CSV 文件(`output/vulnerabilites_anssi.csv`)
- [x] Jupyter Notebook(`analyse_vulnerabilites.ipynb`)
- [x] 导出为 HTML 的 Notebook(通过 `nbconvert` 生成)
- [x] 完整的 README(本文件)
- [ ] 3 分钟演示视频(无音频)
标签:Apex, CVE, NoSQL, Python, XSS, 代码示例, 后端开发, 数字签名, 数据分析, 数据流水线, 无后门, 机器学习, 漏洞情报, 逆向工具