02
演讲内容
以下为速记全文:
本议题主要介绍了域名服务系统的重大安全漏洞,使得攻击者可以利用该漏洞实施全新的域名缓存污染攻击:MaginotDNS。
我们知道DNS是互联网基础的安全服务,而且DNS也是我们很多安全机制的基础,比如防范拒绝服务攻击的CDN它实际上是靠DNS来做路由的。
邮件的路由也是靠DNS里边的mx记录来做指引的。现在网站不相信域名,需要有一个公钥证书来保证网站是真实的,数据传输是加密的。
在申请证书的时候CA怎么验证身份呢?其实在大多数情况下还是依赖于你是否拥有这个DNS的控制权。其实这个点上还是有一些奇怪的依赖关系,我们不相信DNS,但是我们申请CA证书的时候,CA还是相信DNS对吧?
我们现在的很多安全机制,比如口令忘了,需要邮件来恢复你的口令的时候,你得发给你确认的链接,还是通过DNS里边的邮箱记录来最后找到你这个人。所以我们现在可以看到 DNS是互联网安全的基石,说它是信任的锚点,是一点也不过分,可以说DNS的一点小事就可能是互联网的一件大事。我们今天要介绍的攻击是可以用来接管整个顶级域名下边的所有的网站,.com和.net。
在介绍这个攻击之前,我们先看看曾经 Dns的基本的工作流程。虽然是互联网开始的时候是一个端到端的模式,但是我们现在发展到今天 DNS的解析基本上还是依赖于一个缓存递归服务器,在家里边我们靠电信给你分配的服务器,然后在企业里边在校园里边都有自己的递归服务器,现在会越来越多的使用像4个8、4个114这种公共的DNS服务器,这个DNS服务器都提供了一个缓存的功能,如果这个缓存的记录一旦出了问题,使用这个DNS服务器的所有的用户都会受到影响。我们今天的缓存污染攻击,我们学术圈里面叫威胁模型。
这个攻击其实非常久远,有人说在90年代就已经提出了DNSSEC这种以公钥算法数字签名为基础的通用的防范机制,缓存污染攻击还有什么研究的价值?但实际上我们看一下,虽然应该是1995年前后,DNSSEC提出到现在已经近30年了,DNSSEC作为数字签名那一方部署还相对好一些,但是有人签名了,但如果不做验证的话,其实这个机制也是没有用的。
我们可以看到这是 AP neek它做的一个DNSSEC的测量,在中国这个递归服务器也就是缓存那个服务器那地方做DNSSEC和数字签名验证的比率0.02%,这个比我前两年看的还低了,前两年看的是1.6%。所以剩下还有99.8%的还需要多少年才能部署完成的?
所以我们很难指望我们未来的一个美好蓝图能够保护我们今天的安全。所以我们可以说还有绝大多数的DNS还是存在这种缓存污染攻击的。我们的攻击也就像历史上我们曾经发现的一样,一次又一次的希望能够促进大家赶紧把DNSSEC部署上,但是看来效果不大,我们希望今天的报告能够让运营商能够再进一步的重视DNSSEC的部署。
那DNS缓存污染的攻击,它影响的范围可能是多大?这是2013年曾经出现过的一次攻击。在巴西这是一个中等规模的运营商,差不多有三四百万的用户。他的用户在访问谷歌在巴西的节点的时候,被弹出这么一个消息,说你要访问谷歌就必须安装谷歌的防病毒软件,这显然是一个木马软件。
就这样的攻击在长达10个月里边没有被发现,当然它并不是这么直接的,其他的一些做钓鱼攻击的用户其实是很难发现的。这样的攻击能够达成的实际的一些攻击效果,比如这是我们在2018年也是在上海做的一个攻击,一个关于DNS漏洞的展示。这在一个公共的WiFi环境下,大家访问京东的时候,现在看的是正常的,但如果攻击者接入到公共的WiFi环境下,这种场景非常常见的,比如像咖啡厅、机场、酒店,然后我们就发了几个机型的DNS的查询,现在受害者再回到 WiFi环境下,那么在访问京东的时候,现在实际上看到的是被我们劫持的一个网站。
在介绍我们今天的攻击之前,我先介绍一下缓存污染它的前世今生。
最早的是1997年的Kashpureff的攻击,这中间黄色的这些是我参与的,我和我的学生参与的一些攻击,最后我们发展到今天,看看MaginotDNS究竟是怎么回事。我们要攻破马其诺防线,我们先看看马其诺防线是怎么建立起来的。
第一个攻击,1997年Kashpureff对当时的管理域名的InterNIC不满,他起了一个叫AlterNIC,然后就把InterNIC的域名给接管了。这个过程其实非常简单,我们可以看一下。攻击者向 ISP的递归解析服务器发了一个请求,请求他自己的服务器AlterNIC的这个域名,因为他自己控制的域名服务器,这是完全符合DNS的协议要求的。
然后向ISP返回了一个畸形的响应,这个响应里边,后边可能也遇到,有一个请求有一个响应,后边还有一个权威authority, section里边包含了InterNIC的域名服务器,域名服务器的名称是AlterNIC.net,然后AlterNIC.net地址是1.2.3.4,也是Kashpureff这个人他所控制的,然后ISP的递归解析服务器就接受了这个记录。
虽然你请求的是AlterNIC,他捎带着给你的一个InterNIC他也接受了,然后 ISP的递归解析服务器,就向攻击者控制的这个服务器去查询InterNIC下边的所有的域名,用这种方式就接管了InterNIC,其实是可以接管所有的域名。显然这个问题出在哪里?就是对于输入数据的验证是吧?
网络上输入数据的验证,InterNIC显然不应该在AlterNIC这个范围之内,所以针对这个攻击以后, itf互联网标准的制定组织就推出了RFC2181,明确提出了一个叫Bailiwick的概念,就是辖区。就是你返回的记录,应该就是你查询的记录的范围,这个辖区范围指什么?比如你查询的example,然后因为answer在example这是满足辖区规则的,但是你的authority里边有一个bank.com,这是不符合辖区规则的,这些记录都应该给剔除掉。很简单的一个过程是吧?
这个机制也在后来几乎所有的DNS软件当中都已经得到了实施。所以要想再实行这么简单的攻击,其实是不太可能。直到2008年,大家对DNS的缓存污染的攻击已经比较沉寂的时候,然后这个Dan Kaminsky是美国的一个安全专家,他在BlackHat黑帽大会上做了一个报告,当时他就提出了一种新的攻击,说缓存污染其实还是非常严重的,它的成因主要是因为攻击者现在并不是靠请求他自己的,而是他请求真正的 bank.com,但是同时他用自己控制的服务器向递归服务器发大量的这种假冒的响应,我们知道假冒原地址其实到现在来说还是相对容易的,世界上还有1/4左右的IP地址空间,运营商不对所发出的原地址做验证。这个DNS靠的是什么来验证响应的合法性?其中最重要的就是DNS头里边有一个 query ID可以就叫transaction ID叫TXID。比如发出去的请求里边,ISP到authority, my bank.com,有一个10101这个数,那么你的响应里边应该精确的匹配10101。这个数空间多大,16个比特,二的16次方65536,当时也许在设计者看来挺大的,但是在2008年这个数其实实在是太小了。
然后如果攻击者返回的假冒的响应,刚好匹配的 trans xid10101,那么合法的响应就被丢弃了。他到的时候 udp的端口已经关掉了。有人说这个缓存还有一个ttl time to life,之前大家认为比如缓存的时间一个小时,那么一个小时你才可以发起一次的攻击。比如65536次才可能成功的65536×一个小时,这多长时间?
但是Dan Kaminsky提出说我可以每次查询一个随机的域名,这也是当时它相对比较巧妙的,也就是说递归服务器对于不存在的这种域名,其实他不知道是存在还是不存在,他就只好再去每次发这样的随机的查询,递归服务器都要发一个请求出去,那也就是总是有攻击的机会。
自从Dan Kaminsky提出这个攻击以后,缓存污染攻击再次被大家所关注,然后也提出了一些防范的措施,其中最简洁的防范的措施就是对于 udp的源端口,大家知道DNS使用53端口作为目标端口,它源端口通常是一个比较大的随机数,空间是16个比特,就65536,现在合起来大概有42亿的这个空间,再想暴力的去拆解这个数就非常的困难了。
这是2008年,又过了10多年到2020年,这也是我们实验室参与的,以钱志云老师在UC riverside加州大学河滨分校,我们一起发现的还有这样一个攻击,这是钱志云老师非常擅长的侧信道。
怎么样发现源端口号呢,刚才说65536猜起来太复杂了。钱老师发现了Linux在ICMP实现过程当中有一个共享的全局变量,共享的全局变量泄露出了源端口号是多少,它怎么泄露出来的?
我们知道udp的端口扫描是发一个请求过去,如果那个端口关闭了,那么他会给你发一个ICMP的叫port unreasonable的这么一个ICMP的报文,如果没有发,他有可能就是开着的对吧?但是也不是说无限制的给你发ICMP,否则的话就可能会造成一个反射攻击,对不对?反射攻击我假冒你的地址发过去,然后发到那个目标上,如果那个目标地址向你发一个ICMP,那么我就可以隔山打牛,利用它来攻击你了。
所以对于ICMP的 port on return有一个全局变量,它限制每秒钟,比如只能发50个,钱志云老师他们就发现可以利用这个共享变量作为一个侧信道来泄露源端口号。这怎么做呢?攻击者向他们攻击目标的DNS resolver,发50个 udp的端口探测的这么一个包。
如果这50个没有命中,也就是说刚才发出去 DNS的查询,它开放源端口不在50个端口范围之内,那么他最多就发50个ICMP的potrever。但是攻击者并没有办法看到这50个ICMP,因为它假冒权威服务器ans的服务器, reservoir向这个权威服务器发的50个ICMP的包攻击者是没有办法看见的,他怎么知道他发了50个?这时候攻击者在用自己的地址、不假冒地址的情况下,向 reservoir发一个udp的探测,如果这时候没有搜到ICMP的partnerable,那么它就是证明刚才那50个计数器已经用完了,这里边就是有一点技巧,利用假冒原地址去探测 ICMP的包全局计数器是不是已经用完了。
打开的情况下,如果在打开的情况下会是什么情况呢?
攻击者还是假冒这个权威服务器中间的dns,向reservoir发50个udp的探测,如果刚好有一个命中,那么其中有一个就没有触发ICMP的product,也就只共发了49个,现在攻击者再用自己的地址去向resolver发udp探测的时候,那么他就可以收到一个ICMP的partner,就是计数器还剩了一个,他就用这种方法每次发50个包,每次发50个包,这样就可以很快的探测到源端口是多少。我们把它叫做side channel assistant DNS attack。
用这种方法大家可以简单的想一想,就是把2008年所增加的源端口随机化的那个功能给抵消了,又回到我们1997年的攻击了。
怎么防御攻击?其实相对来说防御是比较简单的,原先不是50个计数器,我很容易猜,现在我让你猜不出来。在Linux内核里边把全局的共享变量,ICMP global这个变量变成一个随机的值,这也是在钱志云老师文章发表完之后,net社区里边把这个数给改了,于是再要做这种缓存污染的攻击,你要做四十多亿的探测了,然后下边是另外一种攻击。
介绍这个攻击之前,我们先简单介绍一下分片的原理。在什么情况下会发生分片呢?是链路上的最大传输单元,比如你路由器上边是以太网,1024个可以装1500个字节,后边只能装512个字节,于是这一个IP的packet就被分成了两个fragment,这两个fragment就有一个问题,就是第二个分片里边它只有IP的head,没有 udp的head了,我们刚才说 Udp的head里面有端口号,还有DNS里边有一个transcendID。第二个分片,我如果能够伪造的比较像的话,我可以不用猜,我用第一个分片里边的那个数,那个数是合法的DNS。怎么让它产生分片呢?有两个办法。
一个是我让你 mtu很小,另外一个我是让你包变得很大。在2013年的时候,德国人他们做了很多DNS的研究,他们提出这个方法就是我怎么让权威DNS不分片变小,然后可以假冒,其实他都不用假冒地址,因为路径上的任何一个路由器都有可能给分片,然后他就发这么一个叫packet to big的ICMP的包,然后全服务器就可以把这个包给分片了。这个攻击原理上非常简单,攻击者可以首先发第二个分片,为了保证它能够抢在合法的第二个分片到达之前,第二个分片在第一个分片到达之前,他是可以被缓存在递归服务器的协议站的数据结构里边还没有提交到DNS,那下边他再发起一个DNS的请求,这个权威服务器给返回了两个分片,第一个分片里边包含原端口号,目标端口号,还有川xid都是合法的完整的完美的通过了DNS递归服务器的验证。
第二个分片在那等着,拼在一起就构成了一个缓存的污染。这个攻击我们在2018年的时候,其实看到他们发表的另外一篇文章是攻击证书权威ca的,然后在2020年的时候,我们又做了一个测试,其实发现这种攻击已经不太可能了,是因为什么?
我们当时对排名十万的域名做了一个测试,发现那些权威服务器它在Linux内核里边把最小的分片绝大多数降成了528个字节,实际上我们一般的DNS的响应是小于512个字节的,所以他不会给你分片,你再给他发再小,但是这个权威服务器会把这样的包给忽略掉,于是这分片攻击似乎也不太可行了,但是我们当时发现还有另外一个思路,你让 mtu变小不行,我可以让packet变大,怎么变大?
我们找到另外一个突破点,就是除了中间的递归服务器以外,还有一个现在越来越多的就是那种转发服务器,我们现在的WiFi路由器,现在很多企业里面也是把自己的服务,像家用WiFi路由器,公共的WiFi路由器都把它转发到比如114、4个8这里面。我们可以在权威,权威是我们自己控制的attack.com,它可以用 cname构造一个列,你看a.com,cname就相当于一个别名,a指向B、B指向c这都是在攻击者的权威下控制的一个子域名。
然后我们看到的超大的 DNS的响应,她还是满足我们刚才说的Bailiwick的规则,因为都是TAC.com下,但这个包可以完美的通过递归服务器的Bailiwick的检查。但是这时候他必须得分片了,他一旦分片之后,后边第二个分片是攻击者发出来的,也就是说在递归服务器看到的是中间的这两个是分开了,但是在forward DNS中间的转发服务器,左边转发服务器看到是攻击者发出来的第二个分片跟它拼在一起的,所以用这种方法又再一次的绕过了Bailiwick的检查。
到目前为止我们可以看到为了防范攻击,源端口的随机化,carry ID的随机化,实际上还有查询域名大学写的水计划,还有IPID。一旦涉及到分片,其实还有一个前面的ipid必须一致,你还得预测那个值。后来为了防范这种预测,ipid的随机化也做了,一直到现在我们可以看到可以做的随机化,大概这不算是域名查询的随机化,我们以2的48次方这个数量,你再想做暴力的这种拆解,其实是几乎不太可能了。
这也是我们在2020年前后做过一次全局的测量,端口随机化,transaction随机化,再加上其他的现在部署率已经越来越高,几乎是100%了。
到DNSSEC的部署可能测量的结果不太一致,至少我当时测量还是挺高,但现在不对了。固若金汤的马其顿防线基本上建成了。大家知道他修筑的这个范围大概就是法国和德国的边境,我们看地图或者我们知道历史,大概都知道马其顿防线其实不是被攻破的,而是被绕过的是吧?
怎么样去找到马奇诺防线它的边界,或者曾经历史上那个比利时究竟在哪里,这是我们这个研究发现的一个问题。这个论文我们是今年的8月份已经发表了,大家可以通过这个二维码来下载这个论文,仍然也有一些视频的演示。简单地说它的攻击目标是一个叫做条件域名解析服务器conditional DNS server,这种服务它部署在什么地方?
首先它兼具查询转发和递归的功能,我们刚才说这两种角色,实际上既然是解析服务有多种不同的角色,这是我在美国访问的同事,伯克利那边的马考曼他们发表这篇文章,这里边把客户端的DNS服务分成了这么几个复杂的类型,包括 forward,包括recursive做递归的,然后还有一些他看不见的叫隐藏的,我们当时问他,你隐藏的这黑的,你既然看不见你怎么测出来?
他说我不是测出来的,他说我是跟运营商的人问出来的。
我们在做这个研究的时候,也是跟很多运营商的,包括114,也包括阿里我们都了解过,包括电信运营商,其实我们也知道有一些比这个图里边还要复杂,我们研究的 Forward fdns和rdns它是混合在一起的一个角色。
这篇文章其实没有明确的提出,所以对它的研究其实大家并没有太多的关注,因为我们就发现有几种场景,第一个是企业内网它部署一个DNS解析服务器,对于大多数的域名,所以他就直接转发到外边去了,比如114,比如4个8,然后是对于企业内部的服务器,我自己可以做,比如说华为、谷歌都可以在不需要申请一个外部域名的情况下,有一个自己内部的服务器,就是攻击者有可能是一个企业内部的用户,也有可能被攻破的一个企业内部的电脑。
那么它可以通过我们说的叫做off-path,就是它不监听网络的情况下,来做这种攻击。
另外一种,运营商里边缺省我们是做递归的,但是它对于某一些域名,其实它是可以做转发的。
比如有一些合作伙伴,比如这些视频流量消耗特别大的一个网站采用本地的一些镜像,这些本地的服务器有可能就在维护他自己的权威服务的时候,那有可能比如处于跟竞争对手的这种这种对抗,有可能会比如把竞争对手商业伙伴给他接触过来,所以这种场景也还是比较常见的,就是运营商把一部分的域名转发到第三方维护的DNS服务器上,还有攻击者也可以完全不控制任何一个DNS服务,他只要能够探测出来,是这个条件转发就可以了。
这个攻击讲到现在其实原理上非常的简单,首先递归服务条件,DNS服务,它是同时启用转发和递归,但是转发和递归共享一个全局的缓存。攻击者发起一个请求,如果匹配到转发的区域里边,那么攻击者可以在返回的响应里边伪造一个.com的权威记录。
然后我们后边会介绍主流的DNS软件,对于转发回来的数据的检查是非常的不严格,然后就可以污染掉递归服务器里边的.com的名字记录。以后,其他的受害者在查询递归服务的时候,这个记录就被左边的攻击者所污染掉了。
这里边主要的问题就在于这个CDNS,就是条件DNS服务器对于转发的这一部分,它的结果的验证是非常的差,尽管它对于递归那部分的验证是固若金汤式的这种防范。
另外还有一个就是他们共享全局的变量,这个是说起来简单,但实际上要发现这些软件的问题还是蛮复杂的,因为这些问题其实也没有办法用自自动化的方法,比如fuzz来做测试,很多靠人的一些经验,我们分析了主流的开源软件,做代码审计,对于像微软的DNS只能做黑盒的一些审计和测试。
我们发现他们在做转发服务的时候,最初的有一个函数里,对于查询的区,它的初始化的设置都是root,也就是说返回的所有的响应都满足Bailiwick的规则,这也是最根源的问题,对于on-path,也就是说如果攻击者可以控制其中的一个权威服务器,比如运营商的这种场景下,那么它就可以返回任何一个记录,比如直接返回一个.com的记录,就把这个递归服务器的缓存给污染了。
另外一种如果他没有这种权限,就on-path的攻击,它只能靠猜端口号的情况下,我们刚才说的像 side DNS侧信道的方法,可以用来扩展一下,也可以做这个工具,但是我们还发现另外一些问题,比如对于BIND的攻击,看似2的16次方,也就65536个源端口,但实际上BIND它使用的端口只有上面的那一些部分,也就是2万多个,一个forward查询1.2秒之后就要超时,我们要在1.2秒之内返回一个合法的响应。
假设我们还是用sad里边每次拆50个端口,我们大概如果是拆3600,也就是一个小时,一个小时的成功的概率是99.8%,看似你一个小时就可以成功了,但实际上我们想一想生日悖论,大多数情况下我们用不到一个小时,我们只需要800秒左右的时间差不多就可以攻击了,剩下还有65535只需暴力枚举就可以了,只需要100毫秒。
另外对于微软的DNS,我们发现它的源端口的随机化做得更差,它只用了2500个端口,这种情况下我们连猜那种技巧都不需要了,我们就直接一个暴力的破解一个暴力的枚举,最后也是800秒左右的时间,我们很大程度上就可以攻破了。也就是基本上我们用七八百秒的时间基本上就可以攻破 DNS,微软的DNS和BIND的这些是最主流的。
但你说这好像都是你们在实验室里面做的,真的在互联网上你怎么样去找到这样一个conditional DNS呢,因为 DNS他不告诉你我是同时做转发又做递归的。
大家如果看我们论文的话,可以了解更多的一些细节,我们是使用了一个特殊的方法来确定它是这样的一个DNS,而且通过版本号的分析探测它可能是受到影响,这个数量还是也超出了我们的想象,在比较稳定的 DNS解析服务器当中,41%是这种条件递归服务器,然后在这里边大概有14.8%是可以受攻击的,我们排除掉已经启用DNSSEC的,那是我们没有办法的。
到目前为止,我们已经通知了我们测试过的所有主流的DNS的厂商获得了4个CVE的编号,微软给了奖励,然后最核心的修补的办法就是把那里边最初始的变量给改成转发的域名,而不是root。这个也是在今年的8月份BlackHat做过一个展示,也在一些其他的媒体上做了一些报告。因为我们整个工作是提出了一个之前被忽视的 DNS的解析角色,就是条件DNS。在我们研究的这个基础上,现在的主流的DNS都已经把这个问题给修补了。
刚才其实那个视频要演示下来还有一分多钟,但实际上我们有没有可能用更短的时间来攻破这个缓存,比如有人说能不能在一秒钟之内做完。我们下边的一个攻击,这个攻击我给它取了个名字叫突门,已经被明年5月份 ICMP给录用了。这是到目前为止,我们从缓存污染1997年一直发展到现在,一次又一次的攻击,一次又一次的修复,再往后还会是什么呢?如果明年有机会的话,我还希望再跟大家来分享一下,谢谢大家。
*峰会议题PPT及回放视频(剪辑中)已上传至【看雪课程】https://www.kanxue.com/book-leaflet-171.htm
PPT及回放视频对【未购票者收费】;
【已购票的参会人员免费】:我方已通过短信将“兑换码”发至手机,按提示兑换即可~
《看雪2023 SDC》
球分享
球点赞
球在看
点击阅读原文查看更多