Alpha-Beta-810/MailGlass_v3.1

GitHub: Alpha-Beta-810/MailGlass-v3.1

MailGlass 是一个混合式网络钓鱼邮件检测平台,结合黑名单查询、威胁情报、域名分析与机器学习分类器,提供可解释的风险评分及持久化扫描历史。

Stars: 0 | Forks: 0

# 🔍MailGlass_v3.1:混合式网络钓鱼邮件检测系统 MailGlass 是一个混合式网络钓鱼邮件检测器,它结合了**基于黑名单的检查** (白名单、PhishTank、VirusTotal) 与一个 **ML 回退分类器**, 加上支持性的域名情报(WHOIS 域名年龄、IDN/同形异义字以及 域名抢注/仿冒检测)以及一个加权的、可解释的风险评分。可通过 命令行或 Flask Web 仪表板使用。 ## 🚀 版本 3.1 的新特性 版本 **3.1** 在现有的混合式钓鱼检测平台基础上,引入了使用 SQLite 的**持久化扫描历史**。扫描结果现在可以在应用程序重启后保留,允许用户回顾之前的分析、导出历史报告,并直接从 Web 界面管理扫描历史。 | 功能 | 版本 3.0 | 版本 3.1 | |:--------|:-----------:|:-----------:| | Flask 仪表板 | ✅ | ✅ | | 机器学习检测 | ✅ | ✅ | | Typosquatting 检测 | ✅ | ✅ | | 邮件头分析 | ✅ | ✅ | | WHOIS / 域名情报 | ✅ | ✅ | | 可解释风险引擎 | ✅ | ✅ | | CSV 导出 | ✅ | ✅ | | JSON 导出 | ✅ | ✅ | | **持久化 SQLite 扫描历史** | ❌ | ✅ | | **历史记录仪表板** | ❌ | ✅ | | **服务器重启后的仪表板重建** | ❌ | ✅ | | **导出以前的扫描结果** | ❌ | ✅ | | **清除扫描历史** | ❌ | ✅ | ### ✨ v3.1 的新功能 - 🗄️ **持久化 SQLite 历史记录** - 每次扫描都会自动存储在本地 SQLite 数据库(`scan_history.db`)中。 - 即使在关闭或重启应用程序后,扫描结果依然可用。 - 📜 **历史记录仪表板** - 查看所有以前扫描过的邮件。 - 过滤并重新查看历史扫描结果。 - 🔄 **仪表板重建** - 应用程序重启后,可以直接从数据库重建以前生成的仪表板。 - 📥 **历史报告导出** - 无需重新扫描邮件,即可将任何以前的扫描导出为 **CSV** 或 **JSON**。 - 🧹 **清除历史记录** - 只需单击一下,即可从应用程序中删除所有已存储的扫描历史。 ## 架构 ``` Read .eml | Parse HTML + Text | Extract href URLs + Plain URLs | Validate URLs | Whitelist | PhishTank | VirusTotal | Machine Learning (only if blacklist stage was inconclusive) | Risk Score | Final Verdict: SAFE / SUSPICIOUS / MALICIOUS ``` ## 项目布局 | 文件 | 用途 | |---|---| | `phishing_detector.py` | **主入口。** CLI、编排、单封邮件报告。 | | `config.py` | 分层设置:默认值 -> `config.json` -> 环境变量 -> CLI 标志。 | | `email_utils.py` | `.eml` 解析:主题、发件人、正文、附件。 | | `url_utils.py` | URL 提取(基于 href,而非锚文本)、验证、重定向解析。 | | `whitelist_utils.py` | 域名标准化 + 基于根域名的白名单匹配。 | | `threat_intel.py` | PhishTank + VirusTotal API 调用,带有单次运行缓存。 | | `domain_intel.py` | WHOIS 域名年龄查询 + IDN/punycode 同形异义字检测。 | | `typosquat_detection.py` | 仿冒品牌域名检测(字符替换、 combosquatting 、后缀交换)。 | | `risk_engine.py` | 加权风险评分和 SAFE/SUSPICIOUS/MALICIOUS 分类。 | | `ml_analysis.py` | ML 回退模型 + 对其推理过程的人类可读解释。 | | `results_export.py` | 导出单封邮件结果的 CSV/JSON。 | | `history_store.py` | 持久化 SQLite 扫描历史(在重启后保留),支持 Web 仪表板的历史记录页面。 | | `app.py` | Flask Web 仪表板:上传 `.eml` 文件,在浏览器中浏览结果。 | | `templates/`, `static/` | Web 仪表板的 HTML/CSS。 | | `model_classes.py` | 训练好的 pipeline 使用的自定义 sklearn transformer。 | | `ml_integration_fixed.py` | 从 `CEAS_08.csv` 训练 `phishing_email_model_fixed.pkl`。 | | `model_evaluation.py` | 针对训练好模型的交叉验证、ROC 曲线、混淆矩阵。 | | `whitelist.json` | 受信任的域名/URL 配置。 | | `tests/` | 涵盖 URL/白名单/风险/域名情报逻辑的 Pytest 测试套件。 | 有关修复/添加的内容及其原因的详细历史记录,请参见 `CHANGES.md`。 ## 设置 ``` pip install -r requirements.txt # runtime # 或者,同时运行 test suite: pip install -r requirements-dev.txt ``` 如果在加载内置模型时遇到 scikit-learn 版本不匹配的问题(请参阅 下方的**已知注意事项**),请锁定 `scikit-learn==1.6.1`,或者在您当前的 scikit-learn 版本下重新训练模型(请参阅**训练**)。 ## Web 仪表板 ``` python app.py ``` 然后打开 `http://127.0.0.1:5000`。上传一个或多个 `.eml` 文件( `emails/` 中的两个文件可用作演示),可选择勾选“解析跟踪链接 重定向” / “检查域名年龄”,您将获得: - 一个仪表板,显示总扫描数 + SAFE/SUSPICIOUS/MALICIOUS 计数 + 平均 ML 置信度 - 一份单封邮件报告:风险评分仪表、可解释的逐个因素 分解、每个提取的 URL 旁边附有其*可见的锚文本*(以便您 能看到 href 与锚文本修复的实际效果)、附件扫描结果、 ML 回退的推理过程,以及任何 typosquat/同形异义字/域名年龄 发现 - 导出当前扫描的 CSV/JSON 每次单独的扫描也会写入一个小型 SQLite 数据库 (`scan_history.db`,自动在 `app.py` 旁边创建)。顶部导航栏中的 **历史记录** 链接列出了曾经扫描过的每一封邮件——跨越不同的 扫描批次,甚至在重启服务器后也是如此——并带有各自的 CSV/JSON 导出和“清除历史记录”操作。这就是使 `/dashboard/` 和 `/email//` 链接在重启后依然能继续工作 的原因:如果内存中的副本丢失,它们会回退到数据库。详情请参见 `history_store.py`。 这是一个本地单进程工具(无用户账户,无身份验证)——适合 于演示和评分,不适合作为共享的面向互联网的服务进行部署。 ## 运行检测 (CLI) ``` mkdir -p emails # drop your .eml files here python phishing_detector.py ``` `emails/` 中提供了两个示例 `.eml` 文件,演示了最初的 href 与锚文本 bug 修复以及 `mckinsey-login.com` 仿冒域名。 ### CLI 标志 ``` python phishing_detector.py --help ``` | 标志 | 效果 | |---|---| | `--emails-dir DIR` | `.eml` 文件的目录(默认:`emails`) | | `--whitelist-file PATH` | 白名单 JSON 的路径(默认:`whitelist.json`) | | `--model-path PATH` | 训练好的 `.pkl` 模型的路径 | | `--resolve-redirects` | 在检查信誉之前,跟随跟踪链接重定向到达其最终目的地 | | `--check-domain-age` | WHOIS 查询链接/发件人域名,并标记注册时间在 30 天内的域名(速度较慢,需要网络 + `python-whois`) | | `--output-csv PATH` | 将结果摘要写入 CSV | | `--output-json PATH` | 将结果摘要写入 JSON | | `--config PATH` | JSON 配置文件的路径(默认:`config.json`) | | `--log-level LEVEL` | `DEBUG` / `INFO` / `WARNING` / `ERROR` | ### 配置优先级 `config.py` 按以下顺序解析设置(后者优先): **内置默认值 → `config.json`(如果存在)→ 环境变量 → CLI 标志。** 复制 `config.example.json` 到 `config.json` 以进行自定义, 无需改动环境变量或标志: ``` cp config.example.json config.json ``` 相关的环境变量:`PHISHTANK_API_KEY`, `VIRUSTOTAL_API_KEY`, `EMAILS_DIR`, `WHITELIST_FILE`, `MODEL_PATH`, `RESOLVE_REDIRECTS`, `CHECK_DOMAIN_AGE`, `OUTPUT_CSV`, `OUTPUT_JSON`, `LOG_LEVEL`。 ### 示例:包含导出和域名年龄检查的完整运行 ``` export VIRUSTOTAL_API_KEY=your_key_here python phishing_detector.py --check-domain-age --resolve-redirects \ --output-csv results.csv --output-json results.json ``` ## 运行测试 ``` pip install -r requirements-dev.txt pytest tests/ -v ``` 该套件涵盖:href 与锚文本提取的修复、URL 验证 边缘情况、根域名白名单匹配(包括 `mckinsey-login.com` 仿冒案例)、跨所有 信号的加权风险评分、IDN/punycode 同形异义字检测,以及 typosquat/combosquat/ 后缀交换品牌冒充检测。 ## 训练 ML 模型 训练器需要在项目根目录下存在 `CEAS_08.csv`(此处未包含 - 大小约 65MB;请从您原始的数据集导出中获取)。 ``` python ml_integration_fixed.py ``` 这将训练一个 Random Forest pipeline(发件人模式特征 + 针对主题/正文的 TF-IDF + URL 计数),并写入 `phishing_email_model_fixed.pkl`。 请在与您运行 `phishing_detector.py` 相同的 scikit-learn 版本下进行训练,以避免下面提到的 pickle 兼容性问题。 要评估训练好的模型(混淆矩阵、ROC 曲线、交叉验证): ``` python model_evaluation.py ``` ## 已知注意事项:scikit-learn 版本不匹配 内置的 `.pkl` 是使用 scikit-learn 1.6.1 训练的。在明显 更新的 scikit-learn 上,某些内部类(例如 `_RemainderColsList`)可能 无法被 unpickle。这是一个环境/版本问题,而不是检测 逻辑中的 bug - 系统已经实现了优雅降级,回退到 轻量级的发件人/主题启发式方法,而不是崩溃或静默地 报告 SAFE(请参阅 `risk_engine.py` 的 `ml_unavailable_heuristics` 路径)。 通过锁定 `scikit-learn==1.6.1` 或按上述方法重新训练来解决。 ## 扩展 - **受信任的域名**:将根域名添加到 `whitelist.json` 中的 `domainsInSubdomains` 中。 - **Typosquat 品牌列表**:精选的候选列表位于 `typosquat_detection.CURATED_BRANDS` 中;通过 `whitelist.json` 中的 `"typosquatBrands"` 数组添加要监视的特定项目品牌,而不是直接修改代码。 - **风险权重**:所有分值都是位于 `risk_engine.py` 顶部的命名常量。 - **新信号**:向 `results_export.EmailResult` 添加一个字段,在 `phishing_detector.analyze_email()` 中计算它,并将其传递给 `risk_engine.score_email()`。
标签:Apex, SQLite, 威胁情报, 开发者工具, 机器学习, 逆向工具, 邮件安全, 钓鱼检测