一文搞明白SAD DNS
(Side channel Attacked DNS)/ CVE-2020-25705
前言
本文试图理顺和归纳ACM CCS 20上UC Riverside和清华大学的研究人员宣布的针对域名系统(DNS)的新攻击——SAD DNS(Side channel AttackeD DNS)的原理和细节,已被记录为 CVE-2020-25705
论文本体与基础知识:
- 论文:DNS Cache Poisoning Attack Reloaded: Revolutions with Side Channels
- 关于DNS:一文搞明白DNS与域名解析
- 关于DNS缓存投毒:一文搞明白DNS缓存投毒
1、SAD DNS 概述
SAD DNS是经典DNS缓存中毒攻击(自2008年起不再有效)的复兴,它利用了所有现代操作系统(包括Linux、Windows、macOS和FreeBSD)中存在的新型网络侧通道,这代表了一个重要的里程碑——第一个具有严重安全影响的可武器化网络侧信道攻击。此攻击允许非路径(off-path)攻击者将恶意DNS记录注入DNS缓存(例如 BIND、Unbound、dnsmasq)
效果:
- SAD DNS攻击允许攻击者将任何流量(最初指向特定域)重定向到自己的服务器,然后成为中间人(MITM)攻击者,从而允许窃听和篡改通信
优势:
- 击败了最有效和最常用的防御——源端口随机化
条件:
- 允许受害者操作系统生成传出的ICMP错误消息
- 攻击者不在路径上(off-path)(不能窃听转发器和解析程序之间的通信),并且具有伪造IP能力
- 控制能够触发DNS转发器或DNS解析程序请求的计算机,例如,攻击者可以加入咖啡店、购物中心或机场的公共无线网络
- 攻击者还需要控制一个傀儡,该傀儡的唯一责任是在无法直接访问局域网的情况下查询转发器以发起攻击
影响范围:
- Linux 3.18-5.10
- Windows Server 2019 (version 1809) and newer (we did not test older versions)
- macOS 10.15 and newer (we did not test older versions)
- FreeBSD 12.1.0 and newer (we did not test older versions)
- 此外,研究人员还发现互联网上超过34%的开放解析器都是有漏洞的,其中85%是由谷歌、Cloudflare这样的主流DNS 服务组成的
2、SAD DNS 原理
首先需要明确的是:SAD DNS 本身还是DNS缓存投毒,可参见一文搞明白DNS缓存投毒,简明图如下:
问题在于2008年之后,源端口随机化被普遍部署,使得攻击从原先的只需要猜测事务ID(TxID),共216种可能,变为需要同时猜测目的端口和TxID,共232种可能,这就使DNS缓存攻击难以实现,基本销声匿迹
SAD DNS 的贡献在于利用ICMP速率限制机制作为侧信道,成功获知哪个端口是开放的,突破了源端口随机化,使得攻击的需要猜测的可能性从232降为217,于是DNS缓存攻击重出江湖。同时,SAD DNS还想办法扩大攻击窗口,以更容易实现攻击
关键点:
- 推断源端口:为了克服源端口的随机性,SAD DNS利用ICMP速率限制机制作为侧信道来扫描和发现哪些源端口用于发起DNS查询,速度最多为每秒1000次猜测
- 扩展攻击窗口:一个未完成的查询将在几十或几百毫秒内收到来自上游服务器的回复。这是不够的,因为攻击者需要时间来推断源端口和注入恶意DNS回复。SAD DNS针对转发器和解析器各有不同的有效策略,可以将攻击窗口延长数秒(甚至超过10秒)
(1)推断源端口
通过ICMP速率限制和ICMP端口不可达响应推断源端口是SAD DNS的核心思想
前置知识:
- DNS用UDP协议,无状态,源端口向公众开放;但若用socket的connect(),就变成专用端口了
- ICMP端口不可达响应:任何UDP数据包扫描端口范围,在命中正确的端口时不会触发任何消息(因为探测将被操作系统接受,但在应用程序层被丢弃);而端口不可访问的话,在丢失它时会返回一个ICMP端口无法访问的消息
- IP速率限制:比如IP速率限制为 1/s ,即在1秒这段时间内只限1个IP访问DNS解析器上的端口。Linux内核2.4.10中引入
- ICMP速率限制:表示在这段时间内,DNS解析器最多能发出的ICMP响应报文个数。比如:ICMP 速率限制为 50 /20ms ,这里表示在20ms内只能返回50个ICMP响应。比如攻击者以 1000/20ms 的速度进行探测端口,这里只能返回50个ICMP不可达报文。Linux内核3.18中引入
- 临时端口:只对权威域名服务器开放,攻击者并不知晓,所以要用到IP欺骗,伪造权威域名服务器的IP发送UDP探测报文
对于公开的端口,任何攻击者IP都可以直接探测源端口,例如unbound和dnsmasq
- 绕过IP速率限制:用多个IP,通过DHCP申请多个地址,IP欺骗
- 利用ICMP速率限制查找端口:如下图所示,先找到ICMP速率限制,比如是50/20ms,那么攻击者先在20ms内发送50个伪造的探测包,每个包IP不同,然后攻击者以自己的IP再向解析器已知的封闭端口发送一个UDP包,如果没收到任何ICMP回复,说明已达到ICMP速率限制,可进行下一个20ms的探测,不断循环。如果此时收到不可达响应,说明前面50个端口里至少有一个端口是开放的。可通过二分查找,查找开放的端口
- 注意事项:注意时间,这个case里,一轮攻击要在20ms内,两轮攻击要间隔50ms;二分查找时要发送填充数据包(发送到已知关闭的UDP端口的欺骗数据包)确保触发ICMP应答;对于噪音,可以用多个IP,并在探测包和验证包之间加个延迟
对于专用的端口,即用了socket里的connect(),有意思的是,ICMP速率限制是在IP速率限制之前进行验证的。所以,即使最后一个IP只返回一个ICMP响应包,但是ICMP 速率限制的计数器是变化的。所以原理其实没有大变化,只要用IP欺骗就行了,即用上游DNS服务器的源IP发送伪造的UDP数据包
(2)扩展攻击窗口
攻击窗口:DNS解析器向服务器发送查询,到权威域名服务器响应报文到达解析器的这段时间
所以扩大攻击窗口的主要思路,应该集中在阻止响应报文的到达,或延迟响应报文的到达
1、转发器攻击的扩展窗口方法
转发器在设计上信任上游解析器及其响应,那么就可以向转发器发送自己域www.attacker.com的查询,转发器触发上游解析器查询攻击者控制的权威域名服务器,再将权威域名服务器配置为无响应
乍看之下这没什么意义,但是转发器无条件信任解析器,所以在施加了最大的等待时间,即攻击窗口后,最终转发器将接收到如下图所示的恶意响应:
从而对www.victim.com目标域进行投毒
2、解析器攻击的扩展窗口方法
现代DNS名称服务器软件(如BIND、NSD、PowerDNS)都支持一种称为响应速率限制(RRL,response rate limiting)的通用安全功能,以缓解DNS放大攻击。具体来说,如果达到限制,则响应要么被截断,要么被丢弃
那么,就可以通过发送大量的DNS查询来淹没权威域名服务器,类似于攻击者伪造解析器,发送大量DNS query,高于配置限制的速率(服务器上配置的RRL),会使权威域名服务器不发送响应,于是正常的请求,要么被丢弃,要么被堵塞,以此扩大攻击窗口
3、实验
论文中做了两个场景的实验:
- 运行在家庭路由器上的DNS转发器
- 运行BIND/Unbound的DNS解析器
一个攻击成功的展示
(1)攻击DNS转发器(家庭路由器)
对转发器的调研如下:
实验装置:
- 小米R3(一种Wi-Fi家庭路由器),连接了10到15台设备
- 小米R3的上游DNS服务器设置为CloudFlare DNS(1.1.1.1),其DHCP服务器默认配置为在a/24网络中提供253个IPv4地址
- 攻击机器是一个树莓派,它也连接到路由器无线
攻击过程:
- 第一阶段,攻击者尝试使用DHCP策略获取240个IP地址
- 第二阶段,重复以下操作,攻击者向转发器发出查询,要求提供任意子域,例如nonce.attacker.com. 如果收到SERVFAIL/NXDOMAIN或者攻击者等待的时间超过1分钟,说明出现问题,我们将通过发出另一个查询来重复攻击过程,否则,如果接收到响应,则表示成功注入伪造的响应。在第二阶段,攻击者使用获取的IP地址扫描路由器上的开放端口。我们在可用IP之间轮换,并确保我们永远不会超过每IP速率限制(稳定状态下为1pps)。在发现一个端口打开后,我们通过重复探测同一个端口来确认它至少保持打开一秒钟。如果有,我们就开始注入伪造响应
- 实验重复20次,报告成功率、平均成功时间等统计数据
结果:
- 在20个实验中成功率为100%(如果攻击在30分钟内完成,我们认为是成功的)
- 平均成功时间为271s,第一阶段为103s,第二阶段为168s。第二阶段的标准偏差为109s,最大值为739s,最小值为83s。由于攻击时间主要由攻击窗口大小决定,即冲突解决程序决定放弃并返回SERVFAIL/NXDOMAIN之前的超时,因此差异较大
- 攻击平均需要扫描36325个端口才能成功;平均端口扫描速度为210pps,这与使用240个IP进行扫描时的预期速度240pps大致相当
- 攻击产生了78MB的流量
(2)攻击DNS解析器
对解析器的调研如下:
实验设置:
- 冲突解决程序每天处理大约7000万个查询,有数千个实际用户跨多个机构访问。一个值得注意的行为是它有两个后端服务器,这两个服务器似乎都在UDP套接字上使用connect()。有趣的是,我们被告知它们正在运行Unbound,我们怀疑类似connect()的行为可能是由于负责过滤状态外数据包的有状态UDP防火墙造成的
- 在一个相邻的网络中得到了一个距离解析器4跳的攻击机器,解析器有一个1Gbps以太网,可以执行IP欺骗
- 设置了一个测试域,并将其托管在由我们控制的权威服务器上,以便只对自己的测试域下毒。我们将BIND软件的响应速率限制配置为10pps,以尽量减少对网络的影响。一旦达到极限,我们仅允许五分之一的响应,有效损失率为80%。这形成了baseline实验的设置,我们进行了20轮实验,一轮在白天,另一轮在当地时间午夜之后(如表3所示)
- 为了了解响应速率限制对权威名称服务器的影响,我们改变了静默级别,允许丢失率为75%、66.7%到50%——丢失率越低,攻击越困难
- 还通过在同一台攻击机上施加额外的延迟、抖动和丢失来模拟更真实的网络条件。表3给出了准确的数字,其中baseline表示未修改的网络条件和altered表示模拟条件
- 为了应对由模拟网络条件引起的误报增加,我们在实验中使用了两个IP发起攻击;这是为了避免由于耗尽每个IP令牌而过于频繁地停止扫描
攻击过程:
- 类似地,从攻击者生成请求查询nonce.attacker.com开始
- 因为解析器有两个后端服务器IP,所以同时在两个IP上启动端口扫描
- 同时,以20pps的速率将所有具有查询的权威名称服务器静默,这样解析器将有80%的恒定丢失率
- 实验分别在baseline和altered上重复20次和5次
结果:
- 如表3所示,我们在第一个baseline实验Base(D)(白天)取得了完美的100%成功率,平均成功时间为504s。标准差为399秒,最大值为1404秒,最小值为13秒(这只是运气使然),平均只生成69MB的攻击流量
- 如表3所示,Base(M)实验与Base(D)实验的设置完全相同,只是在午夜后进行,此时背景交通量和噪声通常较低。我们观察到同样的100%成功率,平均成功时间从504s减少到410s,这是意料之中的,因为我们的攻击对噪声很敏感
- 此外,对于表3所示的实验,除了50%的丢失率外,其他所有的都可以达到近乎完美的成功率,并且通常可以在一小时内完成(注意66.7%的静音级别的成功阈值为3小时)。在50%的静音水平下,20例中只有9例成功,平均耗时为8985秒或2.5小时。
- 最后,对于altered实验,我们也取得了成功率100%,成功时间分别为2005s、538s、792s、1287s和29s。平均攻击时间为930秒,产生131MB流量。注意,altered实验中的扫描速度高于baseline实验中的扫描速度。这是因为我们在altered实验中使用了两个IP,减少了扫描过程中中断的频率。
- 丢失率和抖动的增加会导致更多的误报,我们就错误地认为发现了一个端口(因为验证数据包成功地请求了一个ICMP)。这通常是由探测数据包的任何丢失引起的,这会产生两个问题:(1)在二分查找阶段,我们浪费大量时间过滤这些误报,从而降低有效扫描速度;(2)扫描仍然会被停止,因为即使我们使用了两个IP,ICMP令牌也会频繁耗尽
4、矛与盾
(1)关于攻击
攻击中还有些细节需要注意
1、绕过缓存记录的TTL
对于解析器缓冲区而言,可能已经拥有某条记录,但攻击者不得不等待这条记录消失之后,再发动攻击。TTL即表示这条记录的生存时间,时间可能为1天或者更久。
对此, 攻击者访问类似1.xxx.com、2.xxx.com、3.xxx.com等等这些大概率就完全不存在的域名,由于DNS解析器并没有这些域名的缓存,就会发起查询,假设ns1.xxx.com是xxx.com的权威DNS,DNS解析器就会去ns1.xxx.com询问
这个攻击比较精彩的地方是:可以不在应答区做手脚,而是在权威区和附加区行骗!
伪造的响应包,大约是这个样子:
代码语言:javascript复制
代码语言:javascript复制问题区:83.xxx.com A
应答区:(空)
权威区:xxx.com NS www.xxx.com
附加区:www.xxx.com A 6.6.6.6
代码语言:javascript复制这个响应的意思是:“我不知道83.xxx.com的A记录,你去问问www.xxx.com吧,它负责xxx.com这个域,对了,他的IP是6.6.6.6”。
而这里的6.6.6.6,就是攻击者意欲让DNS解析器相信的IP地址,即攻击者控制的DNS服务器,这样被攻击的DNS解析器所有向xxx.com的访问都被劫持了 2、在DNS解析器后面处理多个后端服务器
许多公共DNS解析器有多个后端服务器(具有不同的IP)来执行实际查询。有趣的是,后端服务器的选择通常严重偏向于少数几个(即使我们确实看到一些提供商总共有100多个),可能是根据位置和过去的性能度量来确定的。这使得我们可以只关注几个IP,这很容易实现,因为每个IP只需要1kpps的扫描流量
3、必须发现目标IP或一组目标IP
在某些情况下,这可能是微不足道的-可以通过探查和观察攻击者控制的区域来发现单个转发器或一组固定的IP,但是如果目标IP跨区域分区,则更困难,因为攻击者看不到解析器除非她可以监视受害域的通信量,否则将输出IP
(2)关于防御
针对推断源端口:
- 用户禁用ICMP 响应,禁用UDP端口不可达ICMP回复消息的命令:
iptables -I OUTPUT -p icmp --icmp-type destination-unreachable -j DROP
,服务iptables保存 - 使用随机ICMP全局速率限制,包括可能随机设置允许的最大突发(当前50个)、每次恢复的最小令牌数(当前20个)、恢复令牌的最小空闲时间(当前20ms),以及每个时间单位恢复的令牌数(当前为每毫秒1个)
- 建议解析器在其UDP套接字上使用connect(),这样它们的源端口就不会面向公众并且可以直接扫描
针对扩大攻击窗口:
- 将DNS 查询的timeout设置的更加严格例如,总是低于1s)。这样,在攻击者开始注入欺骗响应之前,源端口将短暂消失。但是,缺点是可能会引入更多的重传查询,总体性能较差
- RRL的配置问题:当达到速率限制时,服务器用截断的消息来响应,而不是保持沉默。这样,它向解析器发送了一个强信号,表明发生了不好的事情,解析器应该立即做出反应,例如,要么切换源端口并发送一个新的查询,要么完全退回到TCP
其他:
- DNSSEC是最好的防御措施,但问题仍然是成本高,部署极少
- DNS cookie,在RFC 7873[1]中于2016年标准化。在较高级别上,它要求客户端和服务器交换一些非路径攻击者不知道的额外秘密;因此,它有可能击败大多数非路径DNS攻击。问题是此功能需要同时升级解析器和权威名称服务器才能看到好处,且到目前为止,只有BIND实现了这个功能,并在9.11.0 forward[28](2016年发布)中默认启用了这个功能。还有就是兼容性问题是否会阻止它被广泛采用还有待观察
结语
咀嚼消化了SAD DNS
参考:
- 官网:https://www.cs.ucr.edu/~zhiyunq/SADDNS.html
- SAD DNS–新型DNS缓存中毒攻击
- SAD DNS解释
- DNS新劫持方法(“侧信道攻击“攻破“端口随机化“)
红客突击队于2019年由队长k龙牵头,联合国内多位顶尖高校研究生成立。其团队从成立至今多次参加国际网络安全竞赛并取得良好成绩,积累了丰富的竞赛经验。团队现有三十多位正式成员及若干预备人员,下属联合分队数支。红客突击队始终秉承先做人后技术的宗旨,旨在打造国际顶尖网络安全团队。