所谓DNS,是一套将人类可读的域名转化为计算机可识别IP地址的命名系统。每当一条尚不存在于解析器缓存中的域名查询请求出现,这一转化过程就会在从根服务器到顶级域名(例如.com型域名)的整个DNS层级体系中走上一遍。接下来顶级域名(简称TLD)会把能够向我们提供所需IP地址的已授权域名服务器找到,并将相关信息提交回来。在我们从域名服务器获取到对应的域名信息之后,结果将带着一个特定的TTL值(即有效时间值)进入DNS解析程序缓存,最终在有效期结束时被清出。
有些时候,某个域会被认定为恶意对象并遭到清除。出现这种情况的原因可谓多种多样,例如恶意软件传播、钓鱼感染等。一般来说,防止用户对某个域发起访问的常见方式是将该域从TLD服务器中删除。然而这还不足以彻底消除安全隐患,因为域仍然能够再次由解析程序解析,并在下一次TTL过期之前始终处于可用状态。通常情况下这算不得什么大问题,因为TTL值生效时间本身就很短,所以攻击型域的存在时间可能只有数秒或者数分钟。
在本文中,我们将讨论近来存在于大多数DNS服务器中的DNS漏洞。此漏洞是由江坚、梁津津、李康、李军、段海心以及吴建平等多位研究人员共同发现的。点击此处可以查看他们的研究论文。
该漏洞的突破口在于某些DNS服务器中的缓存更新逻辑缺口。此漏洞允许缓存以特定方式被改写,进而导致某个特定域将在缓存中拥有源源不断的TTL授权数据,且TTL值不受有效时间所限。这样一来,即使该域被从TLD服务器中清出,也仍然会一直处于可解析状态。此种类型的域如今有了自己的名号:幽灵域名(即Ghost Domain Name)。
DNS基础知识
首先,让我们先来了解DNS解析工作是如何进行的。
比如说,用户打开浏览器并在地址栏中输入infosecinstitute.com内容。这时用户操作系统中的DNS解析程序就会运作起来,尝试为该域名找出对应的IP地址。解析程序首先会检查本地缓存,以确认该查询域名是否在缓存中存在记录。缓存中通常保存着最近一段时间内用户使用过的IP地址与主机名称映射,这样解析程序就不必重复再重复地为同一个域名多次获取IP地址。如果解析程序在缓存中无法找到对应的IP地址,那么接下来它就要向DNS服务器发送请求,检查是否存在该域名的记录。DNS服务器通常由我们的网络服务供应商(简称ISP)提供,当然大家也可以为自己进行手动选择。如果此时仍然查找不到记录,解析程序就会向不同的域名服务器发送循环DNS查询,以期找到所查域名。当IP地址被寻获时,解析程序会在将地址发回用户端的同时保存在缓存中,以方便今后的使用。
#p# 深入了解DNS查询
理解DNS查询的工作原理非常重要。要完成查询,我们需要由根服务器出发、直到顶级域名为止,行遍整个DNS层级体系。打开Backtrack终端(大家也可以使用自己喜欢的其它发行版)并输入“dig”。屏幕上的显示结果如下所示:
我们得到的是一套根DNS服务器列表,下面我们就用根DNS服务器查询infosecinstitute.com域名。具体操作方法如下图所示:
这里我们获得的是一套用于.com域验证的域名服务器列表。请注意点(.)被放在com后方。这就使我们的查询内容成为一个正式域名(简称FQDN)。接着我们利用这些域名服务器再进行一次查询。
现在我们得到了infosecinstitute.com的验证域名服务器列表(即上图中的ns1.pairnic.com以及ns2.pairnic.com)。下面我们对这些域名服务器发起查询,以获取infosecinstitute.com的IP地址。
#p# 现在在应答部分我们能够看到infosecinstitute.com的IP地址为216.92.251.5。任务完成!
通过我们自定义的DNS服务器进行查询并获取不同记录也是可行的。在下图中,我们将使用DIG命令向谷歌的DNS服务器(8.8.8.8)发起查询,以搜索infosecinstitute.com的地址记录。
基本上是指提供给DNS查询的特定记录的有效时间。如果我们再次重复以上查询过程,可以看到现在TTL的有效时间已经减少至3503。
当某个域被认定为恶意的情况下,它从全局域名空间中被清除掉的过程基本上分为两个步骤。首先是从TLD服务器中清除对应记录,接下来是等待其TTL在所有DNS服务器中的有效时间耗尽。
要确定某个域名的IP地址,需要了解的一大重点是该域的授权数据。授权数据中包含了域的NS记录及其对应的A记录,也就是域名服务器的IP地址。授权数据同样拥有一条特定TTL,可以告诉我们授权数据将于何时进入缓存。在下图中,我会向TLD服务器发送.com查询,以获取一条并不存在的子域地址。反馈回来的信息包含验证部分以及附加部分,内容则涵盖了指定域的NS记录以及对应域名服务器的IP地址(即A记录)。
让我们来看看这个实例。我将在自己的网站中创建一个名为infosec.seraching-eye.com的子域。
完成之后,让我们使用特定开放式DNS服务器8.8.8.8(即OpenDNS)来查询这个新域。
#p# 我们仍然可以在应答部分看到响应结果。同样,我们可以看到其中包含一个特定的TTL值:14399。授权数据现在已经进入该服务器的缓存,因此我们再接再厉,清除刚刚建立的子域。
正如大家所见,子域inforsec.searching-eye.com已经被成功删除。现在让我们再进一步,再向同样的DNS服务器发起针对子域inforsec.searching-eye.com的查询指令。
令人惊讶的是,我们仍然收到了响应。
这是因为目前谷歌的DNS服务器缓存中仍然保留着查询记录。正如我们所见,TTL有效时间已经缩短至12790。至于响应存在的原因,相信大家也能够推断出来:由于我们在子域存在的时候曾经向该DNS服务器发出过查询指令,因此相应授权数据就一直存在于该服务器的缓存中。
现在,我们要向自己的默认DNS服务器发起同样的子域查询指令。
根据上图所示,我们没有得到响应。这是因为由于我们的默认DNS服务器中并不具备相应缓存记录,所以服务器将遍历整个DNS层次结构,希望找到我们所查询子域的IP地址。而一旦遍历过程到达顶级域名(即.com)处,服务器会发现此记录并不存在,最终也就不会返回任何结果。
#p# 漏洞
此漏洞由特定DNS服务器中的DNS缓存更新策略所引发。正如前文中所讨论,某个域可以通过从TLD中删除并耗尽全部DNS服务器中授权数据有效时间的方式从全局域名空间中彻底被清除。但只要能够延长授权数据的TTL,例如使其永远不归零,那么这个域将始终处于可解析状态。
请注意,并不是所有DNS服务器都存在此类漏洞。不过根据论文的阐述,此漏洞在大多数DNS服务器中都能轻松找到,因为这些服务器并没有严格执行缓存更新的逻辑要求。
第一步是注册一个域名服务器。一般来说这种服务可以由我们的域名服务供应商提供。我希望自己的域名服务器采用xyz.mydomain.com的形式,而非xyz.hostingcompany.com的形式。请注意,我们提供的IP地址必须是一个有效的域名服务器IP。
一旦域名服务器注册完成,我们就要按照下图所示将其设置为自己的域名服务器。
根据下图所示,我们已经可以确定testns.searching-eye.com彻底设置完成。这套新的域名服务器可以用来查询那些并不存在的子域。
接下来我们创建另一个名为ghost.searching-eye.com的子域。
这一步工作完成后,我们选取某个特定DNS服务器(当然要选那些存在漏洞的)并通过它查询这个子域。
#p# 现在我们可以确定授权数据已然进入DNS服务器的缓存当中。乘胜追击,删除新建的子域。目前授权数据的TTL应该还存在,但处于不断减少之中。因为我们知道授权数据包含着域的NS记录以及域名服务器的A记录,因此它可以表示如下:
在子域被删除一段时间之后,授权数据可能如下图所示:
下一步是改变域名服务器的名称,比如改成test2.searching-eye.com。使用与之前同样的DNS服务器(4.2.2.4),我们向其查询域名服务器的A记录,即test2.searching-eye.com。
解析程序将观察授权数据并向testns.searching-eye.com的IP地址发送查询指令,但此时该IP地址已经被test2.searching-eye.com所占用。接着解析程序会返回域名服务器的IP地址,但它也将同时发现存在一个新的域名服务器(因为服务器名称已经经过改动),最终结果是它会用新服务器覆盖掉原有的缓存内容(不同的DNS服务器可能使用不同的缓存更新逻辑机制)。在缓存内容被覆盖之后,授权数据将如下图所示(前提是DNS服务器并没有严格遵循缓存更新逻辑,也就是说本文所讨论的漏洞在该服务器中确实存在):
请注意,新的授权数据被赋予了新的TTL值。如果多次重复上述过程,那么就能够避免该TTL归零(当然有某些特殊情况下,该值在很长一段时间后仍然会归零,详细情况请阅读文章结尾提供的论文链接)。
为了让这种攻击模式大范围起效,攻击者必须向尽可能多的漏洞DNS服务器发送查询指令,旨在尽量避免授权数据的TTL有效时间耗尽。由于众多DNS服务器的缓存中仍然保留着授权数据,因此攻击者就能够让自己的恶意域始终有IP地址可用,进而使更多用户顺利访问进来。
#p# 如何检测幽灵域名
幽灵域名是指那些已经被从TLD服务器中删除,但却仍然可被DNS服务器所解析的域。其出现的原因分以下两种:
对应域授权数据的TTL值尚未耗尽。请注意,如果对象域的TTL不会被刷新,那么则不应将其视为幽灵域名。
授权数据的TTL值利用DNS服务器漏洞进行不断刷新。
下面是一些颇具指导意义的办法,以帮助大家揪出幽灵域名。
在域中通过遍历DNS分层结构的方式执行DNS查询,即本文中“DNS查询”章节中的内容。
利用特定DNS服务器对某个域的A记录发起查询。
如果DNS查询步骤无法给出回应,但却能通过使用特定DNS服务器得到查询结果,那么目标域很可能属于幽灵域。我们无法确定得出确切结论,因为很可能这种现象是由于授权数据的TTL尚未耗尽所造成(当然也不排除其中存在TTL重置活动)。所以,目前最大的难题就是界定哪些属于幽灵域而哪些不是。
以下步骤可能具有一定辅助作用:
记录目录授权数据的TTL值。
等待域TTL值剩余时间耗尽,并再次发起查询。如果该DNS服务器仍然能够解析目标域,那么我们可以肯定该域为幽灵域。
综述
在这篇文章中,我们就论文中公布的漏洞展开讨论。归纳来说,就是通过非法更新DNS服务器缓存的方式,人为刷新特定域授权数据的TTL值。这意味着该域在被从TLD服务器中清除后,仍然可以长期处于可解析状态。其后我们又讨论了一些方法,用于界定某个特定域是否属于幽灵域。
参考文献
1.幽灵域名:被消除后仍可解析
https://www.isc.org/files/imce/ghostdomain_camera.pdf
2.DNS攻击(从入门到精通)
http://resources.infosecinstitute.com/dns-hacking/
原文链接:
http://resources.infosecinstitute.com/ghost-domain-names/