# 漏洞简介

在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消息集合。

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

# 攻击流程


攻击者可以配置一个恶意的域名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的畸形消息时,将此消息缓存到自己的记录中,触发漏洞。

# 漏洞函数
简言之就是整数溢出后导致堆溢出,将该漏洞抽象为以下模型:
```c
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行:
漏洞成因如下: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置位字段:

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

## 域名编码
eg:对于完整的一个域名www.baidu.com,需要14个字节:
可以看到第一个字节 是3,表示之后会有3个字节的字符。

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

因此,可以将域名压缩的偏移值指向一片可控的区域,而不是指向查询时域名,就完全有可能使得域名的长度大大增加,比如在这里修改为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

## 实验环境:
Windows Server 2008 R2 sp1 和 kali linux
## 复现过程:
1.在windows server 2008 安装dns服务器,并配置静态ip
2.在kali 中运行脚本sudo python sigred_dos.py evil_domain_name
3.在受害者服务器配置转发器,转发器ip为kali 机的ip。
4.在受害者服务器使用nslookup命令查询9.evil_domain_name:
```shell
nslookup -type=sig 9.ibrokethe.net 127.0.0.1
```
5.查看kali,发现会发现收到了一个UDP连接,又收到了一个TCP连接。

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

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

# 漏洞修复
临时修复方案,修改注册表,限制tcp包的长度,TcpReceivePacketSize的值为0xFF00
```shell
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DNS\Parameters
DWORD = TcpReceivePacketSize
Value = 0xFF00
```
注意:必须重新启动 DNS 服务才能生效。

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


# 参考链接:
CVE-2020-1350 Windows Server DNS漏洞复现
漏洞利用剖析:带有CVE-2020-1350 SIGRed的RCE
CVE-2020-1350: Windows DNS Server蠕虫级远程代码执行漏洞分析

CVE-2020-1350 详解与复现的更多相关文章

  1. SENet详解及Keras复现代码

    转: SENet详解及Keras复现代码 论文地址:https://arxiv.org/pdf/1709.01507.pdf 代码地址:https://github.com/hujie-frank/S ...

  2. IntelliJ IDEA 2020.1.1 x64 Debug 断点调试模式详解

    前言 对于初入职场的萌新们来说,很多都还不会 Debug 断点模式.记得我刚写代码的时候,也是通过 System.out.println() 一行一行的把变量打印出来看.其实强大的编辑器已经帮我们做好 ...

  3. 2020你还不会Java8新特性?方法引用详解及Stream 流介绍和操作方式详解(三)

    方法引用详解 方法引用: method reference 方法引用实际上是Lambda表达式的一种语法糖 我们可以将方法引用看作是一个「函数指针」,function pointer 方法引用共分为4 ...

  4. 2020了你还不会Java8新特性?(五)收集器比较器用法详解及源码剖析

    收集器用法详解与多级分组和分区 为什么在collectors类中定义一个静态内部类? static class CollectorImpl<T, A, R> implements Coll ...

  5. MVC图片上传详解 IIS (安装SSL证书后) 实现 HTTP 自动跳转到 HTTPS C#中Enum用法小结 表达式目录树 “村长”教你测试用例 引用provinces.js的三级联动

    MVC图片上传详解   MVC图片上传--控制器方法 新建一个控制器命名为File,定义一个Img方法 [HttpPost]public ActionResult Img(HttpPostedFile ...

  6. linux查看端口及端口详解

    今天现场查看了TCP端口的占用情况,如下图   红色部分是IP,现场那边问我是不是我的程序占用了tcp的链接,,我远程登陆现场查看了一下,这种类型的tcp链接占用了400多个,,后边查了一下资料,说E ...

  7. cron表达式详解

    @Scheduled(cron = "* * * * * *") cron表达式详解 1.cron表达式格式: {秒数} {分钟} {小时} {日期} {月份} {星期} {年份( ...

  8. VSFTPD全攻略(/etc/vsftpd/vsftpd.conf文件详解)

    /etc/vsftpd/vsftpd.conf文件详解,分好类,方便大家查找与学习 #################匿名权限控制############### anonymous_enable=YE ...

  9. CNN详解

    CNN详解 版权声明:本文为博主原创文章,转载请指明转载地址 http://www.cnblogs.com/fydeblog/p/7450413.html 前言 这篇博客主要就是卷积神经网络(CNN) ...

随机推荐

  1. Python数据分析入门(十):数据清洗和准备

    数据清洗是数据分析关键的一步,直接影响之后的处理工作 数据需要修改吗?有什么需要修改的吗?数据应该怎么调整才能适用于接下来的分析和挖掘? 是一个迭代的过程,实际项目中可能需要不止一次地执行这些清洗操作 ...

  2. [矩阵乘法]裴波拉契数列II

    [ 矩 阵 乘 法 ] 裴 波 拉 契 数 列 I I [矩阵乘法]裴波拉契数列II [矩阵乘法]裴波拉契数列II Description 形如 1 1 2 3 5 8 13 21 34 55 89 ...

  3. (原创)高DPI适配经验系列:(二)按DPI范围适配

    一.前言 一个软件,往往会用到位图资源,比如图标.图片.水晶按钮等. 在使用了位图资源后,就不能对任意DPI都进行适配,因为这样适配的代价太大了. 像Win10的缩放比例可以由100%-500%,如果 ...

  4. leetcode 783 二叉搜索树节点最小距离

    PS:(感觉这题名字和内容有歧义) 要求得到任意不同节点值之间的最小差值. 本身二叉树是有序的,又找最小差值,其实就是相当于在一个有序数组中找到每相邻两数之间最小差值. 朴素思想: 中序遍历树,把值都 ...

  5. OOUML系列总结及终章回顾

    盼望着,盼望着,OO课程终于结束了,但是,此刻的我却感到一丝失落,甚至想着再来一单元岂不妙哉? 目录 总结本单元三次作业架构 四个单元中架构设计及OO方法理解的演进 四个单元中测试理解与实践的演进 课 ...

  6. JDBC_11_PreparedStatement(增删改操作)

    PreparedStatement(增删改操作) * 代码: ``` import javax.swing.plaf.nimbus.State; import java.sql.*; public c ...

  7. 读取ini配置文件 及 UI对象库

    读取ini配置文件 配置项 读取API 写入API 实战:UI 对象库 读取ini配置文件 配置项 在每个 ini 配置文件中,配置数据会被分组(比如下述配置文件中的"config" ...

  8. 1061 Dating

    Sherlock Holmes received a note with some strange strings: Let's date! 3485djDkxh4hhGE 2984akDfkkkkg ...

  9. 805. Split Array With Same Average

    In a given integer array A, we must move every element of A to either list B or list C. (B and C ini ...

  10. Unittest单元测试框架——BeautifulReport测试报告和Yagmail自动发送邮件

    一.前言 之前在做appium自动化的时候,已经提到过unittest框架的基本概念.用例执行,以及BeautifulReport测试报告的简单使用了(地址:https://www.cnblogs.c ...