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