前言
为了寻找新的有趣的域名解析系统漏洞,我决定查看各种各样的顶级域名,并分析它们的错误配置,经过一些初步的搜索,我发现有一个很好的开源服务工具,可以帮助DNS管理员扫描它们的域名系统,察看是否存在错误配置,这就是瑞典互联网基金会开发的DNScheck工具,该工具会高亮显示出各种各样的奇怪DNS配置错误,这种错误例如:有一个权威名称服务器列表,一个域名的权威名称服务器和该名称服务器在上一级顶级名称服务器的设置之间不配置(引起这种问题的原因在“通过劫持DNS解析服务器攻击目标”这篇文章中可以看到)。尽管这些域名有配置错误,但是它并没有明确指出漏洞在哪里,不过它可以让我们知道:如果发现有些配置是错误的,那么研究这些错误配置,将是研究工作的一个不错的开始。
截止写这篇文章时,有1519个顶级域名。我并没有手动的逐个扫描每一个顶级域名,我选择写一个脚本来自动扫描所有顶级域名。我已将这个脚本的扫描结果放在了Github上,名称是“TLD
Health
Report”。该脚本可以高亮显示出有严重配置错误的顶级域名。在花了一两个小时对顶级域名配置错误进行检查后,我在“.gt”顶级域名上发现了一个有趣的问题,该错误可以从Github的页面看到,下面是一部分:
正如上面我们看到的,maestro.gt域名存在多个错误或警告状态,有无法路由错误,并且是“.gt”顶级域名的一个无效的主名称服务器(MNAME)。我们可以通过执行下面的dig命令,来看一下这个配置:
如上所示,我们对随机的一个“.gt”域名进行dig后得到了一个NXDOMAIN错误(因为我们请求的域名不存在,可以被注册),而且与此同时,我们得到了一个起始授权机构(SOA)的记录,maestro.gt域名作为了主名称服务器。因此任何“.gt”顶级域名下,不存在的域名发送的请求,在返回的SOA记录中的域名都是maestro.gt(SOA记录)。
“无法解决的”另一个说法是“还没有解决”
如果你读过我之前写的关于DNS漏洞的一篇文章,你就有可能已经猜到了为什么这些域名问题还没有被解决。那是因为这些域名不存在(可以被别人注册并使用)!事实证明,maestro.gt域名也是开放注册的。在进行了一些搜索和Google翻译后,我发现在“Registro
de Dominios .gt.”上可以注册该域名,每年大约需要60美元(至少需要注册两年)。
你相信它使用Visa卡吗?
虽然价格昂贵,但是和美国中部的许多其他顶级域名注册相比,它的注册过程很快,并且完全自动化。唯一的缺陷是我的借记卡因为可疑活动被立即冻结了,我不得不去网上解冻它,使订单可以通过:
很显然,上午1:30买了一个危地马拉域名是卡片被冻结的理由(成功注册了这个域名)。
发现可能存在的问题
由于起始授权机构的主名称服务器(SOA MNAME)是DNS的一个复杂特性,我无法预测DNS流量中有什么。因此我配置了我的“Bind
DNS”服务器(使用了刚才成功注册的域名),并发送查询,来请求“.gt”下所有域名的A记录,并根据我的IP地址,来过滤出所有数据包。我设置了tcpdump,将所有DNS流量打包成一个pcap文件,便于后面的分析。
我在早晨发现的东西是我远远没有预料到的,当我检查pcap数据时,我发现来自危地马拉各地的计算机向我的服务器发送了DNS查询请求。
世界上正在发生什么呢?进一步观察结果只会产生更多的混乱:
大部分DNS UPDATE请求流量来自于内部IP地址。上面是一个DNS UPDATE请求的例子,正在尝试更新我DNS服务器的区域,目的是为了更新一个SRV记录,包含一个LDAP服务器,它属于危地马拉的一个随机的政府网络。
WINDOWS活动目录域
为了理解我们得到的这个流量是什么,我们需要快速了解一下什么是Windows活动目录(AD)域和动态DNS(DDNS)。Windows域的结构与互联网域名的结构大致相同。创建一个Windows域时,你必须指定一个DNS后缀,这个DNS后缀可以看作是一个基域(父域),在这个父域下,所有子域或机器的简单主机名都包含这个子域名。例如,我们有一个thehackerblog.com域,在这个父域下,有两个活动目录网络:east和west。在thehackerblog.com父域下,我们可以设置两个子域:east.thehackerblog.com和west.thehackerblog.com。如果我们有一个专门的WEB服务器来放置east部门的所有文档,它的主机名就有可能类似于documentation.east.thehackerblog.com。我们为该网络建立了一个域树,如下示例:
类似于documentation.east.thehackerblog.com的主机名允许计算机和人们在这个网络中轻松地找到对方。该网络的DNS服务器会将这个人类可读的主机名转换成该机器指定的IP地址,这样你的计算机才会知道去哪请求你寻找的信息。因此,当你在浏览器键入documentation.east.thehackerblog.com这个内部的网站URL时,你的计算机首先会向该网络的DNS服务器发出请求,目的是为了获得这个主机名对应的IP地址,从而找到这个主机并将流量路由过去。
根据这种结构,产生了一个问题,在这个网络中,由于机器的IP地址会经常改变,当documentation.east.thehackerblog.com的IP突然改变后,会发生什么呢?网络中的DNS服务器如何才能知道该机器的新IP地址呢?
WINDOWS动态DNS(DDNS)
Windows活动目录网络通过动态更新机制来解决这个问题,动态更新的核心其实很简单。为了将documentation.east.thehackerblog.com的记录保持为正确的和最新的,该服务器会偶尔访问网络的DNS服务器,并更新它的DNS记录,例如,如果documentation.east.thehackerblog.com的IP地址突然改变了,该服务器会访问域的DNS服务器,并告诉它:“嗨,我的IP改变了,请将documentation.east.thehackerblog.com的IP记录更新为我的新IP,以便于人们知道我在哪”。这就好比一个真实世界的人在搬家后,它可以通过邮件,将新的地址通知给它的朋友、工作场所、及在线商店。
这个技术的关键点总结如下(这是从“理解动态更新”中引用的):
1.DNS客户端使用该计算机的DNS域名发送一个SOA类型的查询。
2.该客户端计算机使用它当前配置的完全合格域名(FQDN)(如newhost.tailspintoys.com),作为这个查询的指定名称。
对于标准的主要区域,在SOA查询响应中返回的主服务器或拥有者是固定的和静态的。主服务器名称始终与准确的DNS名称相匹配,因为该名称会存储在区域中,并显示在SOA资源记录中。然而,如果正在更新的区域是目录集成区域,则任何加载此区域的DNS服务器都可以响应此SOA查询,并在SOA查询响应中动态插入它自己的名称作为此区域的主服务器。
3.DNS客户端服务会尝试联系主DNS服务器。
客户端会对它名称的SOA查询响应进行处理,以确定这个IP所在的、接受它名称的、作为主服务器的DNS服务器是被授权的。然后,它将根据需要执行下列步骤,以联系并动态更新主服务器。
(1)客户端向SOA查询响应中确定的主服务器发送一个动态更新请求。
如果更新成功,则不执行其他操作。
(2)如果更新失败,接下来,客户端针对SOA记录中指定的区域名称,发送一个NS类型的请求。
(3)当客户端收到此查询的响应时,向收到的响应列表中的第一个DNS服务器发送一个SOA查询。
(4)解析此SOA查询后,客户端向SOA解析出的服务器发送一个动态更新。
如果成功,则不执行其他操作。
(5)如果更新失败,根据第(2)步中查询响应的服务器列表,客户端继续下一个SOA查询过程。
4.联系到可以执行更新的主服务器后,客户端将发送更新请求,随后服务器将处理该请求。
更新请求的内容包括指示添加“newhost.tailspintoys.com”的 A(以及可能的PTR)资源记录,并删除“oldhost.tailspintoys.com”的这些相同类型的记录,因为该名称先前已经注册过。
服务器还将进行检查,以确保允许根据客户端请求进行更新。对于标准主要区域,动态更新并不安全,因为任何客户端的更新尝试都会成功。对于活动目录集成区域,更新是安全的,并且使用基于目录的安全设置执行更新。
上面的过程是比较啰嗦的,主要过程可以精简一些,因此我将上面步骤的重要部分加粗了,并将上面步骤中客户端最重要的工作总结如下:
1.机器使用当前完整的主机名,向网络中的DNS服务器发送一个SOA查询。我拿刚才的例子来说明,它会包含documentation.east.thehackerblog.com作为主机名。
2.网络中的DNS服务器收到这个查询后,会返回它自己的一个SOA记录,内容是指定的主名称服务器的主机名,例如,这可能类似于ns1.thehackerblog.com。
3.然后,客户端解析这个SOA记录,并访问解析出的ns1.thehackerblog.com主服务器,并发送它想要做的DNS更新/修改。
4.ns1.thehackerblog.com DNS服务器收到这个更新后,将documentation.east.thehackerblog.com的IP修改为新的IP。好了,一切路线再次正常了!
Windows域命名约定&最佳实践指南
在我们理解危地马拉DNS异常前,我们需要了解的最后一段信息是Windows域的要求:
“默认情况下,DNS客户端不会尝试动态更新顶级域名(TLD)区域,任何使用单标签命名的区域都会被认为是一个TLD区域,例如,com、edu、blank、my-company。为了允许DNS客户端能动态更新TLD区域,你可以使用更新顶级域名区域策略设置,或者你可以修改注册表”
因此,默认情况下,你不能有类似于companydomain的一个Windows域,因为它是单标签的,会被Windows认为是一个顶级域名,如.com,.net,或.gt。而这个设置可以(有希望的)在每个单独的DNS客户端被禁用,这很容易,仅需要companydomain.com一个域。虽然不是所有的公司都遵循这个说明,但还是在强烈建议,因为使用单标签域名时,如果你内部网络域名的末端被注册为互联网顶级域名的DNS根区域,就有可能引起很多冲突(一个著名的问题是名称碰撞,这是一个热门的网络讨论话题,并且还会继续)。
把它们全放在一起----成为你域名的主人
现在我们有了所有信息,情况变得更加明朗了,危地马拉国家有很多Windows网络,在这些网络中有内部的Windows域,它们采用了“.gt”顶级域名的子域名。例如,如果微软在危地马拉有一个部门,他们的内部网络域名有可能类似于microsoftinternal.com.gt,这个机器会周期性的向它网络中的DNS服务器发送动态DNS更新,以确保它网络中的主机名是最新的,并能正确路由。由于种种理由,例如防止与外部公司互联网子域名产生名称碰撞,许多网络很可能利用内部网络域名,该域名在更广泛的互联网中是不存在的,例如在这个例子中,微软可以使用一个内部的活动目录域名,如microsoftinternal.com.gt,从而在这个域里,就不会和外部互联网子域名microsoft.com.gt产生名称碰撞。
问题是,很多巧妙的DNS配置错误,有可能造成本来是向内部域的DNS服务器发送的请求,却发送到了顶级域名服务器上。这个问题被称为名称碰撞,并且是一个证据充分的问题,这有时也被称为DNS查询“泄漏”。
如果一个机器使用一个DNS解析器,并且不清楚该内部网络的DNS设置,或配置错误,导致查询到了外部网络的DNS服务器,从而会使这个查询泄漏到“.gt”顶级域名服务器上,因为他们是整个顶级域名空间的授权名称服务器。名称碰撞问题是非常常见的,并且因为这个原因,新的顶级域名往往会做大量的审查,以确保它们不是一般的内部网络域名,例如.local,.localhost,.localdomain,等等。
当有“.gt”扩展的一个内部区域发生泄漏时,一个机器尝试更新一条内部DNS记录,并发送DNS更新查询,但是意外的发送到了“.gt”顶级域名服务器上。例如,microsoftinternal.com.gt内部域有一个主机,并且向com.gt顶级域名服务器发送DNS更新查询。以下是执行此查询的示例,使用了nsupdate
DNS命令行工具(大部分OSX和Linux系统都支持):
我们可以看到该查询导致了一个NXDOMAIN错误,但无论如何,却返回了一个SOA响应,并包含了maestro.gt,它作为了主名称服务器。对于该查询,这是一个有效的SOA响应,因此所有主机会继续向maestro.gt服务器发送DNS更新查询,它的IP地址是52.15.155.128(这是我的服务器,我已经注册了maestro.gt域名)。此更新查询会以失败结束,因为我将自己的DNS服务器设置成拒绝客户端的更新请求(因为我不想主动干扰这些机器/网络)。这就是为什么所有这些随机的机器会向我的maestro.gt服务器发送DNS更新请求的原因。
我们现在遇到的问题从本质上说是一个新的DNS漏洞,这是名称碰撞的结果,导致动态DNS更新被发送到“登记在顶级域名的SOA记录列表中”的任何服务器。与常规名称碰撞不同,为了利用这个漏洞,我不需要注册一个完整的新的顶级域名,我们只需要注册一个普通域名,只要这个域名存在于顶级域名的SOA记录列表中就可以(就像我们注册的maestro.gt)。
自己尝试一下---快速的实验室
如果你想在活动中看到这种行为,实际上重现相当简单。我们将使用Windows 7系统作为我们的示例系统,并安装在虚拟机里,并运行Wireshark监控所有我们机器发送的DNS流量。
更改你计算机的DNS后缀,以匹配危地马拉活动目录域,并将主DNS后缀设置为“.gt”顶级域名下的任何域,如下图所示:
单击确定并应用此新设置,将提示你重启计算机。继续进行,并且当Windows重启时,请保持Wireshark一直运行。你可以看到,在启动过程中,一些动态更新查询发生了:
上图是当Windows在启动期间,Wireshark的输出结果,具体活动如下:
1.尝试向8.8.8.8DNS解析器查询mandatory.dnsleaktestnetwork.com.gt的SOA记录(结果是一个NXDOMAIN错误,因为它查询的配置是8.8.8.8,而该域名在公共互联网上是不存在的)。
2.Windows然后会对这个NXDOMAIN响应进行解析,并从顶级域名的响应中找到一个无效的SOA主名称服务器记录,这就是maestro.gt。
3.然后,Windows会访问maestro.gt(此时它已经是我的服务器了),并尝试发送一个DNS更新请求。这会失败,因为我把服务器设置成了拒绝模式。
4.然后,Windows会再次尝试整个过程。
那么,这个问题有多普遍?
因为危地马拉国家使用的是“.gt”域名空间,该空间和一些大的顶级域名相比很小,如.com、.net、.org、.us等等,因此,我们看到只有一小部分DNS请求受到这个问题的影响。但是,在较大规模的顶级域名空间上,使用了顶级域名的活动目录域、并访问常用顶级域名服务器的流量,有可能很大。
尽管我还没有明确地找到任何以前的“关于动态更新SOA劫持”的研究报告,但幸运的是,我们有很多以前的“关于名称碰撞”的研究,这很大程度上是由于担心发布的顶级域名和内部网络域名相矛盾,而内部网络遍布全球。想要研究这个问题有多么普遍,我推荐读一下《DNS中的名称碰撞》这篇文章,这是ICANN委员会的报告,它对于这个问题有一个很好的概述,能更好的理解名称碰撞问题、及它在互联网中的影响。这篇文章包括了很多真实世界的数据,展现出了名称碰撞问题有多大,这使得我们有一个很好的基础,让我们推断出在这个世界里特殊的SOA动态更新变种分布有多广泛。
也许,在这个报告中,真实世界中最震撼的数据是下面的这张表:
上表是一个顶级域名请求数据表,按照根域名服务器的DNS请求数量排列,单位是千。在原始报告中包含了前100个顶级域名,在这里我们只列出前20个。这张表揭示了原始数据中DNS请求泄漏、并访问了根域名服务器的情况,而这个情况并不意味着到此为止。可以看出,有很多无效的“.local”顶级域名请求并查询了根域名服务器,数据排在了第三位,而且比所有“.org”和“.arpa”的请求数量加起来还多。下面的饼状图也能进一步揭示问题的规模:
上图显示了一个惊人的结果,有45%的请求访问了根服务器,这些请求来自于顶级域名,并且是不存在的、无效的域名,它们有可能是DNS请求泄漏的结果。也许更令人震惊的是,该数字可能更高,由于有些内部域有一个有效的顶级域名,但有一个无效的二级域名,例如之前我们提到过的microsoftinternal.com.gt。这些请求对于根服务器来讲是有效的(因为“.gt”在根区域是一个有效的记录),但是可能在com.gt顶级服务器上会被视为泄漏/无效的。
该报告中提到了一个同样很有趣的问题,它们观察到了这些问题的流量,但是却没有进行更进一步的调查,如下图:
很多请求采用了上面的格式,通常这是在查询SRV记录,尽管有些时候它们是在请求SOA记录,但是它们似乎与微软活动目录服务有关。说明它们存在和本文相同的问题。
报告后面又再次提到:
意思是:“虽然在本研究中绝大多数观察到的DNS流量是用名字查找的(例如,传统的查询),但也探测到了其它一些DNS请求。这些都是动态更新的流量,应该永远不会到达根服务器。毕竟,修改根服务器是不会使用动态更新的,更不用说起源于互联网的随机IP了。最可能的解释是它们可能由于活动目录安装配置错误,流量走出了内部网络,并泄漏到了公共互联网上。需要注意的是,这项研究并没有检查导致这种流量的根本原因。”
该文章最终得到的结论是:
可惜的是,该报告对这个流量的大小并没有给出任何陈述,因此和其它名称碰撞相比,我们没有好的办法得到这个问题的百分比和总量。基于顶级域名可能返回完全随意的SOA主名称服务器域名这个事实(就是.gt和maestro.gt这种情况),实际上要在更大的范围内考虑安全问题,而报告中还没有认识到这一点。这允许潜在的攻击者通过注册一个域名,就像我们利用的maestro.gt,进入到DNS的中间过程。
鉴于公认的这个有限的信息,我认为这个问题有可能正在积极地发生,许多顶级域名服务器在这个问题上肯定能看到一些不平常的流量。依赖于每个顶级域名SOA记录的特殊配置,如果它们的SOA主名称服务器是可以被注册的,就像本案例中一样,它们就有可能存在易受攻击的漏洞。
修复这个问题&充分的TLD安全考虑
鉴于利用这个漏洞的门槛是如此之低(基本上仅仅需要买一个域名),关注它所造成的影响有很多原因,我认为应该要求TLD确保它们响应的SOA的主名称服务器字段是不能被解析的、或解析到TLD控制的服务器上,然后拒绝处理动态更新查询。考虑到这个错误似乎很容易造成,因为SOA主名称服务器字段不再用于从属DNS复制,我不认为这种改变是不合理的。悲哀的是,如果你读过本文前面提到过的生成的TLD健康报告的结果,你将会看到惊人数量的TLD在功能配置上是有问题的。鉴于这一事实,修复这个安全问题的希望也很低,即使是简单的事情,就像是“使所有TLD名称服务器处理于正确工作状态”对于TLDs来讲也是不实际的。如果我们甚至不能确保TLDs的健康,那么我们又怎么能希望确保所有TLDs能减轻这个问题呢?
呼叫网络管理员去阻止他们自己网络中这种类型的问题似乎也无法打赢这场战争,况且还有那么多的DNS名称碰撞。同时通知并确保网络管理员了解这个风险是很重要的,不过确保100%的网络都能正确配置是不可能的。
隐私的噩梦
鉴于这个事实,这台危地马拉机器的问题建立在一个相当普通的基础上,这个漏洞带来了一个相当大的隐私问题,很多DNS请求包含了主机名,这是很隐私的(想像一下NANCY-PC、MYLAPTOP,等等)。由于各种触发因素,造成机器发送了DNS更新查询包,意味着用户的个人电脑在他每次旅行、改变网络、或重启时都会向我的名称服务器发送信息。这导致这个人只要带着他的个人便携电脑,不管他是去上班、还是回家、去本地咖啡店等等,我们都能很容易的监控到他。内部IP地址也增加了隐私风险,因为用它可以绘制出远程网络的IP地址图,这些人的电脑在默默地报告他们的位置,想象一下下面这样的图片就有可能是以这些数据为基础:
不用多说,这种隐私问题肯定会让人有所触动。
有道德的处理研究数据
出于对当事人隐私的尊重,我们在这次研究中收集的数据将不会被公开,并会安全的删除。此外,所有这些计算机的进一步流量都会被路由到127.0.53.53,以确保在我maestro.gt域名剩下的注册期限里(大约两年),没有发送进一步的更新查询。127.0.53.53这个IP是很特殊的,因为它是ICANN专门授权的用于提醒网络管理员存在名称碰撞问题的IP地址。希望危地马拉的网络管理员/技术精明的用户看到DNS流量路由到这个IP后,他能搜索这个IP,并立即发现他们的网络/活动目录设置存在这个易受攻击的问题。
此外,我已经给“.gt”顶级域名的DNS管理员发送了邮件,给她们通知了这个问题,并要求她修改主名称服务器的设置,使它不再被解析。基于没有人可以再利用这一点,并且我已经将流量引导到了127.0.53.53这个事实,同时我的域名注册时间是两年,因此,我决定发布这篇文章,尽管此时主名称服务器仍然是maestro.gt。
总的来说这是一个非常有趣的实验,强调即使是TLD的一个轻微配置错误,也可能造成一些有趣的后果。
状态更新:在我将这个问题发送给危地马拉的DNS管理员后,他们很快修复了这个问题(并很快进行了回复)。
作者:pwn_361
来源:51CTO