dns.exe 为一个 SYSTEN 权限的系统服务,该文件只存在于开启 DNS 功能的 Windows Server 服务器上。据 CheckPoint 的描述只有当 Windows Server 上的 DNS 服务接收到类型为 SIG/RRSIG 的 DNS 响应包时,才能进入到可以触发此漏洞的 SigWireRead 函数内。
DNS 服务器收到响应包?DNS 服务器不应该是回复客户端的查询而发送响应包嘛,话虽如此,但如果将 DNS 服务器也当成一个客户端,不就可以发送查询请求并接收响应数据了呀,而 DNS 转发 恰好能够让 DNS 服务器充当客户端,向上级的 DNS 服务器发起查询。
所以该漏洞触发的前提条件是:通过 DNS 转发接收一条 SIG/RRSIG 类型的 DNS 响应包。
DNS 整体结构包括头部区域、查询区域、响应区域、认证区域和附加区域,后面两个暂时用不上,不赘述。结构图如下:
DNS 头部区域固定 12 字节,同一个查询和响应的 ID 是一样的,QR 指明当前是查询还是响应,OPCODE 指明是用标准查询还是反向查询,TC 表示 UDP 长度大于 512 时截断并用 TCP 再次请求(漏洞关键因素),QDCOUNT 表示查询的数量,ANCOUNT 表示响应的数量,结构图如下:
DNS 查询区域主要由欲查询的域名、查询类型和查询类组成,其中最最最重要的是域名不是普通的字符串,而是多个 length + string 的形式,结尾以 length=0 为标志,结构图如下:
DNS 响应区域由资源记录的域名,RDATA 的类型、RDATA 类、TTL 值、RDATA 长度和 RDATA 组成,结构图如下:
必须强调下 DNS 中域名的表示方式:(length + string) * n,这种表示方式是该漏洞成因的关键因素之一:
资源记录(RR)有多种类型,比如说最常用的 A 类型返回的是 IPv4 地址记录。而 dns!SigWireRead 只有在读取 SIG 类型响应包时才有机会触发 CVE-2020-1350 漏洞。SIG 资源记录的结构图如下:
简单说下各个字段的含义:
域名压缩是 DNS 协议节省空间的一种方式,因为请求中的域名字符会频繁出现在响应包的内,故采用了一种标志+偏移的格式来压缩域名。压缩方式很简单:1 + 1 + offset,即最高 2bit 位为 1 时代表了将采用域名压缩,剩余的组合为偏移值(基地址为 DNS 头),如下图:
响应区域中的 Name 字段为 0xc00c,明显是被压缩过的,最高 2bit 位是标志,剩余的 bit 位组合得到的值为 0xc,所以当前 Name 表示的字符串在 DNS 头部向后偏移 0xc 的位置,也就是图中 0x3 开始(0x50 表示 DNS 头起始位置)的域名 bbs.pediy.com。