01 · 缓存投毒总览
DNS使用UDP、query/response 仅靠16位事务ID(Transaction ID)与(早期)固定的源端口配对。解析器收到一个"看起来匹配"的应答就采信并写入缓存。缓存投毒的核心就是:在真实权威应答到达之前,抢先发回一份伪造应答,且事务ID/端口恰好匹配。一旦成功,恶意记录进入缓存,在TTL(生存时间)内所有用户都将"被答案"误导。
为何危害被放大:传统投毒只能污染"一个具体名字"。Kaminsky的关键创新在于——伪响应不仅回答所问,还在附加段(Additional/Authority段)植入一个"通配"委托记录(如为 *.victim.com 伪造NS/A记录),从而一次性劫持整个子域空间,且污染期可长达域的TTL(常以"小时/天"计),而非单条记录。
02 · Kaminsky攻击(CVE-2008-1447)
2.1 披露与影响
2008年7月,安全研究员 Dan Kaminsky 披露了一个影响几乎所有主流DNS实现(BIND、Microsoft DNS、Cisco等)的严重缓存投毒漏洞,被分配 CVE-2008-1447。其本质不是某个产品bug,而是DNS协议"弱关联"设计的系统性缺陷——在修复(源端口随机化)普及前,一次成功投毒即可长期、全域地重定向流量。
2.2 攻击流程
2.3 为什么"随机子名"是关键
若攻击者反复查询同一个固定名字,解析器会缓存成功结果、或限速,难以持续尝试。Kaminsky的方法是不断查询随机、不存在的子域名(如 随机串.victim.com),使解析器每次都"未命中、需向外查询",从而制造大量"可投毒窗口"。由于这些子名本不存在,攻击者可在伪造的应答中"顺带"给出对父域 victim.com 的委托记录,从而接管整个域。
03 · 熵与生日悖论
投毒能否成功,取决于攻击者"猜中匹配字段"的概率。修复前与修复后的熵对比:
| 字段 | 修复前(多数实现) | 修复后(标准做法) |
|---|---|---|
| 事务ID(TXID) | 16位,但实现可能弱随机 | 16位,强随机(熵 2^16=65536) |
| 源端口 | 固定(如53或单端口) | 每查询随机(16位,熵 2^16=65536) |
| 查询名大小写 | 忽略(不校验) | 0x20随机化(RFC 5452,额外熵) |
| 单次猜中概率 | ≈ 1/65536(仅靠TXID) | ≈ 1/2^32(TXID×端口),叠加0x20更高 |
引入随机源端口后,攻击者需同时猜中16位TXID与16位端口,单次成功率降至约 1/2^32;再叠加0x20大小写随机化(RFC 5452,2009,约另增1位/字符的熵),实际攻击在统计上不可行。这正是"提高应答匹配熵"战胜缓存投毒的核心思路。
为何"生日悖论"被提及:在持续、大量查询的设定下,攻击者尝试多次,命中概率随尝试次数上升(类似生日攻击)。但2^32量级下,即使每秒数千次尝试,期望值也远超合理时间窗——这正是修复后投毒从"可行"变"不可行"的数学依据。
04 · 缓解措施
| 缓解 | 机理 | 局限性 |
|---|---|---|
| 源端口随机化 | 每查询使用随机UDP源端口,增加16位熵(Kaminsky修复的核心) | 仅提高成本,不提供密码学保证;实现不当仍可被探测 |
| 0x20大小写随机化 | RFC 5452(2009):随机化查询名大小写,响应须原样匹配,增加熵、防重放 | 部分权威对大小写处理不一致时可能致解析失败;非强制 |
| 强随机TXID | 密码学强度随机化事务ID,避免可预测序列 | 单独的TXID熵(2^16)仍不足,须配合端口随机化 |
| DNSSEC验证 | RFC 4033/4034/4035:应答带RRSIG,解析器验证签名,伪造应答被拒 | 仅对已签名域有效;依赖信任锚与正确部署 |
| 实现层加固 | 严格消息解析、限制缓存接受范围、及时打补丁(见§5) | 需厂商与运维持续跟进 |
结论性判断:源端口随机化+0x20是"提高攻击成本"的工程缓解,使经典Kaminsky式投毒在统计上不可行;DNSSEC是唯一的密码学级终结手段——对已正确签名的域,任何伪造应答都通不过签名验证。但二者互补:DNSSEC覆盖"已签名域",随机化覆盖"尚未签名域"的降级保护。
05 · 现代实现层漏洞
即便协议层缓解普及,解析器软件实现本身的缺陷仍可能 reopen 投毒窗口。典型代表:
5.1 DNSpooq(2021,JSOF)
2021年1月19日,以色列安全研究团队 JSOF(Shlomi Oberman与Moshe Kol)联合CERT/CC披露 DNSpooq:影响广泛使用的 dnsmasq(<2.83版本,常见于路由器、IoT、Android、部分Linux发行版与libvirt虚拟网络)的 7个漏洞(CVE-2020-25681至CVE-2020-25687)。其中CVE-2020-25684/25685/25686为缓存投毒类:dnsmasq在应答匹配时未按RFC 5452严格校验地址/端口组合、使用弱哈希校验查询名、对同名并发查询不查重,使投毒尝试次数大幅下降,数分钟内即可完成一次投毒;CVE-2020-25681/25682/25683/25687为DNSSEC代码中的堆缓冲区溢出,可致远程代码执行或拒绝服务。修复版本为dnsmasq 2.83。它说明:即便"协议已修复",若底层实现解析DNS消息不严谨,投毒仍可能死灰复燃。
5.2 NAME:WRECK(2021,Forescout/JSOF)
2021年4月,Forescout与JSOF披露 NAME:WRECK(Project Memoria系列):影响 FreeBSD(含基于FreeBSD的pfSense等)、Siemens Nucleus NET、Microsoft NetX、Wind River VxWorks(IPnet) 等主流TCP/IP协议栈中DNS客户端解析代码的 9个漏洞(含CVE-2020-7461、CVE-2020-25767等),源于对DNS报文压缩指针与长度字段的错误处理,可导致缓存投毒与远程代码执行。影响设备以网络设备、工控与IoT为主,凸显"协议栈内置解析器"这一常被忽视的攻击面。
5.3 SAD DNS(2020,侧信道绕过端口随机化)
2020年,加州大学 Riverside 与清华大学团队披露 SAD DNS(Side-channel AttackeD DNS,CVE-2020-25705):攻击者利用 ICMP "port unreachable" 等内核侧信道,探测递归解析器为某域名使用的源端口,从而将经典投毒所需的熵(TXID×端口)降回仅16位,使源端口随机化形同虚设。该研究获 ACM CCS 2020 最佳论文之一,直接促使 Linux 内核限制 ICMP 速率(临时缓解)。它揭示:缓解手段本身若存在侧信道,仍可能被绕过,DNSSEC仍是唯一密码学级防线。
5.4 KeyTrap 与 NSEC3 算法复杂度攻击(2024,ATHENE)
2024年2月13日,德国国家应用网络安全研究中心 ATHENE 披露 KeyTrap(CVE-2023-50387)与配套的 NSEC3 漏洞(CVE-2023-50868):利用DNSSEC规范要求"尝试所有DNSKEY×RRSIG组合"与NSEC3哈希迭代的设计缺陷,攻击者仅需单个精心构造的DNS应答,即可使启用DNSSEC验证的解析器(BIND、Unbound、PowerDNS、dnsmasq、Windows Server DNS等全部主流实现)CPU耗尽、停滞数分钟乃至16小时——厂商称其为"DNS史上最严重的攻击"。该漏洞不影响数据机密性与完整性,而是直接威胁DNSSEC验证解析器的可用性,所有主流厂商已于2024年2-6月发布补丁。
检测/防护要点:①及时跟踪CVE并升级解析器软件(BIND/Unbound/Knot/dnsmasq等,含KeyTrap/NSEC3补丁);②在支持DNSSEC的解析器上默认开启验证;③对关键域名启用固定/钉住(pinning)与被动DNS基线比对,识别实现层投毒造成的异常解析;④对启用DNSSEC验证的解析器监控CPU异常飙升(KeyTrap特征),并配置验证失败次数上限。
06 · 检测缓存投毒
- DNSSEC验证:对已签名域,验证RRSIG;若解析器报告"BOGUS"则判定投毒/篡改(见第4页检测体系)。
- 权威回源比对:定期直接查询权威,与递归缓存返回比对,差异即异常。
- 被动DNS基线:比对历史解析(Farsight DNSDB、SecurityTrails等),突发IP变更且无合理变更记录即告警。
- TTL异常:投毒记录常带异常TTL(攻击者设定的较短/特殊值),与正常TTL分布偏离可辅助识别。
- 多解析器交叉:同一域名从≥3个独立解析器取结果,若仅某一个返回异常IP,且非CDN差异,则指向该解析器缓存被污染。
# 直接回源比对示例:查询权威返回的A记录 $ dig +short A victim.com @a.gtld-servers.net # 问根/TLD权威 $ dig +short A victim.com @ns1.victim.com # 问该域权威 # 再与日常递归解析结果比对,差异即需核实 $ dig +short A victim.com @8.8.8.8 # 公共DNS递归 $ dig +short A victim.com @1.1.1.1 # 另一公共DNS递归
示例仅用于说明"回源比对"方法,命令输出因网络与配置而异。
本节参考来源(第3页)
CVE-2008-1447 / US-CERT Vulnerability Note VU#800113(Kaminsky DNS缓存投毒):kb.cert.org/vuls/id/800113
RFC 5452, "Measures for Making DNS More Resilient against Forged Answers" (0x20编码, 2009):RFC 5452
RFC 4033/4034/4035(DNSSEC):RFC 4033/4034/4035
JSOF, "DNSpooq" 披露与技术白皮书(2021-01,dnsmasq CVE-2020-25681~25687):jsof-tech.com/disclosures/dnspooq;CERT/CC VU#434904
Forescout/JSOF, "NAME:WRECK" 技术报告(2021-04,CVE-2020-7461、CVE-2020-25767等):forescout.com/company/resources/namewreck
Internet Systems Consortium (ISC), BIND 安全公告(含 CVE-2023-50387/50868 修复):kb.isc.org/docs/cve-2023-50387
Man, et al., "DNS Cache Poisoning Attack: Resurrected with Side Channels"(SAD DNS,ACM CCS 2020,CVE-2020-25705):nvd.nist.gov/vuln/detail/CVE-2020-25705
ATHENE, "KeyTrap: Denial-of-Service Algorithmic Complexity Attacks on DNSSEC"(2024-02,CVE-2023-50387 / CVE-2023-50868):athene-center.de/en/keytrap