trac3r00/phish-triage
GitHub: trac3r00/phish-triage
一个开箱即用的钓鱼邮件分诊工具包,能自动解析 .eml 文件、富化威胁情报并输出加权判定和可投入生产的 SIEM 检测规则。
Stars: 0 | Forks: 0
# phish-triage
一个开箱即用的小型**钓鱼邮件分诊工具包**,专为 SOC 分析师和检测工程师设计。
输入一个 `.eml` 文件;即可获得:
1. 对所有关键信号的**确定性解析** —— SPF/DKIM/DMARC,From 与 Reply-To 及显示名欺骗,Received 链异常,URL(已解除危险),以及带有加密哈希的附件。
2. **外部情报富化**(VirusTotal v3 + AbuseIPDB 免费层),受内置速率限制器和磁盘缓存控制。
3. **0-100 的加权判定**(`benign` / `suspicious` / `malicious`)以及通俗易懂的评估理由。
4. **八个生产级检测规则** —— Splunk SPL + Sigma —— 映射到 MITRE ATT&CK,基于与工具呈现的相同信号触发。
📖 **详细背景:** [我为何构建此工具](docs/why.md) · [回顾总结](docs/retrospective.md)
## 截图
内置的 Web UI(`python -m phish_triage.web`,参见下方的
[示例测试器](#sample-tester-web-ui))允许您投入任何 `.eml`
文件,并并排查看判定结果、信号、IOC 和推理过程。
| | |
|---|---|
| **主页 —— 上传或选择示例**
 | **钓鱼示例 → MALICIOUS 100/100**
 | | **良性示例 → BENIGN 0/100(无误报)**
 | **CLI 会话 —— 相同工具包,终端优先**
 | ## 架构 ``` ┌─────────────────────────────┐ .eml ───► │ Stage 1: parser.py (stdlib) │ ──► JSON / markdown summary └────────────┬────────────────┘ │ ParsedEmail ▼ ┌─────────────────────────────┐ │ Stage 2: enrich.py │ │ • VirusTotal v3 (URLs, │ ──► markdown triage report │ file hashes) │ (summary + IOC table + │ • AbuseIPDB (Rx-chain IPs) │ enrichment + verdict) │ • rate limit + cache │ │ • weighted scorer │ └────────────┬────────────────┘ │ EnrichmentResult ▼ ┌─────────────────────────────┐ │ Stage 3: detections/ │ │ • 8 SPL queries │ ──► drop into Splunk / SIEM │ • 8 Sigma rules │ │ • MITRE ATT&CK mapping │ └─────────────────────────────┘ ``` ## 快速开始 ``` git clone https://github.com/trac3r00/phish-triage.git cd phish-triage python3.11 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" # 重新生成示例 fixtures(安全:无真实恶意软件) python -m tests.make_fixtures # Stage 1 — 解析 .eml,输出 JSON phish-triage parse tests/fixtures/phish_sample.eml --json # Stage 1 — 相同邮件,markdown 摘要 phish-triage parse tests/fixtures/phish_sample.eml --markdown # Stage 2 — 解析 + 富化(使用 env vars;缺失密钥时优雅降级) export VT_API_KEY= # https://www.virustotal.com/gui/my-apikey
export ABUSEIPDB_API_KEY= # https://www.abuseipdb.com/account/api
phish-triage enrich tests/fixtures/phish_sample.eml --output report.md
# 运行测试套件
pytest -q
```
## 示例测试器 (Web UI)
```
pip install -e ".[web]"
python -m phish_triage.web
# 打开 http://127.0.0.1:5050
```
位于 `src/phish_triage/web/` 下的单文件 Flask 应用,允许您上传
任何 `.eml` 或点击一个内置示例,并以卡片形式查看解析的信号、
IOC、判定结果和理由。
## 示例输出
```
$ phish-triage enrich tests/fixtures/phish_sample.eml | head -25
# 钓鱼初步分类报告 — 紧急:PayPal 账户已暂停
**Source:** `tests/fixtures/phish_sample.eml`
## 摘要
- **Verdict:** `MALICIOUS`
- **Score:** 100 / 100
- **From:** PayPal Security
- **Reply-To:** verify@evil-collector.country
- **Subject:** Urgent: PayPal account suspended
## IOC 表格
| Type | Value | Notes |
|------|--------------------------------------------------|----------------------|
| url | `hxxp://bit[.]ly/paypal-verify-now` | host `bit.ly` |
| url | `hxxps://paypa1-secure-login[.]zip/account` | host `paypa1...zip` |
| file | `invoice.html` | sha256 `1fec...f873` |
| ip | `198.51.100.42` | from Received chain |
```
## 阶段分解
### Stage 1 — 解析器(纯标准库)
* 使用 `email.policy.default` 进行 RFC 5322 解析 —— 处理 MIME、RFC 2047
标头编码、quoted-printable / base64 传输编码。
* 逐个机制解析 `Authentication-Results`;最强
信号优先(后续的 `none` 不会覆盖先前的 `fail`)。
* `From` 与 `Reply-To` 不匹配以及显示名品牌欺骗检测。
* `Received` 链按发起方 → 接收方排序,并带有 **仅 RFC 1918** 私有
检测(测试夹具用作替代公共 IP 的 RFC 5737 文档范围地址将被
视为公共地址 —— 参见
`_is_private` 中的注释)。
* 提取所有 `text/*` body 部分中的 URL,去重并解除危险
(`hxxp://`, `[.]`)。
* 附件提供文件名、content-type、大小以及 MD5/SHA1/SHA256。
* 输出:JSON 或 Markdown 分析师摘要。
[阅读 Stage 1 详细指南 →](docs/stage1-parsing-walkthrough.md)
### Stage 2 — 情报富化(仅使用 `requests`)
* VirusTotal v3 GET endpoints 用于 URL (`/urls/{base64id}`) 和文件
(`/files/{sha256}`),受与免费层配额匹配的 4 req/min RateLimiter 限制。
* AbuseIPDB `/check` 用于每一个 **公共** Received 链跳。
* 缺少 API key?将跳过该源,并在报告的
`Notes` 部分添加一行说明,评分基于剩余内容继续进行。
* 响应缓存在 `.cache/` 下,以 `(source, IOC)` 为键,因此重新运行不会
消耗配额。
* 判定评分:信号权重 + VT 检出 + AbuseIPDB 置信度
限制在 0-100 之间,在 40 / 70 处映射为 benign / suspicious / malicious。
[阅读 Stage 2 详细指南 →](docs/stage2-enrichment-walkthrough.md)
### Stage 3 — 检测规则(Splunk SPL + Sigma)
* 包含 SPL 和 Sigma 格式的八个规则,涵盖解析器呈现的
每一类信号。
* `detections/README.md` 包含规则 ↔ 解析器信号 ↔ MITRE ATT&CK
对照表。
[阅读检测工程说明 →](docs/stage3-detection-engineering.md)
## MITRE ATT&CK 映射
| 规则 | 技术 |
|------|--------------|
| R01 SPF 失败 + From/Reply-To 不匹配 | [T1566.001](https://attack.mitre.org/techniques/T1566/001/), [T1566.002](https://attack.mitre.org/techniques/T1566/002/) |
| R02 新发件域 + 认证失败 | [T1566](https://attack.mitre.org/techniques/T1566/) |
| R03 品牌 / 高管显示名欺骗 | [T1656](https://attack.mitre.org/techniques/T1656/), [T1566.001/002](https://attack.mitre.org/techniques/T1566/) |
| R04 邮件中的短链接 | [T1566.002](https://attack.mitre.org/techniques/T1566/002/), [T1204.001](https://attack.mitre.org/techniques/T1204/001/) |
| R05 附件哈希 → VirusTotal | [T1566.001](https://attack.mitre.org/techniques/T1566/001/) |
| R06 可疑 TLD 链接 | [T1566.002](https://attack.mitre.org/techniques/T1566/002/), [T1583.001](https://attack.mitre.org/techniques/T1583/001/) |
| R07 包含表单的 Base64 HTML body | [T1027](https://attack.mitre.org/techniques/T1027/), [T1566.001](https://attack.mitre.org/techniques/T1566/001/) |
| R08 DMARC 拒绝绕过 | [T1566](https://attack.mitre.org/techniques/T1566/), defense_evasion |
## 项目结构
```
phish-triage/
├── src/phish_triage/
│ ├── __init__.py
│ ├── parser.py Stage 1 — stdlib-only parser
│ ├── enrich.py Stage 2 — VT + AbuseIPDB + scoring
│ ├── cli.py argparse front-end (phish-triage parse|enrich)
│ └── web/ Stage 4 — single-file Flask sample tester
│ ├── __init__.py
│ ├── __main__.py
│ ├── templates/{index,report}.html
│ └── static/style.css
├── tests/
│ ├── fixtures/
│ │ ├── benign.eml regenerated from make_fixtures.py
│ │ └── phish_sample.eml
│ ├── make_fixtures.py no real malware — only signal patterns
│ ├── test_parser.py 9 cases
│ ├── test_enrich.py 11 cases, HTTP fully mocked
│ └── test_web.py 4 cases — Flask test client
├── detections/
│ ├── spl/ R01-R08 (.spl)
│ ├── sigma/ R01-R08 (.yml, uuid4 ids, MITRE tags)
│ └── README.md signal → rule → ATT&CK mapping
├── docs/
│ ├── why.md why I built this
│ ├── retrospective.md what worked, what bit me
│ ├── stage1-parsing-walkthrough.md
│ ├── stage2-enrichment-walkthrough.md
│ ├── stage3-detection-engineering.md
│ └── screenshots/ README image assets
└── pyproject.toml
```
## 测试
```
pytest -q # 28 tests, all green, no live API calls
```
情报富化测试使用 `unittest.mock.patch` 针对
`phish_triage.enrich.requests.Session.get`,因此该测试套件**无需 API key 即可安全运行**
并且**绝不**消耗配额。
## 安全性 / 范围
* `tests/make_fixtures.py` 特意使用无害文本构建钓鱼夹具 —— 此仓库中
**没有真实恶意软件**。
* 该工具包仅对公共 API 执行**只读**查询。
* 任何地方都没有 `eval` / `exec` / `shell=True`;没有硬编码凭证。
## 许可证
MIT —— 参见 [LICENSE](LICENSE)。
 | **钓鱼示例 → MALICIOUS 100/100**
 | | **良性示例 → BENIGN 0/100(无误报)**
 | **CLI 会话 —— 相同工具包,终端优先**
 | ## 架构 ``` ┌─────────────────────────────┐ .eml ───► │ Stage 1: parser.py (stdlib) │ ──► JSON / markdown summary └────────────┬────────────────┘ │ ParsedEmail ▼ ┌─────────────────────────────┐ │ Stage 2: enrich.py │ │ • VirusTotal v3 (URLs, │ ──► markdown triage report │ file hashes) │ (summary + IOC table + │ • AbuseIPDB (Rx-chain IPs) │ enrichment + verdict) │ • rate limit + cache │ │ • weighted scorer │ └────────────┬────────────────┘ │ EnrichmentResult ▼ ┌─────────────────────────────┐ │ Stage 3: detections/ │ │ • 8 SPL queries │ ──► drop into Splunk / SIEM │ • 8 Sigma rules │ │ • MITRE ATT&CK mapping │ └─────────────────────────────┘ ``` ## 快速开始 ``` git clone https://github.com/trac3r00/phish-triage.git cd phish-triage python3.11 -m venv .venv && source .venv/bin/activate pip install -e ".[dev]" # 重新生成示例 fixtures(安全:无真实恶意软件) python -m tests.make_fixtures # Stage 1 — 解析 .eml,输出 JSON phish-triage parse tests/fixtures/phish_sample.eml --json # Stage 1 — 相同邮件,markdown 摘要 phish-triage parse tests/fixtures/phish_sample.eml --markdown # Stage 2 — 解析 + 富化(使用 env vars;缺失密钥时优雅降级) export VT_API_KEY=
标签:Python, TCP SYN 扫描, Web UI, 威胁情报, 安全规则引擎, 安全运营, 开发者工具, 扫描框架, 无后门, 检测规则, 网络资产发现, 逆向工具, 钓鱼邮件分析