DNS Server远程代码执行漏洞分析-SIGRed(CVE-2020-1350)( 六 )


WinDNS的堆管理器
WinDNS使用Mem_nualloc函数动态分配内存 。 此函数管理自己的内存池 , 以用作高效缓存 。 对于不同的分配大小 , 有4个内存池(0x50、0x68、0x88、0xA0) 。 如果请求的分配大小大于0xA0字节 , 则默认为HeapAlloc , 它使用本地Windows堆 。 堆管理器为内存池header分配额外的0x10字节 , 其中包含元数据 , 包括缓冲区的类型(已分配/空闲)、指向下一个可用内存块的指针、用于调试检查的cookie等 。 堆管理器以单链表的方式实现它的分配列表 , 这意味着块的分配顺序与它们被释放的顺序相反(LIFO) 。
Write-What-Where
为了实现“Write-What-Where”原语 , 我们通过破坏chunk的header(元数据)来攻击WinDNS堆管理器 , 实际上就是破坏freelist 。
在freelist被破坏后 , 下次我们尝试分配大小合适的任何内容时 , 内存分配器都会为我们分配我们选择的内存区域作为”Malloc-Where”原语 。
为了绕过CFG , 我们希望该内存区域位于堆栈上 , 由于信息泄漏 , 我们希望知道它的位置 。 一旦我们在堆栈上有了写能力 , 我们就可以将返回地址改写为我们想要执行的地址 , 有效地劫持执行流程 。
必须指出的是 , 默认情况下 , DNS服务在前3次崩溃时重新启动 , 这增加了成功利用的机会 。
总结
这个高度的漏洞已经被微软承认 , 并为其分配CVE-2020-1350 。
我们相信这个漏洞被利用的可能性是很高的 , 因为我们在内部找到了利用这个漏洞所需的所有原语 。 由于时间限制 , 我们没有继续利用这个漏洞 , 但是我们相信其他的攻击者能够利用它 。 成功利用此漏洞将产生严重影响 , 因为通常可以找到未修补的Windows域环境 , 尤其是域控制器 。 此外 , 甚至一些互联网服务提供商(ISP)可能将其公共DNS服务器设置为WinDNS 。
我们建议用户修补受影响的Windows DNS服务器 , 以防止利用此漏洞 。
作为临时的解决方法 , 在打补丁之前 , 建议将DNS消息(通过TCP)的最大长度设置为0xFF00 , 这样可以消除此漏洞 。 您可以通过执行以下命令来实现:
reg add ''HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesDNSParameters'' /v ''TcpReceivePacketSize'' /t REG_DWORD /d 0xFF00 /f net stop DNS && net start DNS披露时间表

  • 2020年5月19日 – 向Microsoft提交的初步报告 。
  • 2020年6月18日 – Microsoft发布了此漏洞的CVE-2020-1350 。
  • 2020年7月9日 – Microsoft承认该问题是一个可修复的严重漏洞 , CVSS评分为10.0 。
  • 2020年7月14日 – Microsoft发布了补丁 。
参考资料
  • https://en.wikipedia.org/wiki/Domain_Name_System
  • https://blog.skullsecurity.org/2011/a-deeper-look-at-ms11-058
  • https://know.bishopfox.com/blog/2017/10/a-bug-has-no-name-multiple-heap-buffer-overflows-in-the-windows-dns-client
  • https://powerdns.org/hello-dns/basic.md.html
  • https://www.cloudflare.com/learning/dns/what-is-dns/
  • https://tools.ietf.org/html/rfc7766
  • https://tools.ietf.org/html/rfc5966
  • https://tools.ietf.org/html/rfc2535
非常感谢我的同事Eyal Itkin(@EyalItkin)和Omri Herscovici(@omriher)在这项研究中的帮助 。
本文翻译自 research.checkpoint.com ,原文链接。 如若转载请注明出处 。


推荐阅读