远程 DNS 缓存投毒攻击

站点: SEED 实验
课程: DNS 攻击实验 - 远程攻击
图书: 远程 DNS 缓存投毒攻击
打印: Guest user
日期: 2025年10月7日 星期二 09:07

1. 远程攻击的挑战

本地 DNS 攻击有一定的局限性,即为了嗅探受害者的 DNS 请求,攻击 者的机器和受害者的机器必须在同一局域网上。这给远程黑客造成了障碍,因为远程黑客嗅探不到 DNS 请求。DNS 请求里面有两个数据远程黑客很难获得。第一个是 UDP 头部中的源端口号,DNS 请求是 UDP 包,其源端口号是一个 16 位的随机数字。第二 个是 DNS 头部的一个 16 位的交易 ID。欺骗回复必须包含这两个值,否则,回复不会被接受。因为不能嗅探,攻击者只能猜测这两个数字,猜到的几率是 232 分之一。如 果黑客可以在 1 秒内发送 1000 个欺骗请求,需要 50 天才能尝试 232 次。如果黑客用 有 1000 个主机的僵尸网络发起攻击,则只需要 1.2 小时。

上述假想的攻击忽视了缓存的影响,因为我们需要猜测交易 ID 和源端口号,一次性成功几乎是不可能的。如果我们失败了,真实的请求会到达本地 DNS 服务器,并且被缓存。为了尝试下一次攻击,我们需要等待服务器发起第二次 DNS 请求。但是不幸的是,因为本地 DNS 服务器可以从缓存中得到 IP 地址,它就不会对同一主机名发出请求,除非缓存内的记录过期。缓存的这个特点让攻击者在尝试第二次攻击之前需要等待,等待的时间可能是几小时或者几天。这使得远程 DNS 缓存中毒攻击变得非常不现实。

2. Kaminsky 攻击

为了从远程机器发起有效的 DNS 攻击,我们需要完成三个任务:(1) 触发目标 DNS 服务器(让我们称之为Apollo)发送 DNS 请求,(2) 发送欺骗回复,(3) 使缓存效果无效。前面两个任务很简单,攻击者只需发送 DNS 请求给目标 DNS 服务器,这会触发服务器发送 DNS 请求,攻击者就可以发起欺骗回复攻击。最难的是第三个任务。如果不能使缓存效果无效,攻击者就不能持续不断地发动攻击。这一直是一个悬而未解的问题,直到 Dan Kaminsky 提出了一个很巧妙的解决方案。通过他的方案,攻击者可以持续地发起欺骗攻击,而不需要等待。为了帮助理解 Kaminsky 攻击的工作原理,我们假定 www.example.com 是我们的目标主机名,攻击的目的是为这个主机名提供虚假的 IP 地址。

为了防止目标 DNS 缓存 www.example.com 的IP地址,我们不应该触发 Apollo 发送对这个主机名的请求,否则,如果我们的欺骗回复失败了,在一段时间内就不能尝试下一次了。但是我们必须要触发Apollo 发送请求,否则我们连发欺骗回复的机会都没有。那么触发 Apollo 发送我们不想要的请求(不发送目标主机名)的目的到底是什么?这是 Kaminsky 攻击的奇妙所在。我们先提示一下读者,在 DNS 回复里,除了给出 IP 地址外,还可以有其他部分,这些部分如果是合法的话,也会被缓存。因此,即使我们不触发 Apollo 发送正确的请求,如果我们的欺骗回复被接受,我们仍然能使服务器缓存我们给出的信息。我们要解决以下的问题: 如果我们不触发 DNS 服务器 Apollo 发送对 www.example.com 的查询请求,那么我们需要触发什么请求?我们应该在伪造回复里面放入什么,以至于如果我们的回复被接受,我们可以影响对 www.example.com的 DNS 解析?
 
首先回答上述问题中的第二部分:即我们在回应中应该放入什么内容?既然我们不能提出正确的查询,就不得不将目光从答案部分转移开。让我们来看看权威部分。该部分的目的在于提供域名的服务器信息。如果我们可以利用这一字段告诉 Apollo,example.com 域的名称服务器是我们的机器  ns.attacker32.com。一旦这些信息被 Apollo 缓存后,当它需要解析该域中的任何主机名时,会把查询发送到我们的机器上,提供什么样的回复就完全由我们说了算了。

现在,我们来回答第一个问题,我们应该触发 Apollo 发送什么请求?首先为了使权威部分的信息被接受,这个部分的域名应该和查询的问题有关,因此这个查询需要是针对 example.com 域内的某个主机名。其次,为了触发 Apollo 不停的发送请求(好让我们可以不停地伪造回复),我们需要让 Apollo 不停的询问不同的问题,让从合法 DNS 服务器得到的信息即使被缓存,也不影响我们的攻击。

我们了解了 Kaminsky 攻击的原理,让我们来看看这个攻击到底是如何工作的。下图描述了攻击的步骤 (假设 Apollo 已经知道 example.com 的权威域名服务器)。
 
DNS_Remote_with_font_chinese
 
  1. 攻击者向 DNS 服务器 Apollo 询问一个位于 example.com 域内的主机名,名字可以随机产生,例如twysw.example.com。 
  2. 因为答案不在 Apollo 的 DNS 缓存中,Apollo 需要发送 DNS 请求给 example.com 的域名服务器。刚开始 Apollo 可能不知道  example.com 的域名服务器在哪,所以它会通过根和  com 服务器得到  example.com 的域名服务器信息,并把信息储存到缓存中。
  3. 当 Apollo 等待回复的时候,攻击者向 Apollo 发送一连串的伪造的 DNS 回复,每个 DNS 回复都尝试不同的交易 ID 和 UDP 目的端口号,希望其中的一个回复是正确的。在回复包中,攻击者不但提供 twysw.example.com 的 IP 地址,还提供了一个 NS 记录,标明  ns.attacker32.com 是  example.com 的域名服务器。如果其中一个伪造的回复恰好有正确的交易 ID 和 UDP 端口号,而且它比正确的回复更早到达 Apollo,它就会被接受和缓存,从而污染了 Apollo 的 DNS 缓存。下面是一个样本响应。
    ;; QUESTION SECTION:
    ;twysw.example.com.           IN   A
    
    ;; ANSWER SECTION:
    twysw.example.com.    259200  IN   A   1.2.3.4
    
    ;; AUTHORITY SECTION:
    example.com.          259200  IN   NS  ns.attacker32.com
    
  4. 如果伪造的 DNS 回复失败了,攻击者会返回到第一步,重新开始整个攻击过程,但是在请求中会用一个不同的主机名(这就是在第一步主机名是随机产生的原因)。因为 Apollo 的缓存没有新主机名的 IP 地址,它会发出一个新的请求,这就给攻击者创造了又一个提供回复的机会。缓存已经不再是问题了,攻击者可以不停地进行攻击,而不需要等待缓存过期。  
  5. 如果攻击成功,在 Apollo 的 DNS 缓存中,example.com 的域名服务器会被替换成攻击者的域名服务器 ns.attacker32.com。