Ralphare/phishing-email-analyzer

GitHub: Ralphare/phishing-email-analyzer

一款防御性钓鱼邮件分诊工具,通过解析 .eml 文件对邮件身份验证、URL、附件及社会工程学特征进行加权风险评分,帮助安全分析师快速判断邮件威胁等级。

Stars: 0 | Forks: 0

# Phishalyzer — 钓鱼邮件分析器 ![示例报告](https://static.pigsec.cn/wp-content/uploads/repos/cas/d0/d02ed506ede7b01bcfb7e2dbbfcd887ea49370a72c10188e04c9e0e968e940e3.png) 这是一款防御性分流工具,它接收原始的 `.eml` 文件,并生成一份清晰、带有详细解释的钓鱼风险报告,附带 0-100 的加权评分。专为 SOC 风格的工作流构建:它不仅会标记问题,还会像资深分析师指导新人排查可疑邮件那样,解释每一项发现*为何*重要。 100% 使用 Python 标准库。完全离线运行。对于格式错误的输入(如损坏的 MIME、伪造的字符集和缺失的标头),它们会被作为分析发现记录下来,而绝不会引发崩溃异常。 ## 检查内容 **1. 邮件身份验证 (SPF / DKIM / DMARC)** 解析接收邮件服务器写入的 `Authentication-Results` 标头并解读裁定结果,包括一些隐蔽的异常情况:DKIM 验证通过但与可见的 From: 域名*未对齐*,存在冲突的(可能是攻击者注入的)Authentication-Results 标头,以及 Reply-To / Return-Path 域名与 From: 域名不一致。 **2. URL** 从纯文本和 HTML 正文中提取所有链接(包括经过防御性处理的 `hxxp://` 表示法),然后标记: - 针对约 25 个常被冒充品牌的域名伪装/拼写错误检测(基于编辑距离:`paypa1-secure.com` 与 `paypal` 的编辑距离仅为 1) - 将受信任品牌名称硬塞到不相关域名的子域中(`paypal.com.account-verify.net`) - 原始 IP 链接、URL 缩短服务、`user@host` 混淆 - 可见文本显示为一个域名,而 href 实际指向另一个域名的 HTML 锚点 —— 这正是“点击前先悬停检查”所要防范的骗局 - 指向登录类页面的纯 HTTP 链接 **3. 附件** 枚举所有附件(包括为躲避简单扫描器而标记为 `inline` 的附件),并标记可直接执行的文件类型(`.exe`、`.scr`、`.js` 等)、双重扩展名(`invoice.pdf.exe`)、启用宏的 Office 格式(`.docm`、`.xlsm`)、旧版 Office 格式、归档/磁盘镜像容器、HTML 附件,以及后宏时代的诱导文件(`.one`、`.xll`、`.chm`)。 **4. 正文社会工程学 通过模式匹配识别钓鱼邮件实际使用的语言:紧急性与最后期限、账号停用威胁、直接索取凭证/付款请求、虚假发票、奖品诱饵、CEO 欺诈中的保密要求(“帮个小忙”、礼品卡)、通用问候语 —— 此外还包括发送域名并不具备该品牌所有权,却在显示名称中声称代表该品牌的情况。 **5. 加权评分** 各项发现带有严重程度(INFO=0 …… CRITICAL=40 分),且在每个类别内部收益递减,因此一次 DMARC 失败的权重会大于十次弱关键词命中;一封包含 30 个链接的垃圾邮件也不会因为错误的原因而拉满分值。裁定分级:0–19 可能为安全,20–44 低风险,45–69 可疑,70–100 极可能为钓鱼邮件。 ## 项目结构 ``` phishing-analyzer/ ├── analyze.py # CLI entry point ├── requirements.txt ├── README.md ├── phishalyzer/ │ ├── __init__.py │ ├── eml_parser.py # crash-proof .eml loading & decoding │ ├── findings.py # shared Finding dataclass │ ├── auth_checks.py # SPF / DKIM / DMARC interpretation │ ├── url_checks.py # link extraction & lookalike detection │ ├── attachment_checks.py # dangerous file-type flagging │ ├── body_checks.py # social-engineering language signals │ ├── scoring.py # weighted 0–100 score │ └── report.py # console + JSON report rendering └── samples/ ├── benign_newsletter.eml # scores 0 — LIKELY BENIGN ├── subtle_borderline.eml # scores 55 — SUSPICIOUS └── obvious_phishing.eml # scores 100 — HIGH RISK ``` ## 安装 要求 Python 3.10+。离线使用无任何依赖: ``` git clone && cd phishing-analyzer python3 analyze.py samples/obvious_phishing.eml # that's it ``` 可选 — 启用 `--online` DNS 查询(检查发件人域名是否甚至发布了 SPF/DMARC 记录): ``` pip install -r requirements.txt ``` ## 用法 ``` python3 analyze.py # human-readable report python3 analyze.py --json # machine-readable (SIEM/jq) python3 analyze.py --no-color # plain text (files, tickets) python3 analyze.py --online # + live DNS SPF/DMARC lookups ``` 退出代码:`0` 分析完成,`2` 文件无法读取。 ## 示例输出(节选自 obvious_phishing.eml) ``` ============================================================================== PHISHING EMAIL ANALYSIS REPORT ============================================================================== From: PayPal Security Team Subject: URGENT: Your account will be suspended within 24 hours Reply-To: recovery-desk@mail-blast-747.xyz URLs found: 4 Attachments: 1 (SecurityForm.pdf.exe) ============================================================================== RISK SCORE: 100/100 VERDICT: HIGH RISK — LIKELY PHISHING Strong, converging indicators of phishing. Quarantine, report to your security team, and hunt for other recipients of the same campaign. ============================================================================== [AUTHENTICATION] -------------------------------------------------------------------------- [CRITICAL] DMARC: fail The visible sender 'paypal.com' could NOT be verified. Why it matters: neither SPF nor DKIM passed in alignment with the visible From: domain — the classic signature of From:-header spoofing. [URLS] -------------------------------------------------------------------------- [CRITICAL] Likely typosquatted domain 'paypa1-secure-verification.com' looks like 'paypal.com' (token 'paypa1' is 1 edit(s) from 'paypal'). [CRITICAL] Link text doesn't match real destination Visible text shows 'paypal.com' but the link goes to 'paypa1-secure-verification.com'. ... ``` 运行所有三个示例以查看完整的分数范围: ``` for f in samples/*.eml; do python3 analyze.py "$f"; done ``` ## 各项检查如何映射到真实的钓鱼策略 | 检查项 | 拦截的真实场景策略 | |---|---| | DMARC 失败 | From: 标头欺骗 —— 在发送自攻击者基础设施的同时,显示为 `service@paypal.com`。DMARC 是唯一能够验证*用户实际看到*的地址的协议。 | | SPF 失败 / 软失败 | 来自未经授权服务器的直接欺骗;从未关心过信封域策略的简陋攻击者基础设施。 | | 未对齐的 DKIM 通过 | “技术上已签名”的邮件,但其签名属于攻击者自己的域名 —— 来自 `evil.com` 的有效签名根本不能用来证明其与 `paypal.com` 有任何关系。 | | Reply-To 不匹配 | BEC/凭证收集:伪造 From: 地址,但将回复路由到攻击者控制的邮箱。 | | 域名伪装检测 | 注册外观相似的域名(`paypa1`、`micros0ft`、`arnazon`),专门因为它们能在一瞥之间不被识破。 | | 子域名中的品牌名 | `paypal.com.security-check.net` —— 利用从左到右的阅读习惯;只有最右侧的可注册域名才能标识所有者。 | | 文本/href 不匹配 | 锚点显示受信任的 URL,而 href 指向其他地方 —— 这种做法没有任何合法理由。 | | 缩短服务与原始 IP | 隐藏目的地并规避信誉过滤;使用没有注册域名的临时或受损主机。 | | 可执行文件 / 双重扩展名附件 | 利用 Windows 隐藏已知扩展名的恶意软件释放器(`invoice.pdf.exe` 会显示为 `invoice.pdf`)。 | | 启用宏的 Office | Emotet/Qakbot 时代的传播链:诱导文本告诉受害者点击“启用内容”,从而运行 VBA payload。 | | 归档文件 / ISO 镜像 | 规避过滤器并绕过 Mark-of-the-Web 清除,导致 SmartScreen 无法发出警告。 | | 紧急性 / 账号威胁 / 索取凭证语言 | 钓鱼攻击的心理核心:人为制造最后期限和对损失的恐惧,从而让受害者放弃进行核实验证。 | | 保密 + 礼品卡措辞 | CEO 欺诈:冒充权威,将受害者与任何可能会说“这是个骗局”的人隔离开来。 | | 通用问候语 | 群发钓鱼工具包无法实现个性化;而你的银行知道你的名字。 | ## 设计说明 - **解读裁定,而非重新验证。** 身份验证结果来自接收服务器写入的 `Authentication-Results` 标头,因为投递时的检查(针对实际连接的 IP)在事后是无法重现的 —— 而且这让该工具能够保持完全离线。 - **信任但要验证标头本身。** 存在多个冲突的 Authentication-Results 标头会被标记,因为攻击者会预先注入伪造的“通过”标头,期望工具会盲目信任第一个标头。 - **评分是分流辅助手段,而非最终裁定。** 报告对此作了明确说明。一个完美的评分并不能洗清一封没有链接的定向 BEC 邮件的嫌疑;最终还是需要分析师去阅读各项具体发现。 ## 后续扩展计划 1. **附件内容检查** — 对附件进行哈希处理 (SHA-256),提取并扫描 ZIP 内部,使用 `oletools` 检测 OLE/OOXML 文件中的 VBA 宏,并可选择针对本地威胁情报列表查询哈希值。 2. **接收链跳分析** — 自下而上遍历 `Received:` 标头,以发现地理/ASN 异常及伪造的早期节点。 3. **同形异义词/IDN 检测** — 将域名伪装检查扩展到 punycode(`xn--`)域名和 Unicode 易混淆字符(例如带有西里尔字母 'а' 的 `pаypal.com`)。 4. **批处理模式 + CSV/JSONL 导出** — 分析整个邮箱的导出文件,并将结果作为自定义事件馈送到您的 Wazuh 实例中以用于仪表板展示。 5. **本地 URL 信誉缓存** — 在进行任何在线查询之前,可选地参考离线列表(例如已下载的 OpenPhish/URLhaus 快照)。 ## 范围与道德规范 仅限防御性分析:该工具仅进行解析和报告;绝不联系 URL、引爆附件或生成内容。示例“钓鱼”邮件是用于测试检测器的静态测试文本。
标签:Python, 安全运营, 扫描框架, 无后门, 逆向工具, 邮件安全, 钓鱼检测