首发至公众号Yofune安全研究 欢迎关注。隐匿与对抗——构建不可溯源的基础设施本文是「邮件钓鱼攻防工程」系列的第二篇。上一篇我们拆解了传统钓鱼框架GoPhish的架构债务与检测面。这一篇深入基础设施层从域名获取、网络拓扑、TLS指纹到探针逐层拆解如何构建一套经得起威胁情报溯源、沙箱分析的基础设施。0x01 基础设施的生存窗口基于OPSEC守则红蓝对抗中基础设施的存活时间决定成败因素。用一台公网IP裸奔的VPS挂一个刚注册12小时的域名HTTPS还是自签证书——可以设想一下没有更改过特征的原生CS这套设施的生存周期通常不超过10分钟。现代企业的纵深防御体系拥有多维度情报源•邮件网关SEG国内主流邮件安全网关奇安信邮件安全网关、深信服邮件安全网关、Coremail论客的域名信誉模块会综合域名注册时长、发信历史、SPF/DKIM配置状态等维度打分。网易企业邮、腾讯企业邮等云端服务则内置了基于发信行为画像的反垃圾引擎对注册不足30天的新域名默认增加风险权重。国际厂商如Proofpoint TRAP实时关联域名信誉与URL分类、Spamhaus DBL的域名黑名单在国内也有一定部署主要用于在华外企和跨国企业。•网络边界下一代防火墙华为HiSec、深信服AF、奇安信智慧防火墙和上网行为管理设备深信服AC、网康的TLS解密模块可提取Client特征。国内多数甲方企业采购上网行为管理时已附带SSL审计功能虽然性能损耗显著但一个配置了SSL审计的网络出口确实能够生成JA3/JA4指纹用于识别非浏览器自动化工具。•端点与沙箱国内EDR市场以奇安信天擎、深信服EDR、火绒企业版等等。邮件沙箱方面奇安信天眼沙箱、微步在线OneSandbox国内沙箱即服务代表、安恒威胁情报沙箱等安全厂商的设备能力均会对邮件中的URL执行headless浏览器爬取提取DOM结构和JavaScript探针返回内容。部分厂商沙箱已支持Chromium内核完整JavaScript执行猜测不确定。•威胁情报中心国内SOC团队常用的CT日志监控路径与海外不同相比较直接订阅国外大厂的安全情报API实时推送在国内网络环境下不稳定主流做法是通过奇安信威胁情报中心、微步在线ThreatBook的域名监控服务设置与组织域名相似的新注册域名告警规则。阿里云和腾讯云DNSPod也提供了面向企业客户的域名注册监测API。设施即第一要素这就意味着面向实战的钓鱼演练平台必须在架构上将反溯源和高隐匿作为第一等优先措施。0x02 域名信誉工程从获取到养护基础设施的第一步不是买服务器是买域名。域名的信誉级决定了邮件能否通过SEG的第一道关卡。2.1 抛弃新域名拥抱老域名红队常见错误为某次行动注册一个corp-login-update.com这样的新域名。致命问题在于域名年龄太短。有些安全厂商明确的会把域名注册时长当作核心因素之一。新域名注册后立刻发送含链接邮件大概率进入垃圾箱或被直接隔离550 5.7.1。这一点在国内的189邮箱136邮箱163邮箱上都有经历。实战获取策略老域名收购。寻找已有数年历史、被域名注册商归类为科技或商业的正常域名因为忘记续费而进入冷却期间。这类域名自带初始信誉。据The Record报道2024年某9年历史的老域名digitalscrapbookingfreebies.com冷却后被钓鱼团伙重新注册成功绕过某州卫生机构的邮件网关。域名年龄数据来自Whois历史记录信誉分数则继承自域名的DNS解析历史和SSL证书签发连续性。子域名接管。2024年2月Guardio Labs研究员Nati Tal和Oleg Zaytsev揭露了代号ResurrecAds的大规模子域名接管活动参见Guard.io研究论文。攻击者扫描大型企业MSN、VMware、McAfee、Cornell University、UNICEF等的过期CNAME记录——例如marthastewart.msn.com的CNAME指向一个已废弃22年的域名msnmarthastesweeps.com。重新注册该域名后即可用marthastewart.msn.com发信直接继承MSN的顶级信誉。该活动高峰期每日发送约500万封恶意邮件使用约22,000个唯一IP地址含住宅ISP代理每个劫持域名仅使用1-2天即轮换。Guardio Labs提供了免费检测工具checker.guard.io。同态形似词Homoglyph与Punycode。利用Unicode字符视觉混淆——拉丁字母a(U0061) 与西里尔字母а(U0430)拉丁字母o(U006F) 与希腊字母ο(U03BF)。现代浏览器Chrome 58、Firefox 58、Edge对跨脚本混合有Punycode自动显示机制当域名包含不同Unicode脚本集的字符时地址栏强制展示xn--编码形式。但2025年腾讯云安全团队的研究指出单一脚本内如全日语Hiragana字符集内的同形混淆仍能绕过浏览器检测——例如用ん(U3093) 替代/构造https://account.booking[.]comんdetail这种在视觉上看起来像子目录结构的钓鱼URL。至今仍然活跃在在Web3的攻击事件中•蓝队对策利用confusables-inspectorGitHub开源工具2025年6月更新自动检测同形字符在SEG侧对邮件正文中所有URL进行Punycode解码检测。2.2 邮件认证协议的正确配置SPF、DKIM、DMARC已是必选项而非可选项。如果想让钓鱼邮件进入受害者收件箱这是条件之一。•SPF的include:链劫持SubdoMailing活动展示了SPF的include:机制可作为攻击面——当企业SPF记录引用了一个已废弃的外部域名攻击者注册该域名后即可注入恶意内容。•DKIM的选择长度建议使用rsa-sha256且密钥长度至少2048位。1024位密钥面临暴力破解风险参考CVE-2023-50387中DNSSEC密码学分析的前车之鉴。•DMARC策略自建邮件网关中 这是不可或缺的一部分。应将DMARC设为vDMARC1; preject;——这看似严苛的策略反而增加了域名的可信度因为显得域名所有者非常重视邮件安全。0x03 网络拓扑别让蓝队摸到你的真实IP长久以来直接将钓鱼平台的公网IP写入域名A记录意味着蓝队可封禁IP、扫描开放端口、通过ASN溯源VPS供应商并向IDC提交Abuse投诉封机这一点在国内云依然有效参考华为云/腾讯云/阿里云的策略不仅有来自内部的扫描封机外部同样如此。3.1 Cloudflare Tunnel从被动入站到主动出站当初在构建TaiGong项目的时候这一点也是参考了一些国外的技术文章总的来说就是利用隧道技术完成对整个基础设施的隐藏。Nginx在一定程度上能力有限于是我们摒弃传统反向代理全面采用Cloudflare Tunnel。工作原理在服务器本地运行cloudflared守护进程主动向Cloudflare边缘节点发起出站HTTP/2或QUIC长连接默认连接到7844端口。服务器不需要开放任何入站端口——防火墙安全组可以配置为拒绝所有入站流量。当请求到达Cloudflare边缘节点时通过已建立的隧道复用流将请求透传至本地回环地址127.0.0.1:80。核心收益|维度|传统反向代理|Cloudflare Tunnel|| :-- | :-- | :-- ||入站端口|必须开放80/443|无需任何入站端口||IP隐匿|CDN兜底但源站IP可能被网络测绘引擎FOFA、ZoomEye钟馗之眼、Shodan的历史数据扒出|物理级隐藏测绘引擎只能扫到CF节点IP||ICP备案|国内云服务器未备案域名会被ISP网络层RST阻断|出站流量不受Host头嗅探影响完美穿透||DDoS防护|依赖前置CDN|CF边缘天然抗D|CDN前置鉴权仅靠Tunnel还不够——蓝队拿到域名后仍可用脚本进行请求调用导致数据库产生大量脏数据据此可以参考Cs伪装上线一样的反制手法。TaiGong的解决方案是结合Cloudflare Transform Rules在边缘节点为所有合法请求注入自定义Header后端的TaiGong引擎只在验证Header正确后才返回钓鱼页面。没有令牌的请求测绘引擎、沙箱爬虫、直接扫描被302重定向到无害目标如https://www.baidu.com从根源上尽量避免空间引擎扫描以及溯源追踪。•蓝队对策检测异常高频出站连接到[IP范围]:7844Cloudflare Tunnel端口通过流量设备识别Tunnel特征流量关注观察请求包中的不常见头信息。3.2 边缘层环境感知过滤在Cloudflare Workers或Edge Functions实现第一道过滤逻辑基于请求特征选择性回源ASN黑名单ASN黑名单过滤云服务商和安全公司的ASN——这些IP段几乎不可能是真实受害者。- 阿里云AS45102、AS37963国内最大的公共云覆盖华东1/2、华北1/2/3、华南1等地域几乎所有的国内商业SEG沙箱和第三方邮件安全服务商的爬虫节点都部署在阿里云上。- 腾讯云AS45090、AS132203腾讯云公网出口腾讯企业邮和微信企业邮箱的安全检测模块的沙箱流量从此出站。- 华为云AS55967华为云公网出口部分政企客户的邮件安全。安全厂商ASN奇安信深信服、知道创宇扫描节点IP段——这些厂商的邮件沙箱和威胁情报爬虫通常有固定的出口IP段但是我并没有找到具体CIDR范围。以上参考资料均来源于https://bgp.tools/Bot Management Score利用Cloudflare的Bot Management引擎对分数低于30的请求返回虚假内容。Geo-IP限制根据演练目标受众的地理位置限制来源国家如果你已知目标的IPC范围地址那么可以直接限制到市以内超出范围的请求直接丢弃。类似后文实现的地理围栏功能如果使用CDN的话就可以直接实现。0x04 TLS指纹对抗JA3/JA4与uTLS逃逸这部分是攻防博弈中最底层的技术细节——TCP/IP之上的第一层。4.1 ClientHello指纹原理客户端发起HTTPS连接时发送ClientHello报文包含TLS版本、密码套件Cipher Suites、扩展列表Extensions、椭圆曲线Elliptic Curves、压缩方法等字段。不同软件栈发送的ClientHello结构存在固定差异•JA3Salesforce 2017提出将特定字段串联后MD5哈希生成32字符指纹。例如Go的默认JA3指纹为771,4865-4866-4867-49195-49199-49196-49200-52393-52392-49171-49172-156-157-47-53,0-23-65281-10-11-35-16-5-13-18-51-45-43-27-21,29-23-24,0。•JA4FoxIO 2023提出更结构化的分级指纹方案格式为t13ics_ext_groups移除了MD5哈希支持对TLS握手的两侧分别指纹化JA4 Server / JA4 Client / JA4S / JA4XSS等。如果使用Go标准库net/http或gomail发起请求网络流量携带Go独有的JA3/JA4指纹。开源方案如Zeek的ja4 plugin、Suricata的JA3支持国内商业方案如奇安信天眼、绿盟NTA、科来网络分析系统的TLS指纹检测模块还有部分厂商的全流量设备等在边界看到陌生的外联IP正频繁特定的指纹包进行TLS握手且行为类似POST凭证收集可立刻阻断。4.2 uTLS浏览器模仿TaiGong借鉴了refraction-networking/utlsGitHubGo 1.21的方案。uTLS是Gocrypto/tls的fork允许程式化地对ClientHello进行精确控制•预置浏览器模板HelloChrome_Auto、HelloFirefox_Auto、HelloSafari_16_0、HelloIOS_14等精确模仿对应浏览器的密码套件顺序、扩展列表和椭圆曲线组合。•随机化指纹HelloRandomized从uTLS所有支持的密码套件和扩展中随机选取组合适用于绕过黑名单式检测。•自定义指纹HelloCustom允许完全手动构建ClientHello——可以先捕获真实浏览器的ClientHello报文通过tcpdump或Wireshark然后用Fingerprinter.FingerprintClientHello()反向解析为uTLS配置再ApplyPreset()实现精确复制。重要限制uTLS目前只能在ClientHello阶段模仿浏览器。tls-client尽管实现了服务器Hello验证阶段的类似模仿但成熟度不如uTLS。另外Go标准库缺少TLS 1.3的某些扩展支持如Compressed Certificate导致部分Chrome模板在特定服务器握手失败。参考GitHub Issue [#321](javascript:。4.3 GREASE对抗GREASERFC 8701定义了TLS GREASEGenerate Random Extensions And Sustain Extensibility机制本意是确保协议扩展的向后兼容性。Chrome率先在ClientHello中随机插入GREASE密码套件如0x0A0A和扩展类型防止服务器因遇到未知值而中断连接。有趣的是GREASE反而让JA3检测变得更加困难因为Chrome每次连接可能发送不同的GREASE值JA3指纹也随之变化。•红队进阶手法在uTLS自定义ClientHello中主动加入GREASE值使指纹更接近真实Chrome。但需要维持一致性——AI模型如PerimeterX、DataDome的ML分类器不仅看单次握手指纹还分析整个会话的TLS行为一致性例如握手完成后发送的HTTP/2 SETTINGS帧序列是否与浏览器一致。0x05 载荷层对抗多级探测页面基础设施隐匿的最后防线在着陆页本身。taigong在这一层采用的是客户端JS探针 服务端多因子联判的双层架构。这篇内容部分照搬了TaiGong项目中《第6章 高级识别之争》的研究笔记目前不是很玄乎也不是特别优秀的构思刚好发出来举个栗子了。5.1 客户端双层探针magic.js finger.jstaigong在每个落地页模板中注入了两个独立的客户端脚本一个magic.js一个fing.js。他们的作用大概如下.检测 navigator.webdriver• 检测 UA 中的 HeadlessChrome/PhantomJS 等关键词• 检测 Chrome DevTools Protocol 是否已连接• 检测 navigator.plugins 是否为空• 检测 navigator.languages 是否存在• 检测 window._phantom、window._selenium 等自动化框架属性• 检测 window.outerWidth/outerHeight 是否为零• 检测 Notification.permission 与权限 API 查询结果是否矛盾• 检测 WebGL 渲染器是否为 SwiftShader/llvmpipe 等软件渲染器• 检测 performance.timing 的 DOM 解析耗时是否短于 5ms判定逻辑signals 2默认阈值时直接document.write将整个页面替换为Nginx标准404 HTML。100ms后setTimeout再跑一次覆盖异步加载的检测如权限API。检测到沙箱后还会向服务端发一个/report?idxxxreasonsandboxer的像素上报用于统计。红队视角这个探针的工程取舍是明确的——宁愿漏报也不误报因为在我看来钓鱼演练更重要的是效果送达率。阈值设为2意味着单个异常信号如仅UA匹配了HeadlessChrome不会触发阻断只有两个以上独立维度同时命中才判定为沙箱。在Taigong的实际使用中后端控制了这一点你可以通过修改threshold变量调整灵敏度建议范围1-3。蓝队视角magic.js的检测逻辑是静态的、完全可溯源的的。它检测不到以下场景• 使用真实Chrome实例非headless模式的沙箱——WebDriver标记被抹除、WebGL渲染器正常、插件存在• 从真实办公网络IP出站的爬虫——不命中任何静态检测项•puppeteer-extra-plugin-stealth 真实浏览器实例的组合——第1、3、4、5项全部被绕过这从反面说明了为什么服务端联判必不可少。fing.js客户端环境采集— 与magic.js同时注入的第二个脚本在magic.js判定非沙箱后执行。采集内容包括• Canvas指纹固定文本固定颜色固定矩形的canvas.toDataURL()哈希值——不同浏览器/OS/GPU组合产生不同的渲染结果• 浏览器属性navigator.userAgent、navigator.language、navigator.platform• 屏幕属性screen.width×screen.height• 环境属性时区偏移new Date().getTimezoneOffset()、触屏支持ontouchstart in window、Cookie启用navigator.cookieEnabled、DNT设置navigator.doNotTrack采集数据通过POST发送到后端端点服务端将其与click事件关联写入数据库用于后续的受害者行为画像和风险评分。5.2 服务端多因子联判CheckEvasiontaigong在服务端函数中执行了以下判定优先级从高到低JA4黑名单客户端TLS指纹精确匹配已知扫描器/沙箱库如Evilginx的t13d191000_9dc949149365_e7c285222651IP黑名单支持精确IP、CIDR、通配符前缀三种格式云厂商IP阻断内置200条CIDR规则覆盖AWS/Azure/GCP/阿里云/腾讯云爬虫UA拦截35个已知Bot UA关键词从Googlebot/Bingbot到python-requests/Go-http-client到VirusTotal/Censys常见的都在添加。三级地理围栏支持国家级CN、省级CN-广东、市级CN-广东-深圳多区域逗号分隔混用判定为可疑后根据配置执行返回302重定向到合法网站、返回伪装Nginx 404、或照常显示。再举个实际场景的例子假设一次针对某公司财务部的演练邮件伪装成年度审计通知落地页是伪造的 Office 365 登录框。第一层——服务端请求还没到落地页就被拦部分邮件网关在用户收到邮件之前就已经在后台访问了这个链接。请求到达 taigong 服务端时• 云厂商 IP 阻断出口 IP 落在 腾讯CDN的 CIDR 段里 → 如果开启了 云厂商IP拦截直接返回302跳转到百度首页。网关看到的是这个链接会跳转到百度判定安全。• 即使云厂商检测没开UA 检测TencentCloud的 UA 里含TencentCloud/Tencent-Cloud关键词命中爬虫黑名单 → 同样被拦截。第二层——magic.js服务端没拦住落地页已返回但沙箱看不到真内容假设换了个高级沙箱——从真实办公网络 IP 出站、自定义了正常浏览器 UA、没命中 JA4 黑名单——成功拿到了落地页 HTML。此时 magic.js 开始执行• navigator.webdriver true → 1沙箱用 Selenium/Playwright 驱动• navigator.plugins.length 0 → 1headless 没装插件• 加载时间 5ms → 1机器秒开 DOMsignals 3 2触发阻断。document.write 把浏览器的整个 DOM 替换成404 Not Found同时发一个像素上报/report?idAb7Xk2Qreasonsandboxer。沙箱的视角它以为自己访问了一个已经下线的页面404什么钓鱼特征都没抓到。沙箱判定安全。真实用户的视角收到邮件点击链接浏览器正常打开落地页。magic.js 跑了一遍——navigator.webdriver 是 false插件正常加载渲染耗时正常几百毫秒——signals 0不触发阻断。页面正常显示 Office 365 登录框。输密码、提交、跳转。全程无感。所以这套设计的实际设想是不是阻止沙箱访问而是让沙箱和真人看到不同的东西。沙箱看到 Nginx 404真人看到钓鱼表单。两层防线叠加后沙箱要在服务端绕过 IP/UA/JA4 三层过滤还要在客户端同时命中不到 2 个检测信号看起来反溯源设计是不是很合理这套设计仍然有弊端性存在。5.3 这个方案的实际效果与局限性局限性•没有行为分析magic.js不做鼠标轨迹追踪、不做滚动检测、不做Fitts定律分析。市面上有些商业反检测方案把这些写进白皮书但工程上行为分析延迟高、误报多、资源消耗大在钓鱼场景下性价比不如静态检测。•没有延迟渲染Landing Page的HTML是完整返回的magic.js在页面已渲染后执行替换。SEG如果能dump出magic.js执行前的DOM快照仍然能看到钓鱼表单。Sandbox的进化方向恰好是捕获初态DOM。•不是叠加态叠加态这只是我一种之前的设想目前并没有找到一个好的思路进行实现。目前的实际逻辑是检测到沙箱后销毁页面而不是不确定身份时不显示。这个区别在工程上很关键——初次响应不含任何恶意元素的真正叠加态需要服务端在收到客户端探针回调后才下发钓鱼内容这带来了额外的延迟和复杂度。以上就是所有我对钓鱼行动安全的基础设施建设看法但在如今的攻防对抗中即使基础设施完美隐匿一旦进入内容对抗阶段传统的静态HTML和硬编码话术依然会被AI分类器如Microsoft Defender的ML模型、Exchange Safety AI无情击杀。下一篇将深入邮件正文的对抗多态HTML与语义稀释引擎实现让每封钓鱼邮件都成为独一无二的指纹尝试调试贝叶斯和NLP分类器的防线。参考资料•SubdoMailing Research— Guardio Labs, Nati Tal Oleg Zaytsev, February 2024. https://guard.io/labs/subdomailing-thousands-of-hijacked-major-brand-subdomains-found-bombarding-users-with-millions•Cloudflare Tunnel Documentation. https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/•JA4 Network Fingerprinting— FoxIO LLC. https://github.com/FoxIO-LLC/ja4•ja4-nginx-module— FoxIO. https://github.com/FoxIO-LLC/ja4-nginx-module•Refraction Networking uTLS. https://github.com/refraction-networking/utls•RFC 8701 — TLS GREASE. https://datatracker.ietf.org/doc/html/rfc8701•Cisco Talos Sender Maturity FAQ. https://www.cisco.com/c/en/us/support/docs/security/email-security-appliance/215660-sdr-sender-maturity-faq.pdf•Proofpoint Emerging Threats Intelligence. https://www.proofpoint.com/us/products/advanced-threat-protection/et-intelligence•IDN Homograph Attack Japanese Character Confusion— Tencent Cloud Security, 2025. https://cloud.tencent.com/developer/article/2597395•confusables-inspector— OpenSecurity, 2025. https://github.com/opensecurity/confusables-inspector•Certifiably Vulnerable: Using Certificate Transparency Logs for Target Reconnaissance— Pletinckx et al., IEEE EuroSP 2023. https://doi.org/10.1109/EuroSP57164.2023.00038•Don’t Phish-let Me Down: FIDO Authentication Downgrade— Proofpoint US. https://www.proofpoint.com/us/blog/threat-insight/dont-phish-let-me-down-fido-authentication-downgrade•FIDO authentication undermined— CSO Online. https://www.csoonline.com/article/4040128/fido-undermined.html•Puppeteer Stealth Anti-Detection. https://scrapingant.com/blog/avoid-detection-with-puppeteer-stealth•Impact Assessment of Adversary-in-the-Middle Attack Evilginx Bypassing 2FA— Springer ICR 2025. https://link.springer.com/chapter/10.1007/978-3-031-95652-2_14•Browser Fingerprinting Techniques. https://fingerprint.com/blog/browser-fingerprinting-techniques/•Aged-domain acquisition bypass— The Record / newestek.com. https://cybersecurityinfocus.com/?p8455