IdreesYousofzai/phishing-email-detector

GitHub: IdreesYousofzai/phishing-email-detector

结合机器学习模型与多层规则检查的钓鱼邮件分类器,通过 Flask Web 应用提供实时检测与风险归因。

Stars: 2 | Forks: 0

# 钓鱼邮件检测器 一个钓鱼邮件分类器,结合了训练好的 ML 模型与基于规则的检查(紧急性用语、可疑 URL、发件人/域名不匹配),通过 Flask Web 应用提供服务。 粘贴一封邮件,即可获得判定结果、置信度百分比,以及被标记的具体原因。 image image ## 为什么这很重要 网络钓鱼是大多数数据泄露的入口。Verizon 的《数据泄露调查报告》反复发现,大多数已确认的违规事件都涉及某种形式的社会工程学或凭证盗窃,且均始于钓鱼邮件。一封具有迷惑性的邮件通常就是整个攻击:不需要漏洞利用,只需要有人点击链接并在错误的页面中输入密码。 ## 数据集 构建计划原本要求使用 Kaggle 的钓鱼数据集。由于当前环境无法直接访问 Kaggle,我改为从三个公开的、已标注的邮件语料库(Nazario 钓鱼语料库、SpamAssassin 和 Enron)中提取数据。它们涵盖了相同的范围:真实的钓鱼邮件和真实的合法商业邮件。 - 合并后:经过去重和清洗,共 37,003 封邮件 - 降采样至 8,000 封用于训练(3,200 封钓鱼邮件 / 4,800 封合法邮件),保留了真实的不平衡状态,而不是人为的 50/50 划分 - 使用的列:`subject`、`body`、`label`(1 = 钓鱼邮件,0 = 合法邮件) ## 预处理 每封邮件的主题和正文会被合并(主题被计算两次,因为它虽然短,但包含大量紧急性信号),然后进行清洗: 1. 全部转为小写 2. 去除 HTML 标签 3. 去除原始 URL(由基于规则的 URL 检查器单独处理) 4. 去除标点符号和数字 5. 按空格进行分词 (Tokenise) 6. 去除停用词和单字符 token ## 特征提取 使用 TF-IDF 向量化,包含 unigram 和 bigram,上限为 8,000 个特征。设置 `sublinear_tf=True`,以防止词频掩盖词频稀有度。 在这里 bigram 非常重要:像“act now”和“verify account”这样的词组,作为短语比作为独立的单词能承载更多的信号。 ## 模型对比 使用相同的 TF-IDF 特征训练了三个模型,按标签进行分层抽样,采用 80/20 的训练/测试集划分: | 模型 | Accuracy | Precision | Recall | F1 | |---|---|---|---|---| | Naive Bayes | 0.965 | 0.955 | 0.958 | 0.956 | | Logistic Regression | **0.977** | **0.966** | **0.977** | **0.971** | | Random Forest | 0.966 | 0.952 | 0.963 | 0.957 | Logistic Regression 胜出,它是该应用加载的模型。 Naive Bayes 假设在给定类别的情况下,单词特征是相互独立的。对于相关词(如 `verify`、`account`、`suspended`)往往在同一封钓鱼邮件中同时出现的 TF-IDF 向量来说,这是一种较为粗略的近似。Logistic Regression 不需要这种假设;它直接学习 TF-IDF 特征的加权组合,这非常适合处理此类稀疏、高维的文本数据。Random Forest 在相同的特征上构建决策树,但在 8,000 列稀疏的 TF-IDF 数据中,单棵树的分裂效果不如线性模型的分离效果干净。因此,它的表现与 Naive Bayes 大致相当,而无法超越 Logistic Regression。 胜出模型的混淆矩阵(行 = 实际值,列 = 预测值,顺序为 [合法邮件, 钓鱼邮件]): ``` [[938 22] [ 15 625]] ``` 在 1,600 封预留的测试邮件中,有 22 封合法邮件被误判为钓鱼邮件,15 封钓鱼邮件被漏判。 ## 基于规则的特征 ML 模型主要读取文本模式。它不一定能捕获那种避开了常见钓鱼词汇、但仍然使用带有 IP 地址链接的虚假 PayPal 域名的钓鱼邮件。因此,除了模型之外,`src/features.py` 还会检查: - **紧急性用语** — 如 "verify your account"、"will be suspended"、"act now"、"within 24 hours" 等短语 - **通用问候语** — 使用 "Dear Customer" 而不是真实姓名 - **金钱/奖品诱饵** — 如 "you have won"、"claim your reward"、"tax refund" - **可疑 URL** — 使用原始 IP 地址而不是域名、异常深的子域链、高风险 TLD(`.ru`、`.tk`、`.xyz` 等)、`user@domain` 重定向欺骗 - **相似域名** — 显示名称写着 "PayPal",但域名与 PayPal 的真实域名不匹配(例如 `paypa1-secure.net`) - **发件人/显示名称不匹配** — 同样的逻辑,不过是通过检查实际发送地址而不是链接来实现 每次检查都会返回一个通俗易懂的原因字符串,这些字符串会显示在结果界面的“是什么触发了此分类”部分中。 最终判定结果将 ML 概率与规则得分相结合:如果触发了三项或更多基于规则的检查,钓鱼邮件的概率会被略微提升几个百分点(上限为 18%)。理由是,如果一封邮件同时触发了多个危险信号,即使其措辞看起来相当普通,也理应获得一个适当的额外加权。 ## 针对真实未见样本的测试 计划原本要求针对 PhishTank 的实时存档进行测试,但这需要当前环境所不具备的 API 访问权限。因此,我特意预留了 150 封真实的钓鱼邮件和 150 封真实的合法邮件,这些邮件在训练或最初的训练/测试集划分期间从未被使用过,并针对它们进行了同样的假阳性/假阴性测量: - 假阴性率(漏判的钓鱼邮件):2/150 = **1.3%** - 假阳性率(被误报为钓鱼邮件的合法邮件):6/150 = **4.0%** 假阳性只会让人在复查一封其实没问题的邮件时感到片刻困惑。而假阴性则可能导致凭证或金钱损失。模型倾向于捕获更多的钓鱼邮件,代价是产生一些额外的误报,这对于当前使用场景来说是正确的权衡。 如果您确实拥有 PhishTank API 访问权限,`tests/evaluate_real_samples.py` 中有一条注释说明了如何将其指向 `verified_online.csv`。 ## 运行项目 ``` pip install -r requirements.txt cd src && python3 train.py # trains all three models, saves the best one cd .. && python3 app.py # starts the Flask app on localhost:5000 ``` 打开 `http://localhost:5000`,粘贴一封邮件,点击“分析”。 此外还有一个 JSON endpoint:`POST /api/analyse`: ``` curl -X POST http://localhost:5000/api/analyse \ -H "Content-Type: application/json" \ -d '{"subject": "Verify your account", "body": "...", "display_name": "PayPal", "sender_email": "support@paypa1-secure.net"}' ``` ## 项目结构 ``` phishing-detector/ ├── app.py Flask web app ├── requirements.txt ├── data/ │ └── phishing_email_dataset.csv ├── src/ │ ├── preprocess.py text cleaning │ ├── features.py rule-based checks │ ├── train.py trains and compares the three models │ └── predict.py combined ML + rule verdict used by the app ├── models/ saved model, vectoriser, metrics (after training) ├── templates/index.html ├── static/style.css └── tests/ └── evaluate_real_samples.py false positive/negative check on held-out real emails ``` ## 局限性 数据集偏向于较旧的、已有充分记录的钓鱼活动(Nazario 的语料库始于 2000 年代中期)。较新的钓鱼手法,尤其是那些利用 AI 辅助编写、刻意避开经典紧急性措辞的邮件,将更多地依赖于基于规则的 URL 和域名检查,而不是 TF-IDF 模型,因为这些活动所使用的文本模式未必已经出现在此训练数据中。
标签:Apex, Flask, 多模态安全, 安全防护, 机器学习, 逆向工具, 钓鱼检测