域名系统(Domain Name System,DNS)是互联网的一项基础服务,默认端口53,可以实现域名和IP地址的相互映射,其数据库分散在全球多地。
DNS默认使用UDP协议通信,但是由于UDP的报文长度限制为512字节,当DNS请求超过此长度时会自动使用TCP协议发起请求。
DNS(或者说域名)是划分层次的,它有根域(Root Doamin)、顶级域(Top Level Domain,TLD)、二级域(Second Level Domain,SLD)等级别,如下图以www.baidu.com介绍其层级,其中根域是一个点,只是默认情况下都不再输入了。通常我们说全球有13台根域名服务器,实际上是有13个根域名服务器地址,服务器数量有1000+,采用任播技术实现负载均衡。
比如访问:https://www.qq.com. ,但是有些域名后面加点是不行的,应该是服务端做了限制,比如https://www.baidu.com.
DNS 中,常见的资源记录类型有:
域名解析是有顺序的,一般首先通过host 文件的静态解析,然后通过DNS 服务器的动态解析,静态解析的优先级高于动态解析。
解析的过程分为以下几步:
注:本地DNS服务器也可以说成递归解析器(Resolver),后面的根域、顶级域、二级域DNS服务器也可以统一说成权威域名服务器(Authoritative Name Server)。
DNS劫持漏洞通常是由废弃的DNS记录造成的,废弃DNS 记录是指一个DNS指向的资源已经被释放掉了,但解析仍然存在,若其指向的资源可被第三方获取,则存在劫持风险。常见的几种解析记录类型都存在此风险,比如A、CNAME、MX、NS等,但其实有些场景很难利用,比如A记录的劫持需要能够获得目标站点的IP,这个是非常困难的。
比较常见的劫持是CNAME 记录劫持或 NS记录劫持,以NS记录劫持为例,在2020年CCS顶会的一篇文章《Zombie Awakening: Stealthy Hijacking of Active Domains through DNS Hosting Referral》中提出了一种僵尸激活攻击(Zombie Awakening),其利用条件有两点:
漏洞场景如上图(其过程忽略了根域)所示,其过程是一个请求example.com 域名的DNS 解析过程,在ns.example.com 的二级域DNS服务器中存储了example.com 的NS记录和A记录。其中如下这条NS记录
example.com NS ns.provider.com
虽然仍然存在,但ns.provider.com 的服务提供商已经删除了此项配置(比如用户已经不在使用provider.com 的服务了)。此时,上面那条NS 记录就可以称之为僵尸记录或失效记录。
漏洞利用过程就是如上图所示,分为以下几个步骤:
攻击者在第三方DNS 托管服务商(provider.com)添加此域名:example.com(1),并配置两个解析记录(2)
example.com NS ns.provider.com
example.com A IPattacker
然后刻意的发起大量NS解析请求(3),当本地DNS服务器没有此记录时会向顶级域服务器发起请求(4),顶级域服务器返回一个NS记录(5)
example.com NS ns.example.com
本地DNS服务器根据NS 记录进一步向二级域(ns.example.com)发起请求(6),此时本地DNS服务器会收到一个A记录和两条NS记录并缓存下来(7),在这个例子中此前从顶级域获得的NS记录会被从二级域获得的相同的记录替换掉,因为二级域比顶级域具有更高的优先级(8)。
然后攻击者向本地DNS服务器发起大量A记录解析请求(9),此时服务器中缓存了两个NS记录,一个真实的和一个废弃的,如果是随机选择的(10),则会有50%的机会返回攻击者的IP,那么那条废弃的解析路径就相当于被激活了(11)。而且这条A记录还会被缓存在递归解析服务器中,直到过期。攻击者可以尝试访问这个域名来判断攻击是否有效(13),若能够访问恶意IP则说明成功(14)。
使用我自己的万网域名和某第三方的DNS托管服务,在原有万网DNS的基础上添加第三方的DNS地址。
NS记录成功解析后如下图所示
使用第三方DNS也可以返回正确的A记录
然后在第三方DNS服务商删除此域名,可以看到已无法获取A记录
然后使用另外一个第三方DNS服务商的账户添加域名并设置恶意的解析(A记录为127.0.0.1),然后使用dig命令指定外部DNS 服务器进行测试(本地的应该有了正确IP地址的缓存,可能无法复现)。如下图所示,使用不同的DNS 服务器,有几率返回不同的结果,其中就有恶意A记录。
此类漏洞关键在于域名管理员要合理配置的域名解析记录,不再使用的要及时下掉!
DNS 拒绝服务比较常见的可能是利用DNS Flood,做流量放大攻击其他服务器,但本质不是DNS的漏洞。这里介绍一种最新的针对DNS 的拒绝服务攻击–NXNSAttack,是发表在2020年安全顶会USENIX上最新的一篇研究成果《NXNSAttack: Recursive DNS Inefficiencies and Vulnerabilities》。该文章提出一种新型的DNS 放大攻击,利用DNS 对NS记录完全解析的特性,可以实现多倍的流量放大,对DNS 服务器造成拒绝服务。
在1.5 节或者2.1 节我们可以看到一个完整的理论上的DNS解析过程,但实际上一个递归解析器与DNS服务器(顶级域、二级域等)的通信要远多于上图所示次数。一个真实DNS请求的如下图所示,当递归解析器向顶级域发起请求时(1)会得到一个NS 记录列表(2),然后会向每个NS记录发起请求(3-6),每个NS地址会返回对应的A记录和NS记录(7-10),此时递归解析器已经获取到了二级域的NS服务器IP地址,但同时也收到对应的NS记录,由于DNS解析的特性(会对NS记录进行完全的解析,即只要收到NS的响应就会发起NS请求)递归解析器会发起一次A记录请求,向二级域DNS问询NS地址的IP地址(11-14,16-19),最后询问主域名的IP(15)获得地址(20)。
利用这个特性,攻击者就可以实现DNS流量放大,达到拒绝服务的效果。漏洞利用需要具备两个条件:
发起DNS 请求就不说了,二级域NS记录通过购买域名并自定义配置,很多域名服务商可以购买特别廉价的域名,使用较低的成本就可以获得大量的NS记录。如下图所示,当满足了上述两个条件,攻击者可以发起一个 sd1.attacker.com 的DNS 请求,请求会到达attacker.com 的威域DNS服务器并返回提前设置好的大量NS记录,这些NS记录指向的就是受害者二级域,此时攻击者的本地递归解析器会向victimc.om 的DNS服务器发起大量NS解析请求,其数量时NS记录总量的两倍,因为每个记录会发起IPv4和IPv6两次请求。
在这种攻击模式下递归解析器和目标二级域DNS服务器都承受了大量的流量(与请求的Client数量和NS记录数量有关),是双向的攻击。
这类型漏洞需要修复DNS解析程序的逻辑,不再完全解析NS记录,而是设置上限K,最多解析K个。
DNS安全扩展(Domain Name System Security Extensions,DNSSEC),是由IETF提供的一系列DNS安全认证的机制。它采用基于公共密钥加密的数字签名,从而增强 DNS 验证强度。DNSSEC 并非对 DNS 查询和响应本身进行加密签名,而是由数据所有者对 DNS 数据自身进行签名。
每一个 DNS 区均包含一个公私秘钥对,DNS 区所有者使用该区域的私钥对区域内的 DNS 数据进行签名,为这些数据生成数字签名。该区域的公钥则在区域内公开发布,供全体用户检索。凡在区域内查找数据的递归解析器,还必需检索区域公钥,从而使用公钥验证 DNS 数据的真实性。解析器确认检索到的 DNS 数据的数字签名是否有效。如果有效,证明 DNS 数据合法,则将 DNS 数据返回给用户。如果签名未通过验证,解析器会假设发生攻击,丢弃数据并向用户返回错误。因此,DNSSEC 相当于在 DNS 协议中新增了两项重要功能:
很多域名服务商已经提供了DNSSEC的配置能力。
1、Zombie Awakening- Stealthy Hijacking of Active Domains through DNS Hosting Referral.pdf
2、NXNSAttack- Recursive DNS Inefficiencies and Vulnerabilities.pdf