关于Gophish:从二次开发到语义Fuzz的实战之路 作者: 纯情 时间: 2026-01-14 分类: 开源 评论 返回文档 0x00 项目背景与前提 0.1 项目场景 最近接了个钓鱼演练的活,整的焦头烂额,连续爆肝两天,我的主要目标是通过社会工程学手段测试企业员工的安全意识和邮件网关的防护能力。客户环境如下: ● 目标规模: 5000+ 员工,多个事业部 ● 邮件系统: coremail ● 防护措施: 未知 0.2 初始工具选择 作为穷人,公司也并没有提供商业工具,我选择了 Gophish 作为基础钓鱼平台,原因如下: ●✅ 开源且成熟稳定 ●✅ 支持完整的项目管理 ●✅ 内置邮件追踪和统计 ●✅ Go语言开发,便于二次开发 0.3 面临的核心挑战 然而,直接使用原版Gophish进行测试时,我遇到了100%的拦截率: 912345测试结果(Day 1):├─ 发送邮件: 50 封├─ 成功投递: 0 封├─ 被拦截: 50 封└─ 拦截原因: "Suspected phishing activity detected"0x01 发件基础设施搭建:从失败到可信域绕过 在正式进行钓鱼测试前,我首先需要解决邮件投递问题。 1.1 第一次尝试:Postfix SMTP(失败) 初始方案 最开始,我尝试使用自建Postfix邮件服务器直接发送钓鱼邮件:(至于为什么不用ewomail,网上都推荐的这个,因为不是centos,没办法跑,直接找了最简单的进行测试了。) 9123456789sudo apt-get install postfixmyhostname = mail.phishing-domain.commydomain = phishing-domain.commyorigin = $mydomain测试结果 QQ邮箱 通过。 163邮箱 通过。 189邮箱 失败,550。 客户给的测试邮箱 失败 550。 日志输出: 猜测失败原因: 问题189网关判定IP信誉低垃圾邮件发送源无SPF记录伪造发件人无DKIM签名身份不可信域名年龄新钓鱼域名特征反向DNS缺失非正规邮件服务器 投递率:0% (全部被189网关在SMTP握手阶段拒绝) 1.2 第二次尝试:Zoho企业邮箱(成功) 解决思路 既然自建服务器信誉不足,我决定借助成熟的企业邮箱服务: ● 选择Zoho Mail:免费企业邮箱,支持自定义域名 ● 域名准备:购买类似域名,没要求就以便宜的为主了 ● 完整配置:SPF、DKIM、DMARC三件套 Zoho邮箱配置过程 步骤1:注册Zoho企业邮箱 步骤2:配置DNS记录 步骤3:验证配置 步骤4:创建发件账户 测试结果(可信域绕过成功) 第一轮测试:纯文本邮件 结果: 重大突破:通过Zoho企业邮箱 + SPF/DKIM/DMARC配置,189是可以收到邮件的。 正当我以为一切都结束的时候,给客户发,得到的回复依然是收不到。 1.3 第三次尝试:钓鱼模板发送(再次失败) 虽然可信域问题解决了,但当我发送真实钓鱼内容时,又遇到了新的拦截: 测试邮件(含钓鱼内容) 测试结果 这就很有意思了,众所周知大企业一般布有企业级邮件网关,那么他邮件网关到底是拦截的什么,是什么策略?这些我们都不得而知,只有一点点fuzz了。 猜测失败原因: 检测层结果详情✅ SPF验证PASSZoho授权发送✅ DKIM验证PASS邮件签名有效✅ 域名信誉PASSZoho企业邮箱可信❌ 内容检测FAIL触发关键词过滤 猜测被拦截的关键词: 1.4 阶段性总结 经过几轮尝试,我得出以下结论: 已解决的问题 1 可信域检测 → 通过Zoho企业邮箱 + SPF/DKIM/DMARC配置绕过 2 IP信誉问题 → 使用Zoho的可信IP池 3 SMTP握手 → 正常完成,不会在连接阶段被拒绝 仍存在的问题 1 内容关键词检测 → 189网关对邮件内容进行深度扫描 2 钓鱼模式识别 → "点击链接+验证信息"等模式被识别 3 URL路径检测 → "verify"、"login"等路径触发拦截 下一步策略 既然可信域问题已解决,但内容仍被拦截,我需要: 1对Gophish进行二次开发,去除工具指纹。 2继续FUZZ邮件内容找到网关盲区。 这也是本文后续章节的核心内容。 0x02 二次开发阶段:去指纹化改造 2.1 指纹分析 通过我能够发送成功的邮箱获取到未改造前的eml,我识别出以下Gophish特征: 邮件头特征 URL特征 服务端特征 2.2 改造策略 感觉特征有点多,基于分析结果,决定先把Gophish本身的特征改一下。 改造清单 模块原始特征改造方案文件位置邮件头X-Gophish-*完全移除或伪造成业务头models/email_request.goMailerX-Mailer: gophish伪造成常见邮件客户端models/email_request.go服务端Server: gophish移除或伪装成Nginxconfig/config.go追踪路由/track→ /resource/image/pixel.pngcontrollers/route.go上报路由/report→ /api/v1/statuscontrollers/route.go静态资源gophish.css→ app.cssstatic/, templates/404页面Gophish默认页面伪造Nginx 404controllers/phish.go 核心代码改造 1. 移除服务端标识 2. 邮件头特征处理 对比原版Gophish和修改后的版本: 关键改动: 1 不设置 X-Mailer: gophish 2 不设置 X-Gophish-Contact 3 不设置 X-Gophish-Signature 4 添加 X-Priority: 1(提升邮件优先级) 5 添加 Importance: High(标记重要邮件)会在邮箱里面自主设置为红色叹号 6 保留 用户自定义邮件头功能(SMTP配置中可添加) 说明: ●原版Gophish出于"透明度"考虑,会主动添加X-Gophish-*头标识自己 ●我的改进方案是完全不设置这些头,让邮件看起来像普通业务邮件 ● 通过添加X-Priority和Importance头,模仿Outlook等客户端发送的重要邮件 3. 混淆追踪路由 4. 伪造Nginx 404页面 5. 修改参数名称 6. 动态QR码功能开发(借鉴EvilGophish) 这是一个新增的需求。 在测试过程中,猜测如果超链接被拦截,那就是检测的明文URL,于是借鉴了EvilGophish项目,实现了动态QR码生成和CID嵌入功能。 与原版Gophish的区别 原版Gophish的CID支持(已有功能): 使用方式: 1在模板编辑器中上传静态图片(如logo.png) 2 在HTML中使用<img src="cid:logo.png"> 3 限制:所有收件人看到相同的图片(问题就来了,没有办法追踪谁点击了) 改进(基于EvilGophish): 核心区别: 特性原版GophishEvilGophish改进CID嵌入支持支持图片类型静态附件动态生成QR码个性化所有人相同每人专属(含个人ID)URL跟踪无法追踪QR码包含rid参数 为什么需要动态QR码? 根据EvilGophish和相关研究,QR码在钓鱼中具有独特优势: 1 隐藏明文URL - URL被编码为二维码图片,邮件网关的URL检测和沙箱分析无法直接提取 2 提升可信度 - 企业邮件(年终奖、考勤)常用二维码,符合用户认知 3 绕过桌面安全 - 用户用手机扫描,手机浏览器安全警告较弱 4 绕过过滤器 - QR码是图片,不包含文本链接 实现过程(参考EvilGophish) 邮件中使用 生成的邮件结构: CID嵌入 vs 远程加载对比 方案1:CID内嵌(我们采用) 方案2:远程加载(不推荐) 对比分析 特性CID内嵌远程加载优势方避免"显示图片"提示✅ 直接显示❌ 需用户点击CID隐藏服务器地址✅ 无URL❌ 暴露域名CID加载速度✅ 即时显示❌ 依赖网络CID提升可信度✅ 图片完整❌ 可能显示占位符CID邮件网关检测✅ 仅检测Base64❌ 检测外部URLCID追踪能力❌ 无法追踪打开✅ 可追踪加载远程邮件大小❌ 较大(含图片)✅ 较小远程 关键优势解析 1避免邮件客户端安全机制 1隐藏钓鱼服务器地址 1提升邮件真实性 ○ 远程图片:收件人需要主动点击"显示图片",增加怀疑 ○ CID图片:邮件打开即完整显示,符合正常企业邮件习惯。 0x03 困境:FUZZ机制 3.1 新的拦截机制 其实做到上面的的工作,大部分情况下可以操作了,但是我仍然处于被拦截的情况,因为是黑盒测试,我无法收到邮件的反馈,只能按语义检测进行尝试绕过了: 邮件网关的语义检测机制 拦截案例分析 我被拦截的邮件样本: 拦截原因分析: 1 具有引导性词汇: "重要"、"升级"、"验证" 2 行动引导: "请点击" 3 案例模板: "验证账户信息"是经典钓鱼话术 3.2 心路历程 此时我陷入了困境:如果单纯的是关键字检测,这个模板是客户定的,一时半会重改不太现实,等于说是模板改不了的情况下要如何实现发送。 我不知道邮件网关的确切检测规则,纯粹靠猜测和试错。 拦截原因猜测: 检测层触发点详情邮件头检测通过X-Mailer、Subject编码正常纯文本检测通过text/plain部分无敏感词HTML内容检测拦截检测到明文"年终奖金"、"身份证"、"银行卡"URL检测拦截路径包含"verify"、"status"行为模式拦截"点击链接"+"验证信息"模式 啥也不清楚,就此开蒙。 3.3 单变量Fuzz:定位拦截触发点 在知道邮件被拦截后,我需要精确定位到底是什么触发了189网关的拦截。 单变量测试方法 基于smtp_block_tester.py脚本: 测试结果分析; 关键发现 通过单变量Fuzz测试,定位了189网关的拦截规则: 测试变量是否拦截结论纯文本否基线通过普通超链接否链接本身不触发拦截"年终奖"是敏感词触发点1"身份证/银行卡"是敏感词触发点2主题含"年终奖"是主题也会被检测"请点击"否单独不触发 核心结论: 1关键词检测优先级最高:无论在主题还是正文,"年终奖"、"身份证"、"银行卡"都会立即触发拦截 2超链接本身安全:普通HTTP链接不会触发拦截 3组合拦截机制:虽然"请点击"单独不触发,但"请点击链接+敏感词"会提升拦截优先级 下一步策略 既然定位到了明文关键词检测是核心拦截点,接下来可以做的是: 1保留整体邮件结构(Multipart、链接等) 2重点混淆敏感关键词("年终奖"、"身份证"、"银行卡") 3测试HTML混淆技术能否绕过189网关的关键词检测 这就引出了我的核心绕过方案:HTML混淆Fuzz 。 0x04 突破:基于HTML混淆的Fuzz绕过 4.1 困境分析与新思路 在语义层面被拦截后,我陷入了思考: 邮件网关如果检测的是明文内容,有可能还会对HTML进行检测,因为Gophish就支持HTML布局。 "既然语义敏感词无法避免,能否通过HTML混淆让网关看不懂?" 4.2 HTML混淆Fuzz框架 这是一套渐进式HTML混淆测试系统: 核心思路 HTML混淆武器库 基于WAF绕过经验,准备了以下混淆技术: 混淆技术原理示例HTML实体编码将敏感字符转为Unicode实体年终奖 → 年终奖CSS文字反转用CSS reverse文字顺序年终奖 → <span class="r">奖终年</span>HTML注释截断在敏感词中插入注释验证 → 验<!-- x -->证零宽字符插入插入不可见字符分割身份证 → 身<span style="display:none">_</span>份证字体大小0隐藏通过CSS隐藏干扰字符银行卡 → 银<span style="font-size:0">.</span>行卡 自动化Fuzz测试工具 4.3 Fuzz测试实战过程 第一轮:单一混淆技术测试 针对"年终奖"关键词,测试各种混淆: 结论:所有混淆技术都有效!邮件网关只检测明文,不解析HTML混淆。 第二轮:组合混淆测试 测试实际钓鱼场景的完整邮件: 测试结果: 组合方式投递结果说明全部明文✗ 拦截基线仅CSS反转✓ 成功单一混淆有效仅HTML实体✓ 成功单一混淆有效混合混淆✓ 成功多种混淆叠加最佳混合+注释✓ 成功可读性和绕过兼顾 第三轮:Multipart/Alternative测试 结论:添加纯文本版本可显著提升投递率! 测试对比: 邮件格式投递率说明纯HTML(混淆)68%部分网关仍拦截HTML+TXT(TXT安全)89%显著提升!HTML+TXT(两者都混淆)72%TXT也会被检测 最佳实践:纯文本使用安全词汇,HTML中进行混淆 第四轮:CID图片嵌入测试 为了进一步提升可信度,我测试了CID图片(邮件内嵌图片): 测试结果: ●CID图片不会被URL检测拦截 ●可以隐藏真实钓鱼链接 ●提升邮件可信度(看起来像官方邮件) 4.4 Fuzz成果总结 经过几天的持续测试,得出以下结论: 有效的HTML混淆技术 黄金组合方案 最终测试数据对比 0x05 最终解决方案:Gophish集成与模板优化 基于Fuzz测试的发现,我将混淆技术集成到Gophish平台中。 5.1 Gophish邮件生成改造 核心改动 我在gophishV4Modified/models/email_request.go中实现了Multipart/Alternative支持: 改造要点: 1 引入html2text库:自动将HTML转换为纯文本 2 Multipart/Alternative结构: ○ 先设置text/plain(安全内容) ○ 再添加text/html(混淆内容) 1 业务邮件头:添加X-Priority、Importance提升信任度 5.2 钓鱼邮件模板设计 基于Fuzz测试结果,我创建了新的钓鱼模板: 钓鱼模板.html(真实版本) 对应的纯文本版本(可选) 如果手动指定Text模板,使用安全词汇: 策略:纯文本完全干净,邮件网关检测纯文本时无异常;用户打开邮件时默认显示HTML(包含混淆的敏感内容)。 5.3 动态模板生成器(可选) 为了避免重复模板被机器学习识别,可以实现变体生成: 5.4 URL路由混淆增强 配合HTML混淆,我也优化了追踪链接: 5.5 最终方案架构 0x06 最终测试与成果 6.1 全量测试 应用所有绕过技术后,我189的测试邮箱终于进信了。 同时以此策略改了以下邮件标题换为行政通知不出现年终奖等内容,防止邮件title检测,发送了一份测试邮件到客户的企业邮箱: 第二天就收到了好消息: 我擦累终于完事了。 提供一个发送成功的EML信息以供fuzz。 AI分析如下: 开始大批量的进行安全测试: 0x07 后记 这次从0到1的绕过之旅,历时4天,最终完成这个需求。 随着AI技术的发展,邮件网关的检测能力会越来越强。下一步的研究方向可能包括: ●利用合法平台(如Google Docs、OneDrive)进行跳转 ●转向SMS钓鱼(Smishing)等其他渠道 安全对抗是一场永无止境的竞赛。保持学习,持续创新。 附录 A. Gophish改造Checklist B. 参考资源 Gophish官方资源 ●Gophish官方文档 ●Gophish GitHub仓库 Gophish二次开发与改造 ● Sprocket Security - Customizing Gophish - 详细介绍Gophish去指纹化改造方法 ● EvilGoPhish - Gophish与Evilginx3集成方案,支持MFA绕过 ● sneaky_gophish - Docker化的隐蔽Gophish部署方案 ● FreeBuf - Gophish钓鱼平台二次开发 - 二维码替换功能实现 ● CSDN - 基于Gophish的钓鱼渗透测试平台 - 平台化二次开发思路 Evilginx与MFA绕过 ● Evilginx2 官方GitHub - 高级中间人钓鱼框架 ● Evilginx3 文档 - 最新版本使用指南 ● outpost24 - Evilginx与Gophish组合使用 - 红队钓鱼基础设施搭建 邮件网关绕过技术 ●邮件头安全最佳实践 (RFC 5322) ●Fuzzing技术概述 (OWASP) ●社会工程学防御指南 (SANS) 红队钓鱼实战 ● Red Team Cafe - Phishing Infrastructure - 红队钓鱼基础设施搭建 ● HackenProof - Advanced Phishing Techniques - 高级钓鱼技术 ● 腾讯安全 - 钓鱼演练工具Gophish部署 - 企业钓鱼演练实践 END 相关代码已开源至GitHub:https://github.com/25smoking/GophisModified