子域名接管(Subdomain Takeover)

113 阅读4分钟

官网: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)

  1. saostaging.uber.com 指向 AWS S3(悬空状态)
  1. 攻击者创建并控制该 S3 bucket
  1. SSO Cookie 在 *.uber.com 下共享
  1. 攻击者窃取会话 Cookie → 访问所有 Uber 账户

该漏洞允许攻击者绕过 Uber 的整个认证系统。


防护措施

  • 立即删除未使用的 DNS 记录
    • 持续监控子域名
    • 团队间保持一致,确保 DNS 与云资源管理同步

参考资料

公众号:安全狗的自我修养

vx:2207344074

Gitee:gitee.com/haidragon

GitHub:github.com/haidragon

Bilibili:haidragonx