kaminsky复现报告

一、摘要

本报告旨在记录并分析经典的 Kaminsky DNS 缓存投毒攻击的复现过程。我们通过 Docker 构建了一个包含易受攻击的递归DNS服务器、攻击者和合法权威服务器的隔离网络环境。实验中,攻击者通过向递归服务器查询一系列不存在的随机子域名,并抢在合法响应前发送大量伪造的DNS响应包,成功地在其缓存中植入了恶意的 NS 记录。实验结果表明,攻击成功后,所有对目标域名的查询均被重定向至攻击者指定的服务器,直观地验证了 Kaminsky 攻击的巨大危害性。

二、原理分析

Kaminsky 攻击的核心并非直接猜测并伪造目标域名(如www.example.com)的 A 记录,而是通过污染其父域(example.com)的权威 NS 记录来获得整个域的解析控制权。其攻击逻辑如下:

  1. 攻击者向受害者递归服务器(10.10.0.6)查询一个随机且不存在的子域名,例如 random-string.example.com。由于缓存中没有该记录,递归服务器必须向外查询。
  2. 递归服务器会向其配置的根/权威服务器(本例中为被攻击者控制的10.10.0.8)发起请求。攻击者通过让10.10.0.8上的服务延迟响应,为自己创造了一个宝贵的“竞争窗口期”。
  3. 在此窗口期内,攻击者向递归服务器发送海量伪造的DNS响应包。这些包不仅回答了对random-string.example.com的查询,更关键的是,在响应的Additional Section中,包含了恶意的胶水记录:ns-auth.example.com. IN A 10.10.0.7
  4. 一旦某个伪造包的 Transaction ID 与递归服务器发出的查询匹配,递归服务器便会接受这个伪造响应,并将附加区段中的恶意 NS 记录存入缓存。至此,投毒成功。

三、实验复现

1. 实验环境

我们使用 docker-compose 搭建了包含三个核心服务的网络环境:

服务 IP地址 角色 作用
recursor 10.10.0.6 受害者递归服务器 配置了一个错误的根服务器地址 (10.10.0.8),模拟易受攻击状态。
attacker 10.10.0.8 攻击者(恶意权威服务器) 运行攻击脚本,并使用echo服务伪装成一个响应缓慢的根服务器。
auth 10.10.0.7 重定向权威服务器 攻击的目标是将对 example.com 的查询重定向到此服务器。

2. 实验思路

  1. 首先验证 recursor 无法解析 www.example.com,因为其根指向 attacker 且无响应,导致查询超时。这为后续验证攻击效果提供了对比。
  2. attacker 上启动 echo.py 脚本,模拟一个有 0.5 秒延迟的 DNS 服务器,以确保有足够的“竞争窗口”供攻击脚本注入伪造包。
  3. 运行 attack.py 脚本,指定受害者(10.10.0.6)和投毒目标(example.com 的 NS 记录指向 10.10.0.7),脚本自动循环执行攻击逻辑。
  4. 攻击成功后,再次向 recursor 查询 www.example.com。观察 dig 命令的返回结果,确认 ANSWER SECTION 中有正确的 A 记录,且 ADDITIONAL SECTIONns-auth.example.com 的 IP 地址已被成功篡改为 10.10.0.7

3. 遇到的困难与挑战

  • 竞争: 攻击的成功率与竞争窗口的大小直接相关。如果权威服务器响应过快,或网络延迟过高,都可能导致攻击失败。本实验通过 echo.py 人为制造延迟,简化了这一挑战。

四、新版本

  • BIND(9.16.45),依旧存在可固定源端口属性,但是加入了一些奇怪的优化,例如有时自动询问根服务器一些信息、不定的重试机制

    recursor-1  | 04-Aug-2025 06:41:09.426 DNS format error from 10.10.0.8#53 resolving _.example.com/A for <unknown>: question section mismatch: got ieaose7c1x.example.com/IN/A
    recursor-1 | 04-Aug-2025 06:41:10.288 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:41:10.600 DNS format error from 10.10.0.8#53 resolving ./NS for <unknown>: question section mismatch: got ieaose7c1x.example.com/IN/A
    recursor-1 | 04-Aug-2025 06:41:20.417 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:41:32.651 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:41:42.651 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:41:57.740 DNS format error from 10.10.0.8#53 resolving A.ROOT-SERVERS.NET/AAAA for <unknown>: question section mismatch: got xz3rbl7403.example.com/IN/A
    recursor-1 | 04-Aug-2025 06:42:02.357 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:42:13.403 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:42:28.290 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:42:38.290 resolver priming query complete
    recursor-1 | 04-Aug-2025 06:42:52.856 DNS format error from 10.10.0.8#53 resolving ./NS for <unknown>: question section mismatch: got rnzpcp03c5.example.com/IN/A
    recursor-1 | 04-Aug-2025 06:42:55.981 resolver priming query complete
  • Unbound(1.19.0),没有好的方式固定源端口属性,暴力猜解效率低下(存在小规律,端口只使用5位数,3、4、5开头最多,1、6很少、2几乎没有)

  • Knot(2.3.0)、PowerDNS(4.9.1),也没有好的固定源端口属性,端口随机化更加明显

五、结论

本实验成功地复现了 Kaminsky DNS 缓存投毒攻击,证明了在特定条件下,攻击者可以篡改递归服务器的 NS 记录缓存,从而劫持整个域名的流量。

为了防御此类攻击,现代 DNS 系统已广泛部署了以下补丁/缓解措施

  • 源端口随机化: 这是最有效和最普遍的防御手段。DNS 解析器在发出查询时使用随机的源端口,而不是固定的端口。这使得攻击者需要猜测 Transaction ID(16位)和源端口(约15位)两个变量,攻击难度呈指数级增加
  • DNSSEC: 通过为 DNS 记录提供数字签名,DNSSEC 允许解析器验证响应的真实性和完整性,从根本上杜绝了伪造和篡改的可能