云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

轻量服务器_鸵鸟cdn_速度快

小七 141 0

DNS漏洞的故事:CVE-2015-7547

这篇文章是由Marek Vavruša和Jaime Cochran撰写的,他们在上周二凌晨3点发现他们都在独立处理相同的glibc漏洞攻击向量。GNU libc DNS存根解析程序代码中的缓冲区溢出错误上周被宣布为CVE-2015-7547。虽然它还没有任何昵称(去年的Ghost更吸引人),但它可能会带来灾难性的后果,因为它会影响到任何一个使用gnulibc cpe、负载平衡器、服务器和个人电脑的平台。最大的问题是:它在现实世界中有多大的可利用性?事实证明,唯一有效的缓解措施就是修补。请立即修补您的系统,然后回来阅读这篇博文,了解为什么试图通过限制DNS响应大小来减轻此攻击无效。但首先,帕奇!路径攻击者让我们从Google的PoC开始,它使用漏洞公告中描述的第一个攻击向量。首先,2048字节的UDP响应强制缓冲区分配,然后失败响应强制重试,最后两个答案将破坏堆栈。$echo"nameserver 127.0.0.1"| sudo tee/etc/决议.conf$sudo蟒蛇poc.py公司&$valgrind卷曲==17897==大小1的读取无效==17897==在0x59F9C55:\u libc_res_nquery(res_query.c:264)==17897==by 0x59FA20F:\u libc_res_nquerydomain(res_query.c:591)==17897==by 0x59FA7A8:\u libc_res_nsearch(res_query.c:381)==17897==by 0x57EEAAA:\u nss_dns_gethostbyname4\r(dns主机。c:315)==17897==0x424242424241:???==17897==地址0x424242424245不是堆栈、malloc或(最近)空闲的分段故障这个概念证明要求攻击者直接或通过一个简单的转发器与glibc存根解析程序代码对话。这种情况发生在您的DNS流量被截获或使用不受信任的网络时。公告中建议的缓解措施之一是将UDP响应大小限制为2048字节,对于TCP则为1024字节。严格地说,限制UDP是完全无效的,只会强制合法查询通过TCP重试。限制TCP应答是一种明显的违反协议的行为,它会破坏合法的应答:$dig@b.gtld-服务器.net+tcp+dnssec NS根目录-服务器.net|grep"消息大小";;接收邮件大小:1254不管怎样,让我们看看响应大小裁剪是否有效。在计算大小限制时,我们必须考虑IP4头(20个八位字节),以及UDP报头开销(8个八位字节),从而导致允许的最大数据报大小为2076个八位字节。DNS/TCP可能会因为争论而变得支离破碎,让我们一起放弃DNS/TCP。$sudo iptables-I输入-p udp--sport 53-m长度--2077:65535-j DROP$sudo iptables-I输入-p tcp--sport 53-j丢弃$valgrind卷曲:(6)无法解析主机:foo.bar.google.com网站看来我们已经减轻了第一次攻击的方法,尽管有附带的损害。但是,只有UDP的概念证明呢?$echo"nameserver 127.0.0.10"| sudo tee/etc/决议.conf$sudo python poc-尤多妮.py&$valgrind卷曲==18293==Syscall参数socketcall.recvfrom(buf)指向不可寻址字节==18293==在0x4F1E8C3:u recvfrom_nocancel(syscall template.S:81)==18293==by 0x59FBFD0:发送dg(res_send.c:1259)==18293==由0x59FBFD0:\u libc_res_nsend(res_send.c:557)==18293==by 0x59F9C0B:\u libc_res_nquery(res_query.c:227)==18293==by 0x59FA20F:u libc_res_nquerydomain(res_query.c:591)==18293==by 0x59FA7A8:\u libc_res_nsearch(res_query.c:381)==18293==by 0x57EEAAA:\u nss_dns_gethostbyname4\r(dns主机。c:315)==18293==0x4F08AA0:gaih_inet(getaddrinfo.c:862)==18293==by 0x4F0AC4C:getaddrinfo(getaddrinfo.c:2418)==18293==地址0xfff001000不是堆栈、malloc或(最近)空闲的***"curl"中出错:double free或corruption(out):0x00007fe7331b2e00***中止虽然不可能以2048udp响应大小发送整个攻击有效负载,但这仍然会导致内存损坏。当公告建议阻止大于2048字节的DNS UDP响应作为一种可行的缓解措施时,它迷惑了很多人,包括其他DNS供应商和我们自己。这和下面的概念证明表明,如果这些规则保持启用状态,不仅是徒劳的,而且从长远来看是有害的。到目前为止,所提出的攻击需要一个MitM场景,即攻击者直接与glibc解析器对话。一个"足够好"的缓解措施是运行本地缓存解析器,将glibc代码与攻击者隔离开来。事实上,这样做不仅可以通过本地缓存提高Internet性能,而且可以防止过去和将来可能出现的安全漏洞。缓存存根解析程序真的足够好吗?不幸的是,没有。只有dnsmasq这样的本地存根解析程序不足以化解这种攻击。它很容易遍历,因为它不擦洗上游的答案,让我们看看攻击是否经过修改的概念证明,只使用格式正确的答案和零生存时间(TTL)进行缓存遍历。$echo"nameserver 127.0.0.1"| sudo tee/etc/决议.conf$sudo dnsmasq-d-a 127.0.0.1-R-S 127.0.0.10-z&巨蟒-dnsmasq.py公司&$valgrind卷曲==20866==大小1的读取无效==20866==在0x8617C55:\u libc_res_nquery(res_query.c:264)==20866==by 0x861820F:\u libc_res_nquerydomain(res_query.c:591)==20866==by 0x86187A8:\u libc_res_nsearch(res_query.c:381)==20866==0xA0C6AAA:\u nss_dns_gethostbyname4\r(dns主机。c:315)==20866==0x1C000CC04D4D4C:???被杀死的现在最大的问题是,我们已经看到了MitM攻击的缓解策略是有效的,我们能通过缓存DNS解析器利用这个漏洞吗?非路径攻击场景让我们从攻击的第一阶段开始—兼容的解析器永远不会通过UDP向不支持EDNS0的客户端发出大于512字节的响应。由于glibc解析器在默认情况下不会这样做,我们必须升级到TCP并在那里执行整个攻击。另外,客户机应该至少有两个名称服务器,否则会使成功的攻击复杂化。$echo"nameserver 127.0.0.1"| sudo tee/etc/决议.conf$echo"nameserver 127.0.0.1"| sudo tee-a/etc/决议.conf$sudo iptables-F输入$sudo iptables-I输入-p udp--sport 53-m长度--2077:65535-j DROP让我们用一个合并了DNS代理和攻击者的概念证明来尝试。本地主机上的DNS代理将通过UDP向攻击者询问这两个查询,并且攻击者用TC标志响应,以强制客户端通过TCP重试。攻击者以2049字节或更长的TCP响应响应响应一次,然后强制代理关闭与glibc解析程序代码的TCP连接。这是一个关键的步骤,没有可靠的方法来实现这一点。攻击者发回一个完整的攻击有效负载,代理将其愉快地转发给glibc解析器客户端。$sudo python poc-tcponly.py&$valgrind卷曲==18497==大小1的读取无效==18497==在0x59F9C55:\u libc_res_nquery(res_query.c:264)==18497==by 0x59FA20F:\u libc_res_nquerydomain(res_query.c:591)==18497==by 0x59FA7A8:\u libc_res_nsearch(res_query.c:381)==18497==by 0x57EEAAA:\u nss_dns_gethostbyname4\r(dns主机。c:315)==18497==0x1C000CC04D4D4D4C:???==18497==地址0x10000000000103不是堆栈、malloc或(最近)空闲的被杀死的在真正的解析器上执行攻击在现实世界中,非MitM缓存解析器攻击的关键是间接控制解析器与客户端之间的消息。我们得出的结论是,djbdns的dnscache是尝试演示实际缓存遍历的最佳目标。为了抵御像slowloris这样的DoS攻击向量,slowloris会同时建立大量的TCP连接,并使它们保持开放状态以阻塞服务,DNS解析程序有一个有限的并行TCP连接池。这通常是通过限制这些并行TCP连接并关闭最旧或最近最不活跃的连接来实现的。例如,djbdns(dnscache)最多可容纳20个并行TCP连接,然后从最旧的一个开始丢弃它们。知道了这一点,我们意识到我们能够轻松地终止TCP连接。因此,一个安全修复成为另一个bug的宝藏。为了利用此漏洞,攻击者可以发送一个截断的UDP a+AAAA查询,这将触发必要的TCP重试。攻击者使用TTL为0的有效答案进行响应,dnscache向glibc客户端发送一个截断的UDP响应。此时,glibc函数send_vc()在TCP上使用dnscache重试,由于前一个答案的TTL为0,dnscache再次向攻击者的服务器请求A+AAAA查询。攻击者以大于2000的答案响应A查询,从而导致glibc的缓冲区管理不当,然后dnscache将其转发给客户端。现在,攻击者可以在其他客户端发出完全合法的请求时等待AAAA查询,或者改为建立20个TCP连接回dnscache,直到dnscache终止攻击者的连接。现在,我们已经满足了触发另一次重试的所有条件,攻击者将发回任何有效的A响应和一个有效的、超大的AAAA(以CNAME或AAAA-RDATA格式),dnscache将此返回给客户端,从而触发溢出。这似乎是一个复杂的过程,但实际上并非如此。让我们看看我们的概念证明:$echo"nameserver 127.0.0.1"| sudo tee/etc/决议.conf$echo"nameserver 127.0.0.1"| sudo tee-a/etc/决议.conf$sudo python poc-dnscache.py[TCP]发送第一个大答案,TTL=0[TCP]发送第二个大答案,TTL=0[TCP]准备回答>2k的攻击[TCP]连接回调用者以强制其关闭原始连接('127.0.0.1',53)[TCP]原始连接已终止,希望看到重新查询。。。[TCP]在[TCP]发送AAAA中的攻击负载客户:$valgrind卷曲https://www.cloudflare.com/==6025==进程以默认操作终止