官网:http://securitytech.cc/
子域名接管(Subdomain Takeover)

简介
想象你正在访问 blog.example.com。
1. 浏览器: “blog.example.com 的 IP 地址是什么?”
2. DNS 服务器: “blog.example.com 指向 company-blog.github.io (CNAME)”
3. 浏览器: “那 company-blog.github.io 的 IP 是多少?”
4. GitHub DNS: “185.199.108.153”
5. 浏览器: 连接 GitHub 服务器 → 显示博客内容
在正常情况下,这个过程完全没问题。
但如果公司停止使用 GitHub Pages 并删除了 company-blog.github.io 仓库,却忘了删除 DNS 记录会怎样?
1. 浏览器: “blog.example.com 的 IP 地址是什么?”
2. DNS 服务器: “blog.example.com 指向 company-blog.github.io” (依然如此!)
3. 浏览器: “那 company-blog.github.io 的 IP 是多少?”
4. GitHub: “404 — 没有对应的 GitHub Pages 网站”
此时,如果攻击者新建了一个名为 company-blog.github.io 的仓库并发布页面:
1. 浏览器: “blog.example.com 的 IP 地址是什么?”
2. DNS 服务器: “blog.example.com 指向 company-blog.github.io”
3. 浏览器: “那 company-blog.github.io 的 IP 是多少?”
4. GitHub: “185.199.108.153” (攻击者的页面!)
5. 浏览器: 显示攻击者内容
用户依然以为自己访问的是可信的 blog.example.com,但实际上看到的是攻击者控制的页面。
这就是 子域名接管(Subdomain Takeover, STO)。
注意:虽然这里以 GitHub Pages 举例,但现在几乎不可能再通过 GitHub Pages 完成接管,因为它只允许 [username].github.io 格式(参考:issue #416)。我在写这篇文章时甚至收到了 GitHub Pages STO 警报并尝试接管,结果发现 vulnerable.github.io 需要一个用户名为 “vulnerable” 的 GitHub 账号 :(
什么是子域名接管?
子域名接管(STO)是一种漏洞,出现在组织的子域名指向了一个外部服务(如 AWS S3、GitHub Pages、Heroku 等),但当该外部资源被删除或停用后,攻击者可以创建相同名称的资源,从而劫持该子域名。
正常情况 blog.example.com → CNAME → myblog.github.io → GitHub Pages(有效) 用户 → blog.example.com → 公司合法的博客内容
悬空 DNS(Dangling)状态 blog.example.com → CNAME → myblog.github.io → X(已删除) 用户 → blog.example.com → “404 — Not Found” 页面
接管状态 blog.example.com → CNAME → myblog.github.io → 攻击者的 GitHub Pages 用户 → blog.example.com → 攻击者的恶意内容
这种情况被称为 悬空 DNS(Dangling DNS),即 DNS 记录存在,但其指向的目标资源不存在。
为什么会发生?
根本原因在于:DNS 记录的生命周期与外部服务的生命周期不同步。
比如,开发团队创建了 test.example.com 并将其指向一个 AWS S3 bucket 用来测试新功能。
项目结束后,他们删除了 S3 bucket 以节省成本,但忘了删除 DNS 记录。
此时如果攻击者新建一个同名 S3 bucket,test.example.com 就会显示攻击者的内容。
常见原因包括:
- 临时项目或 POC 没有清理干净
-
- 服务迁移过程中的失误
-
- 团队之间缺乏沟通
-
- DNS 与基础设施由不同团队管理
子域名接管的类型
大多数子域名接管案例都是 基于 CNAME 的接管。 我整理了 HackerOne Hacktivity 上公开的 167 个子域名接管案例(见:subdomain_takeover.json)。
CNAME 型接管
这是最常见的一类,当 CNAME 记录指向了一个不存在的外部服务时,就可能发生接管。
subdomain.example.com. IN CNAME abandoned-app.herokuapp.com.
虽然理论上其他 DNS 记录类型(A、NS、MX、SRV)也可能导致接管,但现实中绝大多数案例都是 CNAME 型。其他类型如今极少可利用,只是为了完整性才被提及。
方法论
1. 子域名枚举 第一步是找到目标域名下的所有子域名。因为每个子域名可能连接到不同外部服务,都需要检查。 相关工具:subfinder、amass、sublist3r
2. 检查悬空状态 检查枚举出的子域名是否处于悬空状态,常见提示包括 “Not Found”、“404”、“There isn’t a GitHub Pages site here”。 相关工具:nuclei、subzy、baddns、can-i-takeover-xyz
3. 尝试接管 一旦确认处于悬空状态,就尝试通过创建相同资源完成接管。
自动化方式
Oneliner 扫描
漏洞猎人常用的一行命令:
subfinder -d target.com -silent | httpx -silent | nuclei -t /nuclei-templates/http/takeovers/
持续监控
我构建了一个自动化监控系统(stomon),每 24 小时运行一次: 流程:子域名枚举 → STO 扫描 → LLM 分析 → Telegram 通知
GitHub 项目地址:stomon
利用影响
接管本身就是漏洞 子域名接管本身就是严重的安全威胁。用户以为自己访问的是合法子域名,但实际上看到的是攻击者控制的页面。
高级利用:认证绕过 最危险的情况出现在认证机制上。 以 Uber 的案例为例(Arne Swinnen 发现,报告:219205):
Uber SSO 认证绕过(2016)
- saostaging.uber.com 指向 AWS S3(悬空状态)
- 攻击者创建并控制该 S3 bucket
- SSO Cookie 在 *.uber.com 下共享
- 攻击者窃取会话 Cookie → 访问所有 Uber 账户
该漏洞允许攻击者绕过 Uber 的整个认证系统。
防护措施
- 立即删除未使用的 DNS 记录
-
- 持续监控子域名
-
- 团队间保持一致,确保 DNS 与云资源管理同步
参考资料
-
HackerOne: A Guide To Subdomain Takeovers 2.0
-
Subdomain Takeover in Azure
-
Arne Swinnen: Authentication Bypass on Uber’s SSO
-
Can I Takeover XYZ — 漏洞服务清单
-
OWASP: Subdomain Takeover