某一天,你的一个子域名开始提供攻击者的内容——而没有人碰过你的服务器。打补丁、认证和监控在这里都帮不上忙。原因不是入侵,而是你忘了删除的东西。
实际发生了什么(三个阶段)
1. 创建
你创建了一个带有完全限定域名(app-xxxx.<服务商域名>)的云资源,并在自己的区域中添加了一条 CNAME 记录,让sub.example.com指向它。2. 下线(只做了一半)
不再需要时资源被删除了。此时sub.example.com的 CNAME 也应该删除——但没有删。它仍被当作有效域名公布,却指向空无一物:这就是悬空 DNS 记录。3. 接管
攻击者发现了这个悬空的子域名,创建了一个与你曾经控制的 FQDN 相同的资源。从此,发往sub.example.com的流量就到达他们的资源,内容由他们决定。
你的 DNS 区域(没有变化)
sub.example.com CNAME→ app-xxxx.provider.example
↓ 只有目标被删除了
云资源:已删除
这个名称重新变成任何人都能认领
↓ 攻击者创建了相同的名称
攻击者的资源(他们的账户)
由他们决定 sub.example.com 显示什么。你的服务器从未被碰过
CNAME 是薄弱点,因为它指向的是名称
A 记录指向地址,而 CNAME 指向名称——在许多云服务上,这个名称谁先认领就归谁。你一放手,别人就能拿走。文档称 CNAME 记录“尤其容易受到这种威胁”。同样的道理也适用于 MX 记录,后果是发往该子域名的邮件可能被别人收走。
损害不只是一个看起来像假的页面
- 失去对子域名的控制
- 从你自己的域名提供你无法管理的内容——损害品牌、失去信任
- 窃取 Cookie
- Web 应用常常通过通配符(
*.example.com)把会话 Cookie 开放给子域名,任何子域名都能访问它们。被接管的子域名上一个足以乱真的页面,就能从访问者那里收集这些 Cookie——包括标记了 Secure 的 Cookie - 用于钓鱼
- 因为域名经得起核对,从这里发起的钓鱼要有说服力得多
最大的误解:“是 HTTPS,有证书”
文档把这一点列为常见误解并予以否定:持有被接管子域名的攻击者,可以为它申请并获得有效证书。域名验证型证书检查的是申请者在那一刻是否控制着这个名称,所以察觉不到控制权已经易手。
结果是有效证书在为攻击者服务——出现了锁形图标,标记了 Secure 的 Cookie 照样会发送,假网站看起来更可信而不是更可疑。请把证书理解为“谁持有这个名称”,而绝不是“我在和谁通信”。
如何防止:把“先删除 DNS 记录”写进流程
原因不在技术难度,而在下线步骤的顺序。如果先删资源、后删 DNS,中间这段时间子域名就可能被接管。
会出事故的顺序
删除资源 → DNS 以后再说 → 忘了
在此期间,DNS 一直在公布一个有效的、正规的子域名。监控不会告诉你服务器宕机了——因为什么都没宕机。
安全的顺序
先删除 DNS 记录 → 再删除资源
文档建议给带有自定义 DNS 条目的资源加上删除锁,因为锁本身就在提醒:在下线资源之前必须先删除映射——同时也指出,这类措施只有与内部培训结合才有效。
把“删除 DNS 条目”放进下线清单
这是文档给出的第一项预防措施:把它放进服务下线时的必查项目,并教育开发者在删除资源时一并删除 DNS 记录。关键是不把顺序交给任何人的记忆。
让记录的生命周期与资源绑定
一些服务商提供与资源本身绑定的记录类型(别名记录等)。删除资源后,记录会变成空集,所以不会留下指向空无一物的记录。适用范围仅限部分服务,但只要能用就用:它靠设计而不是流程来防止遗忘的记录。
要求证明所有权
有些服务允许你为自定义域名发布一条用于验证所有权的 TXT 记录。有这条记录时,其他订阅就无法验证或接管这个自定义域名。它不能阻止别人创建同名资源,但没有证明所有权的能力,他们就收不到你的流量。能使用这个名称的,是能证明所有权的人,而不是先认领的人。
定期检查 DNS 区域——它存在吗,归你所有吗?
文档给出了两项检查:目标是否存在,以及是否归你所有。第二项最重要,因为**“有响应,所以没问题”不算检查**——来自别人资源的响应,恰恰就是这种攻击。维护一份把 FQDN 端点对应到负责人的服务目录,并作为资产盘点的一部分定期导出。
发现时,不要只删除记录就结束
修复步骤还要更进一步:更新应用代码中对过时子域名的引用,调查是否发生了入侵,并弄清楚为什么下线时没有删除记录,避免再次发生。尤其是,如果你的应用逻辑曾把 OAuth 凭据之类的机密或涉及隐私的信息发送到那个悬空的子域名,这些数据可能已经暴露给第三方。
本站的看法:暴露更多来自你停止使用的东西,而不是你正在构建的东西
安全讨论往往集中在正在构建的东西上,而入侵却常常从已经退役、被遗留的东西开始。没人用的子域名、离职同事的账户、为一次实验搭起来的测试环境、退订后仍保留的会员记录——它们都有一个共同点:“已经不用了”会悄悄地把东西移出监控和审查的范围。停止使用的东西,在被删除之前仍然是资产。所以我们主张把盘点的范围定为你曾经创建过的一切,而不是当前正在运行的东西。那些在解约后仍被卷入服务商泄露范围的人,就是同一问题的例子(主机服务商被入侵时该怎么做)。
出处(一手资料)
- Microsoft「Prevent dangling DNS entries and avoid subdomain takeover」(Microsoft Learn / Azure 安全基础)— learn.microsoft.com(三个阶段、CNAME 为何尤其脆弱、窃取 Cookie 和 MX 记录、对证书误解的否定,以及预防和修复步骤——删除锁、别名记录、所有权验证、定期检查——都来自这份文档)
接下来阅读
FAQ
Q子域名被接管,是不是意味着我的服务器被入侵了?
不是,这正是它棘手的地方。被接管的是 DNS 指向的目标,而不是你的服务器。如果你删除了云资源,却在 DNS 区域里留下了 CNAME 记录,第三方只需在自己的订阅下创建一个具有相同完全限定域名的资源,发往你子域名的流量就会到达他们那里。打补丁、认证和监控在这里都帮不上忙,因为它们都没有参与其中。
QHTTPS 不能防止吗?有证书总该安全了吧?
不能,微软的文档直接把这点列为常见误解:持有被接管子域名的人,可以为它申请并获得有效证书。域名验证型证书只证明持有它的一方此刻控制着那个名称——它说明不了对方是谁,也察觉不到控制权已经易手。有效证书反而对攻击者有利,让假网站看起来更可信。
Q如果只影响外观,损害不就有限吗?
会话会泄露。Web 应用常常通过通配符(*.example.com)把会话 Cookie 开放给子域名,这种情况下任何子域名都能读取它们。如果能把用户引导到被接管的子域名,即使是标记了 Secure 的 Cookie 也可能落到攻击者手里。而悬空的 MX 记录意味着发往该子域名的邮件可能被别人收走。
Q实际上该怎么防止?
把删除顺序做成流程和机制,而不是靠人记住。文档建议:把“删除 DNS 条目”放进服务下线时的必查清单;给带有自定义 DNS 条目的资源加上删除锁,让锁本身提醒必须先删 DNS;在可用的情况下使用生命周期与资源绑定的记录类型;并定期检查 DNS 区域,确认每个目标都存在、而且归你所有。