【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性

  • A+
所属分类:安全文章
【玄武小酒馆】
是玄武实验室新上线的专栏,
在这里聊技术聊八卦,
分享玄武实验室的生活日常。
小二,上酒

域名解析服务是计算机网络的重要组成部分,在许多场景下默认域名解析服务是稳定可用的,然而在一些特定的场景下,DNS服务的可用性可能是难以保证的。本文以网络空间测绘中的子域名枚举场景为例,对域名解析服务在特定场景下的可用性做一个简单的测试和分析。

引子

发现这个问题是在实验网络空间测绘工具时,为了测试工具的可用性,面向子域名枚举工具设计了一个测试场景:使用当前应用较为广泛的子域名测试工具(massdns、ksubdomain)解析Aleax Top 10k的域名,计算最终获取到响应的域名占所有域名的比例。本文通过数次实验后发现可以获取响应的域名实际为总域名数量的70%-90%左右,这个比例可以通过调整参数、降低速率的方式在一定程度上提高,但是总体提升较为有限(在测试过程中,为了排除其他因素的影响,测试环境配置为4核 8G 100Mbps带宽的服务器,在测试过程中计算、存储、网络资源均留有冗余)。通过这个简单的测试实验我们得到了一个初步的想法:在一些极限场景下,DNS服务器的可用性是相对有限的。

感兴趣的读者可以使用以下几条命令复现实验,其中massdns的性能可以通过 --processes / --socket-count / --hashmap-size 等参数进行调整。

wget http://s3.amazonaws.com/alexa-static/top-1m.csv.zip && unzip -p top-1m.csv.zip | cut -d, -f2 - |  head -n 10k > domains.txt
./massdns --resolvers ./resolvers.txt
--output J --outfile ./out.txt
--error-log ./err.log ./domains.txt
./ksubdomain -f ./domains.txt -verify

对于产生这个结果的原因,我们尝试从子域名枚举的技术的演进过程进行探究。

子域名枚举技术演进

子域名枚举技术是网络空间测绘的重要组成部分,考虑到在测绘过程中目标较多,速度是子域名枚举工具实现时考虑的核心指标之一,这也是子域名枚举工具演进的主线。在枚举子域名时,最直接的实现是使用字典遍历所有可能的子域名并查看是否存在有效的返回,但是这种简单的测试方案几乎无法测试稍大的域名列表。因此出现了第一版方案,即使用多进程、多线程、协程等技术,通过增加单位时间内发送请求的数量来提升子域名枚举的速度。

随着技术的不断发展,zmap使用的无状态探测技术被子域名枚举领域关注,massdns将其应用到了子域名枚举中,该工具仅使用指定数量的数个socket进行网络包的发送和接收操作,在用户层通过hashmap管理网络状态,大幅度提升了子域名枚举的速度。ksubdomain则在massdns上更进一层,使用pcap库直接和网卡进行交互,完成数据包的发送和接收,减少了socket带来的性能开销。ksubdomain同样维护了一个状态表,对于超时的数据自动重传,直至获取到响应或重试测试超过限制为止。除了上述的技术之外还有一些其他的技巧,如预读字典、异步读写、域传送等,本文在此不进行更多的介绍。

一个直观的想法是,上述的工具使用了堪称激进的速度提升方案,那么有着较高的漏报率是可以理解的。但是实际上massdns和ksubdomain都实现了状态表的功能,本文在测试时也在带宽和计算性能上都留出了较高的冗余,将漏报简单归因到高并发带来的丢包或者其他因素上并不正确。随后在进一步的分析中,我们发现高漏报是DNS服务器在部分场景下不可用造成的。

DNS的不可用性

在讨论DNS的不可用性之前,本文先对数据的假阴性和假阳性做一下定义。

  • 假阴性:原本存在有效记录的域名,被认为是无效域名。

  • 假阳性:原本无效的域名,被认为是有效的域名。

在实现的测试后,本文通过流量监控的方式对子域名枚举过程进行了更详细的分析,在分析中发现当发送DNS数据报文到达一定量级后,有一些域名解析服务器会表现出严重的不可用性,我们根据服务器的响应表现将其分为为服务宕机、拒绝服务、无响应、返回脏数据几类。

服务宕机

服务宕机指DNS响应码为 Server failure ,在RFC 1035中可以查询到对应的定义,该响应表示服务器出现了错误。可以在 wireshark 中 使用 dns.flags.rcode==2 server failure 来过滤出该响应的流量,其在流量中的表现如下图所示。

【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性

拒绝服务

拒绝服务指DNS响应码为 Refused ,同样可以在RFC 1035中可以查询到对应的定义,该响应表示域名服务器由于配置的原因拒绝了请求。可以在 wireshark 中使用 dns.flags.rcode==5 server refuse 来过滤出该响应的流量,其在流量中的表现如下图所示。

【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性

无响应

无响应指DNS服务器没有对查询包进行响应,可能是网络抖动造成的丢包、服务器下线等原因,其在流量中的表现如下图所示。

【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性

在上图中直至测试到第8个域名解析服务器,才获取到了响应,而在一些极端情况下(带宽占满、大量并发、源IP被禁),可能数十个域名解析服务器都没有响应。

脏数据

脏数据是指对于原本应返回NX响应的数据,服务器会返回一个虚假的A记录。以下图的域名为例,对于一个实际不存在的子域名,一些DNS服务器仍然返回了A记录。

【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性


经过测试,发现常见的虚假A记录IP如下:

4.36.66.178, 8.7.198.45, 37.61.54.158, 46.82.174.68, 59.24.3.173, 64.33.88.161, 64.33.99.47, 64.66.163.251, 65.104.202.252, 65.160.219.113, 66.45.252.237, 72.14.205.99, 72.14.205.104, 78.16.49.15, 93.46.8.89, 128.121.126.139, 159.106.121.75, 169.132.13.103, 192.67.198.6, 202.106.1.2, 202.181.7.85, 203.161.230.171, 207.12.88.98, 208.56.31.43, 209.36.73.33, 209.145.54.50, 209.220.30.174, 211.94.66.147, 213.169.251.35, 216.221.188.182, 216.234.179.13

这一类的响应就是假阳性数据,这种响应部分是因ISP劫持DNS引发的,部分是由域名污染引发的,具体的介绍可以参考文末的DNS hijacking wiki链接或其他材料。

通过对上述几个场景的分析,我们可以发现,当有一个DNS服务器返回了 Server failure / Refused ,域名枚举工具会认为收到了响应,从而停止测试该子域名,即造成假阴性的结果。如果有大量的DNS服务器都没有返回响应至达到域名枚举工具的阈值,同样也会造成假阴性的结果。而只要有一个DNS服务器返回了假阳性的结果,由于枚举工具的状态表特性,就会造成假阳性的结果。

解决方案

在实际测试中我们发现,即使是一些使用广泛的域名解析服务提供商,在特定场景中也会表现出上文提到的不可用性,所以这个现象是需要在一些工具的实现中被考虑的。对于网络带宽占满、短时间发起大量DNS请求等场景可能遇到的域名解析服务器不可用问题,本文认为有以下的一些解决方案:

  • 尽量组合使用多个DNSPod、114等较为专业的域名解析服务提供商

  • 在要求服务的稳定性和安全性时,可以使用TCP协议、DNSSEC、DNS over HTTPS进行DNS解析

  • 对解析结果预设一定的ASN或IP范围,或通过黑名单机制去掉应答污染IP的响应

  • 定时检查域名解析服务提供的响应,去掉其中不稳定的域名服务器

参考资料

工具

其他链接


【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性

【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性


本文始发于微信公众号(腾讯玄武实验室):【玄武小酒馆】性能优先的隐忧:浅谈DNS的不可用性

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: