CVE-2020-1350--SigRedDNS漏洞详解与复现

漏洞简介


在Windows上,DNS服务器是域控制器,其管理员是Domain Admins组的一部分。默认情况下,Domain Admins组是已加入域的所有计算机上Administrators组的成员,包括域控制器[8]。如果利用得当,攻击者可以在易受攻击的系统上远程执行代码,并获得Domain Admin权限,从而有效地损害了整个公司的基础架构。

DNS服务器-dns.exe负责在安装了DNS角色的Windows服务器上回答DNS查询。


CVE-2020-1350是DNS.exe在处理畸形DNS Sig消息时,由于对数据包的字段校验不严格,导致了整型溢出。DNS SIG 消息中包含对DNS记录集合的数字签名,DNS记录集合就是一种名字相同,或者类型相同的DNS消息集合。


漏洞类型:整数溢出导致基于堆的缓冲区溢出


攻击流程


aa91b3_adb7b85135e44f38bcca549851f38d68_mv2


攻击者可以配置一个恶意的域名evildomain.com,该域名的DNS指向的DNS服务器作为本次攻击的目标。


  1. 当客户端查询evildomain.com的DNS记录;
  2. 目标DNS服务器向根域名服务器查询evildomain.com的NS记录;
  3. 根域名服务器告诉目标DNS,evildomain.com的权威DNS服务器是3.3.3.3,并该记录缓存起来;
  4. 客户端向目标服务器查询evildomain.com的Sig记录;
  5. 目标服务器将请求转发给权威DNS服务器;
  6. 权威DNS服务器返回畸形Sig查询结果;

目标DNS服务器处理SigQuery的畸形消息时,将此消息缓存到自己的记录中,触发漏洞。


漏洞函数

简言之就是整数溢出后导致堆溢出,将该漏洞抽象为以下模型:

void Examples(char *in){  
    unsigned short len_p1 = len ( in.p1);  unsigned short len_p2  =len ( in.p2);
    unsigned short len_p  = len_p1 + len_p2;  
    char * buf = (char *)malloc(len_p);  
    memcpy(buf, in.p1, len_p1); }

问题就出在 len_p 的计算上,假设 len_p1 = 0xFFD0,len_p2 = 0x40,相加后高位数据被丢弃,那么 0xFFD0 + 0x40 = 0x10010 = 0x10,所以实际分配的内存是 0x10 而不是 0x10010,而之后往 0x10 的空间内拷贝 0xFFD0 长度的数据,自然造成了内存溢出。


而在dns.exe!SigWireRead函数里面也有类似的溢出漏洞,如图所示第11行:

aa91b3_ffb865d47c0b4f54925b8c2acb34b036_mv2

漏洞成因如下:ushort类型,为无符号16位类型。RR_AllocateEx 分配的大小只有16个bit,大小为0~65535,所以只要构造size 大于65535,造成整数溢出,而系统就会分配一个比实际数据量小的堆块,进而造成堆溢出,将整数溢出转化成堆溢出漏洞。


漏洞利用:

因此,触发此漏洞所需的全部操作就是让受攻击的DNS服务器向我们查询SIG记录,并使用长签名(长度&>=64KB)对其作出SIG响应。但是,UDP上的DNS的大小限制为512字节(如果服务器支持EDNS0,则为4096字节)。在任何情况下,这都不足以触发漏洞。


CheckPoint 找到一种方法可以突破上述限制:UDP 响应时将 DNS 头部的 TC 标志置 1,表示被截断,之后客户端便会尝试用 TCP 协议和服务器建立连接,并通过 TCP 协议传递数据。由于消息的前两个字节表示其长度,因此TCP上的DNS中消息的最大大小表示为16位,因此限制为64KB。TCP 协议在 53 端口上可传输长度最大为 65535 的 DNS 数据,这无疑给该漏洞创造了先决条件。如下图:红框中的表示TC置位字段:

image-20210524201342778


但是,即使是长度为65,535的消息也不足以触发漏洞,因为消息长度包括报头和原始查询。计算传递给RR_AllocateEx的大小时不考虑此开销。那么,该漏洞如何触发呢?继续往下看,首先了解一下域名编码和域名压缩。


域名编码

eg:对于完整的一个域名www.baidu.com,需要14个字节:

\3 w w w \5 b a i d u \3 c o m

[img]

可以看到第一个字节 是3,表示之后会有3个字节的字符。


域名压缩

域名压缩是 DNS 协议节省空间的一种方式,因为请求中的域名字符会频繁出现在响应包的内,故采用了一种标志+偏移的格式来压缩域名。压缩方式很简单:1 + 1 + offset,即最高 2bit 位为 1 时代表了将采用域名压缩,剩余的组合为偏移值(基地址为 DNS 头),如下图:响应区域中的 Name 字段为 0xc00c,明显是被压缩过的,最高 2bit 位是标志,剩余的 bit 位组合得到的值为 0xc,所以当前 Name 表示的字符串在 DNS 头部向后偏移 0xc 的位置,也就是图中红框中 0x3 开始(0x50 表示 DNS 头起始位置)的域名 bbs.pediy.com

879291_BK62PXN5P34V87F (1)


因此,可以将域名压缩的偏移值指向一片可控的区域,而不是指向查询时域名,就完全有可能使得域名的长度大大增加,比如在这里修改为c0 0d,那么表示域名从0x62开始,说明后面有0x62个字节的字符,然后依次。这样就使得源代码第11行中的 sigName.Length 的大小变大。


注意:DNS name长度最大为0XFF


所以,可以在不改变原来数据包大小的情况下,将sigLength+sigName.length+0x16 的大小,大于65535,造成整数溢出。分配一个小的空间缓存,然后导致堆溢出。


POC分析和漏洞复现


部分poc代码,大体就是构造sig响应消息。具体POC,在这里:https://github.com/maxpl0it/CVE-2020-1350-DoS

image-20210524204424343


实验环境:

Windows Server 2012 R2 192.168.29.138

KaLi Linux 192.168.29.135

复现过程:

1.在windows server 2008 安装dns服务器,并配置静态ip

2.在kali 中运行脚本,开启ibrokethe.net 域名的恶意服务器,这里的ibrokethe.net 表示恶意域名,也可以代替为其他域名。

sudo python sigred_dos.py ibrokethe.net 

3.在受害者服务器配置转发器,转发器ip为kali 机的ip。

image-20210525165703551

4.在受害者服务器使用nslookup命令查询9.ibrokethe.net:

nslookup -type=sig 9.ibrokethe.net 127.0.0.1

5.查看kali,发现会发现收到了一个UDP连接,又收到了一个TCP连接。

image-20210525165901274

最后要说的是,复现过程采用了Windows DNS服务器的条件转发器,略过了向权威NS查询的步骤,直接向恶意DNS服务器发出查询。

复现结果:

抓包结果如下:

image-20210524205603806

由于本地无法解析“ibrokethe.net”,因此会以UDP协议向恶意服务器kali发送DNS查询,也就是kali收到的第一个UDP连接。恶意服务器查到了该域名,就向受害者发送响应包,设置TC位,通知受害者采用TCP重发原来的查询请求,并允许返回的响应报文超过512个字节。这是第二个DNS包。然后进行三次握手,受害者再次以TCP协议发送请求,这就是kali收到的TCP连接。之后,恶意服务器就可以利用TCP传输大于64KB的响应包发给受害者,触发漏洞,造成堆溢出。

然后,就可以进行远程代码执行等操作了。


可以看到在复现的过程,产生堆溢出,dns.exe进程发生崩溃,从而产生DOS攻击。如下图:

879291_P2ZBQGC4C59M8U6


漏洞修复

临时修复方案

修改注册表,限制tcp包的长度,TcpReceivePacketSize的值为0xFF00

 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters 
  DWORD = TcpReceivePacketSize 
  Value = 0xFF00

注意:必须重新启动 DNS 服务才能生效。


补丁更新

17

可看到右图24行,在前面对整数溢出做了个判断,即sigLength+sigName.Length的值要大于等于sigLength

总结:

协议方面多多少少都会有我们所疏忽的问题,对于dns.exe开发者,最开始并未考虑到最大可以超过65535,造成溢出,代码并没有问题,造成该漏洞的关键点,主要是因为域名压缩。往往很多个疏忽点,凑到了一起就成了攻击者利用的漏洞。



参考链接:

CVE-2020-1350 Windows Server DNS漏洞复现

漏洞利用剖析:带有CVE-2020-1350 SIGRed的RCE

CVE-2020-1350: Windows DNS Server蠕虫级远程代码执行漏洞分析
Windows DNS server从cve-2020-1350到内存泄露

posted @ 2021-05-24 21:08  PsgQ  阅读(2460)  评论(0编辑  收藏  举报