MetaMaaz/phishing-email-analyzer
GitHub: MetaMaaz/phishing-email-analyzer
一款命令行钓鱼邮件分类工具,像 SOC 分析师一样对可疑邮件做静态分析、风险评分并生成可追溯的调查报告。
Stars: 0 | Forks: 0
# 钓鱼邮件分析器




## 在线演示
托管的 Web 版本允许任何人粘贴或上传可疑邮件,并在浏览器中获取
相同的分类报告 —— **仅限静态分析,绝不获取链接,
也绝不执行附件**。
🔗 **在线体验:** **[metamaaz-phishing-analyzer.streamlit.app](https://metamaaz-phishing-analyzer.streamlit.app)** —— 粘贴邮件或运行内置示例。(部署说明:[DEPLOY.md](DEPLOY.md)。)

一款命令行工具,它可以提取可疑邮件,像 SOC 分析师那样对其进行拆解,
并得出结论。它会检查身份验证头,追踪邮件的真实来源,提取并消除
入侵指标 (IOC) 的威胁,静态检查任何附件,对风险进行评分,并保存
Markdown 报告以及可输入到其他工具的 JSON 文件。
一切都是**静态的** —— 没有任何附件会被打开、执行或
引爆。它在 macOS(或任何装有 Python 3.10+ 的机器)上原生运行,且
不需要虚拟机 (VM)。
## 快速开始
```
git clone && cd phishing-email-analyzer
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
# 分析捆绑的 synthetic samples(完全离线)
python -m src.cli batch samples --no-enrich
```
```
[Malicious] score=85/100 01_fake_invoice.eml
[Suspicious] score=55/100 02_credential_harvest.eml
[Malicious] score=100/100 03_macro_attachment.eml
[Suspicious] score=35/100 04_bec_ceo_fraud.eml
[Suspicious] score=30/100 05_ai_generated_phish.eml
```
## 开发动机
钓鱼分类是 Tier-1 SOC 分析师全天最常见的工作之一:
一封邮件落入滥用邮箱,必须有人迅速决定它是垃圾邮件、
窃取凭据的页面,还是带有活动 payload 的东西。
我想要一款能像我一贯手动操作那样进行决策的工具,
并且能解释*为什么*得出该结论,而不是仅仅打印出一个数字。
可解释性是关键。风险评分中的每一分都可以追溯到
具有人类可读原因的指定发现,因此报告读起来就像
分析师的笔记,而不是黑盒。
## 功能说明
- 将 `.eml` 和 `.msg` 解析为一个结构化对象,并且在遇到格式错误或
缺失的头信息时不会崩溃 —— 而是会记录缺失的内容。
- 从 `Authentication-Results` 中读取 SPF / DKIM / DMARC 结果。
- 追踪 `Received:` 链回到最早的源 IP。
- 标记欺骗行为:`From` 与 `Return-Path` 与 `Reply-To` 不匹配,发送域中
隐藏的品名,来自免费 Web 邮件的高管冒充(典型的 BEC 特征),
以及显示名品牌冒充。
- 提取 URL、域、IP、发件人地址和哈希值,对其进行去重,
将发件人基础设施与正文/链接指标区分开来,并消除
所有威胁(`hxxp`、`[.]`),以便安全地四处粘贴报告。
- 针对常被滥用的品牌列表检测相似/错别字域名。
- 静态检查附件:对所有内容进行哈希处理,从 Office
文档中提取宏并标记自动执行触发器和可疑调用,并标记
携带 JavaScript、OpenAction、Launch 动作或嵌入文件的 PDF。
- 使用可调节的、基于规则的权重对邮件进行评分,并将其映射到一个
区间(低 / 可疑 / 恶意)。
- 可选择针对 VirusTotal、AbuseIPDB 和 URLhaus 丰富指标,并且
可以将整个 IOC 集合交给我的 ThreatLens 平台(参见
[ThreatLens 集成](#threatlens-integration))。在未配置 API 密钥的情况下,
它将跳过富化,但仍会生成一份完整的报告。
- 将发现结果映射到 MITRE ATT&CK 并编写 Markdown + JSON,
可处理单封邮件或一次处理整个文件夹。
## 架构
```
┌──────────┐
.eml / .msg → │ parser │ → EmailObject
└──────────┘
│
┌─────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌─────────────┐
│ headers │ │ iocs │ │ attachments │ (all static)
└──────────┘ └──────────┘ └─────────────┘
│ │ │
└─────────────┼──────────────┘
▼
┌──────────┐ (VirusTotal / AbuseIPDB /
│ enrich │ URLhaus / ThreatLens — optional)
└──────────┘
▼
┌──────────┐
│ score │ → weighted, reason-tagged findings
└──────────┘
▼
┌──────────┐
│ report │ → Markdown + JSON
└──────────┘
```
数据流:`parse → (headers + iocs + attachments) → enrich → score → report`。
每个阶段都是 `src/` 下的一个小模块,尽可能使用纯函数,
这使得它具有可测试性。
## 安装
```
python3 -m venv venv && source venv/bin/activate
pip install -r requirements.txt
```
如果跳过可选依赖项,该工具仅使用标准库即可运行,
但 `oletools`、`tldextract` 和 `iocextract` 会使宏、
域名和 IOC 分析更加敏锐。
## 用法
分析单封邮件:
```
python -m src.cli analyze samples/01_fake_invoice.eml
```
分析整个文件夹并获取摘要索引:
```
python -m src.cli batch samples/ --out reports
```
强制完全离线运行(完全无网络调用):
```
python -m src.cli analyze suspicious.eml --no-enrich
```
报告将生成在 `reports/` 目录下,格式为 `.md` 和 `.json`,
批处理模式下还会生成按最差优先排名的 `index.md`。
## 报告示例
```
# Phishing Triage Report — 🔴 Malicious
**Risk score:** 85/100 · **Verdict:** Malicious
| Field | Value |
|--------------|----------------------------------------------------|
| From | Accounts Payable |
| Return-Path | bounce@mailer-xyz.ru |
| Originating IP | 203.0.113.66 |
## Authentication
| Mechanism | Result |
| SPF | ❌ fail |
| DKIM | ➖ none |
| DMARC| ❌ fail |
## Score breakdown
| Signal | Points | Reason |
| PDF_ACTIVE_CONTENT | +30 | PDF contains JavaScript, OpenAction (runs on open)|
| SPF_FAIL | +20 | SPF authentication fail |
| DMARC_FAIL | +20 | DMARC policy failed |
| ENVELOPE_MISMATCH | +15 | Envelope sender domain differs from From |
| Total | 85 | Malicious |
```
## 风险评分
分数仅仅是触发的发现权重之和,上限为
100,然后映射到一个区间。没有任何隐藏内容,每一分都有迹可循。
| 信号 | 权重 |
|--------|-------:|
| SPF 失败 | +20 |
| DKIM 失败 | +15 |
| DMARC 失败 | +20 |
| From / Return-Path 不匹配 | +15 |
| Reply-To 重定向(不同邮箱) | +15 |
| 显示名品牌冒充 | +15 |
| 来自免费 Web 邮件的高管冒充 (BEC) | +20 |
| 发送域中嵌入品牌名称 | +15 |
| 相似/错别字域名 | +15 |
| 标记的 URL 或域名 (VirusTotal / URLhaus) | 每个 +25 |
| 已知恶意附件哈希 (VirusTotal) | +40 |
| 标记的源 IP (AbuseIPDB ≥ 50%) | +20 |
| 带有自动执行的 Office 宏 | +30 |
| 带有活动/嵌入内容的 PDF | +30 |
区间:`0–29 低 · 30–59 可疑 · 60+ 恶意`。
权重位于 `src/config.py` 中,可通过 `.env` 覆盖,因此你
可以根据自己的语料库对其进行调整。我根据下面的五个案例研究
样本调整了我的权重:我希望单一严重的身份验证失败加上一个支持信号
就能落入*可疑*,而活动 payload(宏/PDF)或一堆身份验证失败
则推入*恶意*。BEC 案例故意没有 payload 且通过了
身份验证 —— 它仅在行为信号(免费
Web 邮件 + 高管显示名 + 路由到其他地方的 Reply-To)下才跨入*可疑*,这
正是为什么 BEC 难以捕获且值得基于行为而非
基础设施进行评分的原因。
## 案例研究
五个实际调查,包含我所看到的、我如何解读它、结论
以及 ATT&CK 映射。这些才是分析师判断的精髓所在。
1. [虚假发票 —— 附件诱饵](docs/case-studies/01-fake-invoice.md)
2. [凭据收集 —— 相似的登录链接](docs/case-studies/02-credential-harvesting.md)
3. [恶意软件附件 —— 启用宏的 Office 文档](docs/case-studies/03-macro-attachment.md)
4. [商业电子邮件妥协 (BEC) —— 显示名欺骗,无 payload](docs/case-studies/04-bec.md)
5. [AI 生成的钓鱼 —— 语法干净,通过身份验证](docs/case-studies/05-ai-generated-phishing.md)
## MITRE ATT&CK
| 技术 | ID |
|-----------|-----|
| Phishing | T1566 |
| Spearphishing Attachment | T1566.001 |
| Spearphishing Link | T1566.002 |
| User Execution: Malicious File | T1204.002 |
| User Execution: Malicious Link | T1204.001 |
## ThreatLens 集成
此分析器旨在为 ThreatLens 提供数据 —— 这是我独立的威胁情报
平台,用于收集、丰富、评分和关联 IOC。在 `.env` 中设置 `THREATLENS_BASE_URL`(以及可选的 `THREATLENS_API_KEY`)
每封被分析邮件提取的指标都会被 POST 到 ThreatLens,以便
与其余情报进行更深入的关联。该邮件工具回答“这
单封邮件是否恶意”的问题;ThreatLens 则回答“我们以前是否见过这
基础设施,以及在哪里”的问题。两个相互交流的工具比
两个不交流的工具能讲述更好的故事。
## 安全与处理
- 仅限静态分析。主机上不会打开或执行任何附件。
- `samples/` 中提交的 `.eml` 文件是**安全、完全合成的**测试
邮件,带有惰性 payload,由 `samples/make_samples.py` 构建,任何人都可以
立即重现这些案例研究。绝不提交真实的恶意样本 —— 保持
将它们压缩、密码保护并排除在 git 之外。
- API 密钥仅来自 `.env` —— `.env.example` 是模板,而 `.env` 被
gitignored。代码中没有任何机密。
- 如果你需要进行动态分析,请在隔离的 VM 中引爆。根据设计,这超出了
此工具的范围。
## 技术栈
Python 3.10+ · 内置 `email` / `hashlib` · `extract-msg` (.msg) ·
`oletools` (宏) · `iocextract` + `tldextract` (IOC) · `httpx` (富化)
· 标准库 `argparse` (CLI) · `pytest` (测试)。
## 测试
```
python -m pytest
```
单元测试涵盖了解析器(包括格式错误的输入)、头部/身份验证分析、
IOC 提取和消除威胁以及评分区间。CI 会在 Python 3.10–3.13 上运行测试套件以及针对所有五个样本的离线冒烟测试。
## 学到了什么
仔细阅读 `Received:` 链和 `Authentication-Results` 头 —— 并且
意识到仅从头信息中就能捕获多少欺骗行为,而无需触碰
沙盒。此外,BEC 与 payload 钓鱼是不同的问题:
它更安静,因为来自真实的(免费)
邮箱,所以能通过 SPF/DKIM/DMARC,并且你必须根据行为对其进行评分。构建将
输出交给 ThreatLens 的工具让我将指标视为一个 pipeline,而不是
一次性的查询。
## 许可证
MIT —— 见 [LICENSE](LICENSE)。
更多截图
 标签:Kubernetes, Python, SOC分析, 云安全监控, 威胁情报, 安全规则引擎, 开发者工具, 无后门, 网络调试, 自动化, 运行时操纵, 逆向工具, 邮件分析, 静态分析