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 SECTION 中 ns-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 允许解析器验证响应的真实性和完整性,从根本上杜绝了伪造和篡改的可能