mahathirmuh/ad-anomaly-detection
GitHub: mahathirmuh/ad-anomaly-detection
基于 Neo4j 知识图谱和集成无监督机器学习的 Active Directory 用户行为异常检测与可解释性分析流水线。
Stars: 0 | Forks: 0
# AD 审计 — 异常检测流水线
基于知识图谱(Neo4j)和集成机器学习的 Active Directory 用户行为异常检测系统。
## 流水线架构
```
Raw AD Logs
│
▼
[Phase 2] Neo4j Ingestion → Knowledge Graph (7 node types, 8 rel types)
│
▼
[Phase 3] Rule-Based Engine → 7 domain rules → flag pelanggaran per user
│
▼
[Phase 4] Graph Feature Extraction → 8 fitur ML dari graph
│
▼
[Phase 5] Ensemble Anomaly Detection → IF + LOF + EE → anomaly score
│
▼
[Phase 5.5] SHAP Explainability → top cause per user
│
▼
[Phase 6] Reporting → laporan teks, JSON, DOCX
```
## 前置条件
### 软件
| 软件 | 版本 | 说明 |
|----------|-------|------------|
| Python | 3.10+ | 推荐 3.12 |
| Neo4j | 5.x | 社区版或企业版 |
| Jupyter | 1.0+ | 用于运行 notebook |
### 安装 Python 依赖
```
pip install -r requirements.txt
```
或使用安装脚本(Linux/Mac):
```
bash setup.sh
```
主要依赖:`neo4j`、`pandas`、`numpy`、`scikit-learn`、`shap`、`matplotlib`、`python-docx`
## 配置
编辑 **`pipeline_adaudit.ipynb`** 中的配置部分(第二个 cell),或直接在各个脚本中修改:
```
NEO4J_URI = "bolt://localhost:7687"
NEO4J_USER = "neo4j"
NEO4J_PASSWORD = "lalarasa" # ganti dengan password Neo4j Anda
DATA_CSV = "data/restructured_data/unified_logon_events.csv"
```
在运行流水线之前,请确保 Neo4j 已经启动:
- **桌面版**:打开 Neo4j Desktop → 点击 **Start**
- **服务**:`neo4j start` 或 `net start neo4j`
- **验证**:在浏览器中打开 `http://localhost:7474`
## 输入数据结构
将原始的 CSV 文件放在 `data/raw_data/` 文件夹中,格式如下:
| 文件 | 说明 |
|------|------------|
| `Domain Controller Logon Activity.csv` | DC 登录事件 |
| `2. Member Server Logon Activity.csv` | 成员服务器登录事件 |
| `Logon Failures.csv` | 登录失败事件 |
| `Recently Added Members to Security Groups.csv` | 安全组成员添加记录 |
合并后的文件位于 `data/restructured_data/unified_logon_events.csv`(包含 180 万以上条事件)。
## 运行方法
### 选项 1 — Jupyter Notebook(推荐)
```
jupyter notebook pipeline_adaudit.ipynb
```
按顺序从上到下逐个运行 cell。每个阶段都有一个 Markdown 说明的 cell,其后是代码 cell。
### 选项 2 — 直接运行 Python 脚本
在终端中按顺序运行:
```
# 阶段 2:将数据导入 Neo4j (旧版,仅运行一次)
python neo4j_ingest_phase2.py
# 阶段 3:应用 7 个领域规则
python neo4j_phase3_rules.py
# 阶段 4:从 graph 中提取 8 个特征
python neo4j_phase4_features.py
# 阶段 5:Ensemble anomaly detection
python neo4j_phase5_anomaly.py
# 阶段 5.5:SHAP explainability
python neo4j_phase55_shap.py
# 阶段 6:生成完整报告
python neo4j_phase6_reporting.py
```
## 各阶段详情
### 阶段 2 — Neo4j 数据导入
**脚本:** `neo4j_ingest_phase2.py`
**输入:** `data/restructured_data/unified_logon_events.csv`
**输出:** 包含节点和关系的 Neo4j 图
创建的节点类型:
| 节点 | 关键属性 | 说明 |
|------|-------------|------------|
| `User` | `user_id` | AD 用户账户 |
| `Hostname` | `hostname` | 工作站/计算机 |
| `Server` | `server_id` | 被访问的服务器 |
| `IPAddress` | `ip_address` | IP 地址 |
| `Service` | `service_name` | 被访问的服务 |
| `Group` | `group_name` | 安全组 |
| `Event` | `event_id` | Windows 事件 |
关系类型:
| 关系 | 起点 | 终点 | 说明 |
|-------------|------|----|------------|
| `LOGIN_FROM` | User | Hostname | 从工作站登录 |
| `AUTHENTICATED_VIA` | User | Server | 向服务器进行身份验证 |
| `FAILED_LOGIN` | User | Server | 登录失败 |
| `CONNECTED_FROM` | User | IPAddress | 从 IP 连接 |
| `USED_SERVICE` | User | Service | 使用的服务 |
| `MEMBER_OF` | User | Group | 组成员 |
### 阶段 3 — 基于规则的知识引擎
**脚本:** `neo4j_phase3_rules.py`
**输出:** 每个 User 节点上的 `rule_violations` 属性和标志
| 规则 ID | 名称 | 异常条件 |
|---------|------|----------------|
| R001 | 多主机登录 | 从 > 3 个唯一主机登录 |
| R002 | 非工作时间登录 | > 10% 的登录发生在 08:00–18:00 之外 |
| R003 | 共享设备 | 设备被 > 5 个不同用户使用 |
| R004 | 关键服务器访问 | 访问 Domain Controller 或 CRITICAL/HIGH 服务器 |
| R005 | 登录失败激增 | > 50 次登录失败 |
| R006 | 异常 IP | > 20% 的连接来自 Office/VPN 之外的 IP |
| R007 | 非工作时间特权操作 | 管理员在工作时间之外或周末访问 DC |
### 阶段 4 — 图特征提取
**脚本:** `neo4j_phase4_features.py`
**输出:** `data/phase4_graph_features.csv`
| 特征 | 说明 | 范围 |
|-------|-----------|-------|
| `host_diversity` | 相对于平均值的唯一主机数量 | 0–N |
| `critical_server_ratio` | 访问关键服务器的比例 | 0.0–1.0 |
| `failure_ratio` | 登录失败次数 / 总登录次数的比例 | 0.0–1.0 |
| `shared_device_risk` | 所访问设备中平均每台设备的用户数 | 1–N |
| `ip_network_risk` | 办公网络/VPN 之外的 IP 比例 | 0.0–1.0 |
| `privilege_level` | 最高特权级别(1=普通用户,4=管理员) | 1–4 |
| `connectivity` | 图中的度中心性 | 0.0–1.0 |
| `rule_violations` | 违反的规则数量 | 0–7 |
### 阶段 5 — 集成异常检测
**脚本:** `neo4j_phase5_anomaly.py`
**输出:** `data/phase5_anomaly_results.csv`、`data/phase5_anomalies_summary.csv`、`models/`
组合了三种算法:
| 模型 | 方法 | 优势 |
|-------|--------|---------|
| Isolation Forest (IF) | 随机划分 | 适用于全局异常 |
| Local Outlier Factor (LOF) | 基于密度 | 适用于局部异常 |
| Elliptic Envelope (EE) | 鲁棒协方差 | 适用于高斯分布 |
**最终得分公式:**
```
final_score = 0.60 × ensemble_votes_ratio + 0.40 × rule_violations_score
```
**异常判定标准:** 如果 3 个模型中有 >= 2 个达成一致,则该用户被判定为异常。
**严重程度分类:**
| 严重程度 | 得分阈值 |
|----------|---------------|
| CRITICAL | >= 0.7 |
| HIGH | >= 0.5 |
| MEDIUM | >= 0.3 |
| LOW | >= 0.1 |
| NORMAL | < 0.1 |
模型保存在 `models/` 文件夹中:
- `isolation_forest_model.pkl`
- `lof_model.pkl`
- `elliptic_envelope_model.pkl`
- `feature_scaler.pkl`
### 阶段 5.5 — SHAP 可解释性
**脚本:** `neo4j_phase55_shap.py`
**输出:** `data/phase55_shap_values.csv`、`data/phase55_shap_anomalies.csv`
使用 Isolation Forest 原生的 `shap.TreeExplainer`。每个用户将获得:
- 每个特征的 SHAP 值(对异常分数的贡献)
- `top_feature_1/2/3`:三个主要致因特征
- 每个特征的印尼语标签
结果也会作为属性(如 `shap_top_feature`、`shap_top_feature_label` 等)写回到 Neo4j 的 User 节点中。
### 阶段 6 — 报告生成
**脚本:** `neo4j_phase6_reporting.py`
**输出:**
| 文件 | 格式 | 内容 |
|------|--------|-----|
| `output/anomaly_detection_report.txt` | 文本 | 执行摘要、主要异常、建议 |
| `output/anomaly_detection_detailed.json` | JSON | 前 50 个异常 + 证据 + SHAP |
| `output/anomaly_statistics.json` | JSON | 严重程度分布、特征统计 |
| `output/AD_Anomaly_Detection_Report.docx` | Word | 准备打印的正式报告 |
## 文件夹结构
```
tdas_adauditv3/
├── pipeline_adaudit.ipynb # Notebook utama (jalankan ini)
│
├── neo4j_ingest_phase2.py # Phase 2: Neo4j ingestion
├── neo4j_phase3_rules.py # Phase 3: Rule engine
├── neo4j_phase4_features.py # Phase 4: Feature extraction
├── neo4j_phase5_anomaly.py # Phase 5: Anomaly detection
├── neo4j_phase55_shap.py # Phase 5.5: SHAP explainability
├── neo4j_phase6_reporting.py # Phase 6: Reporting
│
├── restructure_for_neo4j.py # Pra-proses: gabung CSV raw
├── generate_report_docx.py # Generate laporan Word
├── requirements.txt # Dependensi Python
├── setup.sh # Setup script (Linux/Mac)
│
├── data/
│ ├── raw_data/ # CSV mentah dari AD
│ ├── restructured_data/ # CSV gabungan (unified_logon_events.csv)
│ ├── phase4_graph_features.csv # Output Phase 4
│ ├── phase5_anomaly_results.csv # Output Phase 5
│ ├── phase55_shap_values.csv # Output Phase 5.5 (semua user)
│ └── phase55_shap_anomalies.csv # Output Phase 5.5 (anomali saja)
│
├── models/ # Model ML tersimpan (.pkl)
├── output/ # Laporan akhir
├── cypher/ # Query Cypher untuk Neo4j Browser
└── docs/ # Dokumentasi, referensi, presentasi
```
## 故障排除
### Neo4j 无法连接
```
ServiceUnavailable: Failed to obtain a connection from the pool
```
确保 Neo4j 正在运行,并检查配置中的凭据。通过打开 `http://localhost:7474` 进行验证。
### 阶段 3/4 出现 Cypher 语法错误
请确保使用的是 **Neo4j 5.x**。这些脚本使用了最新语法:
- `datetime(x).hour`(而不是 `hour(datetime(x))`)
- `COUNT { (pattern) }`(而不是 `size((pattern))`)
- `NOT x IN list`(而不是 `x NOT IN list`)
### SHAP 错误:找不到模型
请确保首先运行了阶段 5,以便存在 `models/isolation_forest_model.pkl` 文件。
### Windows 上的编码错误
如果在 Windows 终端中出现 `UnicodeEncodeError`,请使用以下命令运行:
```
set PYTHONIOENCODING=utf-8
python neo4j_phase6_reporting.py
```
## 示例输出
```
ANOMALY DETECTION REPORT
========================
Total users analyzed : 2,729,818
Anomalies detected : 19
CRITICAL : 2
HIGH : 5
MEDIUM : 12
Top Anomalous Users:
mti.admin Score: 0.5514 Cause: Level privilege tinggi
svc.backup Score: 0.4821 Cause: Pelanggaran rule
...
```
## 许可证
本项目为内部安全审计目的而开发。
标签:Active Directory, AD审计, Elliptic Envelope, Isolation Forest, Local Outlier Factor, Neo4j, numpy, OpenCanary, pandas, Plaso, Python, scikit-learn, SHAP, TCP/UDP协议, UBA, 云计算, 代码示例, 内部威胁检测, 可解释性机器学习, 图特征提取, 孤立森林, 局部异常因子, 异常检测, 数据分析, 数据科学, 无后门, 无监督学习, 用户行为分析, 网络安全, 自动化报告, 规则引擎, 资源验证, 身份安全, 逆向工具, 隐私保护, 集成机器学习