本文翻译:mssp299
本文属于安全脉搏原创金币奖励计划
转载请参考:https://www.secpulse.com/archives/61458.html
最近,安全研究人员在systemd中发现了一个漏洞,攻击者可以利用该漏洞对许多Linux发行版发动拒绝服务攻击。准确来说,该漏洞位于DNS解析器中。对于存在这种漏洞的系统,攻击者可以利用该漏洞让系统将DNS查询发送到处于攻击者控制之下的DNS服务器,之后,该DNS服务器会返回一个精心构造的查询,导致systemd陷入无限循环,从而将系统的CPU使用率固定为100%。这个漏洞对应的编号为CVE-2017-15908。
实际上,为了让用户查询处于攻击者控制下的DNS服务器,攻击者可选的方法有很多,但最简单的方法是让用户的系统访问攻击者控制下的域名。为此,可以通过恶意软件或社会工程来实现。
解决这个安全威胁最有效的方法就是修复系统中的潜在漏洞。今年7月,我们首先发现了这个漏洞,并在同月通过“零日计划”(ZDI)向相应的供应商提交了报告。在今年10月,有位独立研究人员也发现了这个漏洞,并将其报告给了Canonical。在10月底,补丁被推广到各种Linux发行版,如Ubuntu等。幸运的是,目前还没有发现针对这个漏洞的在野攻击。
漏洞分析
随着时间的推移,新的功能被不断加入到DNS中,其中有些是用于增加新特性的,同时有些是为了提高其安全性的。例如,DNS安全扩展(DNSSEC)中添加了一种新类型的资源记录,即NSEC(Next Secure)记录(具体定义请参考RFC 4034)。
该漏洞出现在处理表示NSEC位图中的伪类型的相关位的过程中。下图显示了相应的代码段和堆栈帧。其中,高亮显示的"continue"行表明“while循环”从此进入了无限循环。dns_packet_read_type_window()的具体实现位于文件resolved-dns-packet.c中。
图1 无限循环的源代码和堆栈帧
请注意,当记录类型为DNS_TYPE_NSEC时,将从dns_packet_read_rr()中调用上面的dns_packet_read_type_window()函数。下图展示了resolve-dns-packet.c文件中与dns_packet_read_rr()函数相关的代码。
图2.读取DNS数据包的源代码
POC代码
为了测试这个漏洞,我们创建了一个定制的DNS服务器,它将返回精心制作的“恶意”响应。这个响应包含了一个旨在触发这个漏洞的NSEC记录,具体如下所示:
图3 精心制作的DNS响应的数据包
一旦运行systemd的系统使用它来进行DNS解析,就会收到这个精心制作的DNS数据包,这时,系统CPU的利用率将蹿升至100%,具体如下所示:
图4 被撑爆的CPU利用率
缓解措施
正如我们前面提到的,修复该漏洞的安全补丁已经发布。我们建议,尽快给存在这种安全风险的系统打上相应的补丁。
系统管理员也可以选择手动阻止潜在的恶意数据包。具体来说,检查传入的DNS响应是否包含RFC 4034第4节中规定的资源记录。
监视传入的DNS响应流量,并检测应答部分中的DNS RR是否包含(定义NSEC RR的)RFC 4034第4节中规定的DNS和类型记录。如果附加的位图被处理并且包含伪类型,则应该加以拒绝。