2011年11月,巴西数百万互联网用户在访问Google、Gmail、YouTube时被重定向到一个要求安装"Google Defence"软件的页面。这个所谓的安全软件实际上是一个银行木马。攻击者并未入侵Google的服务器——他们只是修改了几家ISP的DNS缓存记录。这个事件揭示了DNS缓存投毒攻击的恐怖之处:攻击者不需要攻破目标服务器,只需要欺骗DNS解析器。

十五年后,2025年10月,BIND 9发布紧急安全公告,CVE-2025-40778漏洞让DNS缓存投毒再次成为焦点。这不是一个新问题,而是一个反复复活的老问题。从2008年Dan Kaminsky的发现,到2020年的SAD DNS攻击,再到2023年的MaginotDNS,DNS缓存投毒从未真正消失。

DNS协议的先天缺陷

理解DNS缓存投毒,必须从DNS协议的设计说起。DNS诞生于1983年,彼时互联网还是一个以信任为基础的学术网络。协议设计者关注的是效率和可靠性,而非安全。

DNS查询默认使用UDP协议。UDP是一个无连接协议:客户端发送一个数据包,服务器返回一个数据包,没有握手过程,没有会话状态。这种设计带来了极高的效率——一个DNS查询通常在几十毫秒内就能完成——但也带来了致命的安全缺陷。

当一个DNS解析器向权威服务器发送查询时,它如何验证收到的响应确实来自那个服务器?DNS协议的答案是:检查16位的事务ID(Transaction ID)。客户端在查询中设置一个随机ID,服务器在响应中返回相同的ID。如果ID匹配,响应就被接受。

问题在于,16位ID只有65536种可能。更糟糕的是,早期DNS实现使用顺序递增的ID,攻击者只需观察一个查询就能预测下一个ID。即便使用随机ID,攻击者也有约1/65536的概率猜中——在网络世界中,这是一个可以暴力破解的范围。

DNS响应匹配验证的要素包括:源IP地址(应为权威服务器地址)、目的IP地址和端口(应与查询匹配)、事务ID(应与查询匹配)、查询问题(应与查询一致)。攻击者的目标是伪造一个满足所有条件的响应,并在真正的权威服务器响应之前到达。

缓存投毒的基本手法

DNS解析器的一个重要特性是缓存:一旦解析了某个域名,结果会被缓存一段时间(TTL,Time To Live)。在TTL过期前,相同查询直接从缓存返回。这提高了效率,也成为了攻击的目标。

基础缓存投毒攻击的流程如下:攻击者向目标解析器发送一个针对目标域名的查询;解析器向该域名的权威服务器发送查询;攻击者向解析器发送大量伪造的响应,尝试猜中正确的事务ID;如果伪造响应在真实响应之前到达且ID正确,解析器将接受伪造结果并缓存。

但这个基础攻击有一个致命弱点:一旦攻击失败,解析器会缓存正确结果,攻击者必须等待TTL过期才能再次尝试。对于热门域名,TTL可能只有几分钟,但攻击窗口仍然非常狭窄。

Kaminsky的突破:绕过TTL限制

2008年夏天,安全研究员Dan Kaminsky发现了一种革命性的攻击方法,彻底改变了DNS缓存投毒的游戏规则。

Kaminsky的核心洞察是:不必攻击目标域名本身,可以攻击它的子域名。假设目标是example.com,攻击者不直接查询www.example.com,而是查询random123.example.comrandom456.example.com等不存在的子域名。

每次查询一个新的随机子域名时,解析器都必须进行完整的DNS解析——因为这个子域名从未被查询过,不存在缓存。更重要的是,在解析过程中,权威服务器的NS记录会被缓存。Kaminsky的攻击目标正是这个NS记录。

在伪造的响应中,攻击者不仅返回一个IP地址,还在Authority段中包含伪造的NS记录,声称某个由攻击者控制的服务器是example.com的权威服务器,并在Additional段中提供该服务器的IP地址。一旦这个伪造响应被接受,解析器就会将整个example.com域名的解析权交给攻击者。

这意味着攻击者可以绕过TTL限制:每次查询新的随机子域名都创造一个新的攻击机会。攻击者可以以极高频率发送查询和伪造响应,大大提高成功率。根据CZ.NIC实验室2009年的测试数据,在理想条件下(源端口固定),攻击可以在几秒到几分钟内成功;即使源端口随机化,攻击也可能在几小时到几天内成功。

Kaminsky的发现导致了互联网历史上最大规模的同步补丁行动。2008年7月8日,微软、思科、Sun等主要厂商同时发布补丁,修复了这一漏洞。

源端口随机化:第一道防线

针对Kaminsky攻击,DNS社区引入了源端口随机化作为主要防御措施。此前,DNS解析器通常使用固定的源端口(如53)发送查询。攻击者只需要猜测16位的事务ID。

源端口随机化将查询的源端口也变成随机值。这样,攻击者需要同时猜中16位的事务ID和16位的源端口——搜索空间从65536扩大到约40亿(实际可用端口约28000个,搜索空间约18亿)。在2008年的技术条件下,这使得攻击变得不切实际。

RFC 5452(2009年1月发布)正式规范了这些防御措施,包括事务ID随机化、源端口随机化,以及限制每个查询只接受一个响应等。

SAD DNS:侧信道攻击复活

然而,安全研究从未停止。2020年11月,加州大学河滨分校和清华大学的研究人员在ACM CCS会议上发布了SAD DNS攻击(Side-channel AttackeD DNS),证明源端口随机化可以被绕过。

SAD DNS的关键创新是利用ICMP速率限制作为侧信道。现代操作系统实现了ICMP速率限制,防止服务器被用于反射攻击。例如,Linux默认限制每秒发送50个ICMP"端口不可达"消息。

攻击原理如下:攻击者向目标解析器发送大量UDP数据包,探测哪些端口是开放的。如果端口开放,没有ICMP响应;如果端口关闭,解析器会发送ICMP"端口不可达"消息,消耗速率限制配额。通过观察ICMP速率限制是否被触发,攻击者可以推断哪些端口是开放的。

这个过程将搜索空间从约40亿缩小到几百甚至几十。攻击者可以快速定位开放端口,然后针对这些端口进行传统的事务ID爆破。

Cloudflare和其他主要DNS提供商在公开披露前就修复了这一漏洞。但SAD DNS揭示了一个重要事实:防御措施只是增加了攻击成本,而非从根本上解决问题。

MaginotDNS:边界检查的沦陷

2023年,USENIX Security会议上发表了MaginotDNS攻击,针对的是DNS安全的另一道基石:bailiwick检查

Bailiwick检查是自1990年代以来DNS安全的核心机制。它规定:DNS响应中的额外记录只有在被请求域名的"管辖范围"内才能被接受。例如,查询example.com时,响应中的额外记录只能是example.com及其子域名,不能是bank.com

MaginotDNS针对的是条件DNS解析器(CDNS)——同时充当递归解析器和转发器的服务器。这类服务器在ISP和企业网络中广泛存在(研究发现约41.8%的DNS服务器是CDNS)。问题在于,bailiwick检查在递归模式和转发模式下实现不一致,攻击者可以利用这种不一致注入越界记录。

该攻击影响了BIND(CVE-2021-25220)、Knot Resolver(CVE-2022-32983)、Microsoft DNS和Technitium(CVE-2021-43105)等主流DNS软件。更可怕的是,它甚至可以劫持顶级域名(如.com),影响范围极其广泛。

2025年的回响:CVE-2025-40778

2025年10月,ISC发布BIND 9的安全公告,CVE-2025-40778(CVSS 8.6)再次让DNS缓存投毒成为焦点。这个漏洞影响BIND 9.11.0至9.21.12多个版本,允许远程攻击者在特定条件下向缓存注入伪造的DNS记录。

漏洞的根源在于BIND对DNS响应中"非请求资源记录"的处理过于宽松。正确的实现应该严格验证这些记录是否在被请求域名的bailiwick范围内,但受影响版本接受了一些不应接受的记录。

这再次证明了一个残酷的事实:DNS缓存投毒不是单一漏洞,而是一整类攻击。每次修复都只是堵住了特定的攻击路径,而协议的根本缺陷从未解决。

DNSSEC:终极解决方案?

理论上,DNSSEC(DNS Security Extensions)是解决DNS缓存投毒的终极方案。DNSSEC使用数字签名对DNS数据进行认证:每条DNS记录都有一个关联的RRSIG签名,解析器可以验证签名确保数据未被篡改。

DNSSEC的工作原理建立在信任链上:根区域的密钥由"根签名仪式"产生和保管;每个顶级域名(如.com)由根区域签名;每个二级域名由其父域名签名。解析器可以从根开始,逐级验证信任链。

如果DNSSEC被正确部署和验证,DNS缓存投毒将变得不可能——攻击者无法伪造有效的数字签名。然而,二十年过去了,DNSSEC的部署率仍然令人失望。根据2025年的统计数据,全球只有约4.7%的域名启用了DNSSEC。

DNSSEC部署的困境

DNSSEC部署如此缓慢的原因是多方面的。

复杂性是首要障碍。部署DNSSEC需要生成和管理密钥对、定期轮换密钥、与域名注册商协调上传DS记录。对于许多组织来说,这些操作的复杂性和出错风险超过了安全收益。

密钥管理是持续负担。DNSSEC使用两种密钥:区域签名密钥(ZSK)和密钥签名密钥(KSK)。ZSK用于签署区域内的记录,需要频繁轮换;KSK用于签署ZSK,轮换涉及与父区域的协调。密钥泄露或丢失都可能导致严重后果。

响应体积增大。DNSSEC增加了大量签名记录,可能导致DNS响应超过UDP的512字节限制,触发TCP回退。这不仅增加了延迟,还可能在某些网络环境中造成兼容性问题。

验证成本。DNSSEC验证需要执行公钥密码学操作,对解析器性能有影响。对于高负载的公共解析器(如8.8.8.8),这是一个需要考虑的因素。

缺乏可见性。DNSSEC对终端用户是透明的——成功验证不会显示任何指示,失败则可能导致解析中断。用户看不到DNSSEC的好处,这降低了部署的动力。

替代方案:加密DNS

在DNSSEC部署停滞的同时,另一种方案获得了广泛采用:加密DNS传输,包括DNS over TLS(DoT)和DNS over HTTPS(DoH)。

这些协议通过加密DNS查询和响应,防止中间人篡改。虽然它们不能保证数据源的真实性(仍可能被权威服务器欺骗),但可以有效防止网络路径上的缓存投毒攻击。

然而,加密DNS也有其局限性。它只保护客户端到解析器之间的通信,不保护解析器到权威服务器之间的通信。攻击者仍然可以通过攻击解析器本身或权威服务器来实施缓存投毒。

DNS Cookies:轻量级防护

RFC 7873定义了DNS Cookies机制,作为一种轻量级的事务安全方案。客户端在查询中包含一个Cookie(64位随机值),服务器在响应中返回相应的Cookie。只有Cookie匹配的响应才会被接受。

DNS Cookies不需要密钥管理,不改变DNS协议的基本结构,实现成本低。但它只提供有限的安全保障——主要防止离路攻击者(off-path attacker),对在路攻击者(on-path attacker)无效。

Google Public DNS在2024年部署了DNS Cookies,作为多层防御的一部分。

防御建议

对于网络管理员和DNS运维人员,以下措施可以降低DNS缓存投毒的风险:

保持软件更新。BIND、Unbound、PowerDNS等DNS软件经常发布安全更新。CVE-2025-40778影响BIND 9多个长期支持版本,及时升级至关重要。

启用DNSSEC验证。如果作为递归解析器运行,启用DNSSEC验证模式。即使上游区域未签名,这也不会影响解析;对于已签名的区域,可以验证数据真实性。

配置正确的bailiwick检查。确保DNS软件正确实现了bailiwick检查,不接受越界的额外记录。

监控异常流量。DNS缓存投毒攻击通常涉及大量伪造响应。监控入站DNS流量的异常模式可以早期发现攻击。

考虑使用加密DNS。对于客户端到解析器的通信,启用DoT或DoH可以防止本地网络中的中间人攻击。

对CDNS配置保持警惕。如果服务器同时充当递归解析器和转发器,确保两种模式的安全机制一致。

持续的博弈

DNS缓存投毒的二十年历史揭示了安全领域的一个基本事实:没有完美的防御,只有不断升级的攻防博弈

Kaminsky攻击促使业界引入源端口随机化;SAD DNS证明侧信道可以绕过这一防御;MaginotDNS揭示了bailiwick检查的实现漏洞;而CVE-2025-40778说明即使是最成熟的DNS软件仍然存在实现缺陷。

DNSSEC是理论上的终极解决方案,但部署的经济激励和操作复杂性使其难以普及。在可见的未来,DNS缓存投毒很可能继续以新的形式出现。

对于依赖DNS的系统来说,最安全的假设是:DNS解析结果可能是错误的。应用层的安全验证——如TLS证书验证、端到端加密——仍然是最后的防线。当用户看到浏览器的绿色锁标志时,那才是真正可以信任的信号,而非DNS返回的IP地址。


参考文献

  1. Postel, J. “Transmission Control Protocol.” RFC 793, September 1981.
  2. Kaminsky, D. “Black Ops 2008: DNS is at the heart of every network.” DEF CON 16, 2008.
  3. Friedl, S. “An Illustrated Guide to the Kaminsky DNS Vulnerability.” Unixwiz.net, August 2008.
  4. Ateniese, G., Mangard, S. “The Hitchhiker’s Guide to DNS Cache Poisoning.” SecureComm 2010.
  5. Man, K., et al. “DNS Cache Poisoning Attack: Resurrections with Side Channels.” ACM CCS 2021.
  6. Li, X., et al. “The Maginot Line: Attacking the Boundary of DNS Caching Protection.” USENIX Security 2023.
  7. Herzberg, A., Schulman, H. “On the Feasibility of Off-Path DNS Cache Poisoning.” FC 2012.
  8. Petr, E. “An Analysis of the DNS Cache Poisoning Attack.” CZ.NIC Labs, November 2009.
  9. Internet Systems Consortium. “CVE-2025-40778: DNS Cache Poisoning Vulnerability.” October 2025.
  10. Lewis, E. “Where Did DNSSEC Go Wrong?” Internet Society Pulse, July 2024.