DNS 深度理解

0x01 首先,我们先来简单回顾下DNS的基本解析流程, 比较简单,如下

 

1

2

3

4

5

6

7

8

9

10

 

-> 以客户端浏览器访问 www.rootkit.org 域名为例,首先,它会去检查当前浏览器缓存,如果有,就直接响应,如果没有,就继续往下找

-> 接着,操作系统会去检查自己的host文件,如果从中没找到对应关系,会再到系统dns缓存中查,如果缓存中有,就直接返回该域名所对应的ip

-> 如果缓存中没有,则会向我们事先设置好的dns服务器 [ 一般有两个, 主 & 备 ] 去请求,即所谓的`递归查询`,dns服务器首先会到自身解析数据库中去查

-> 如果dns服务器在自己的解析库中也没找到,它就会自动帮我们向根发送询问请求

-> 此时,根看到要请求的是org的后缀,就会把org所在的ns服务器告诉我们的dns

-> 然后,我们的dns服务器就会去请求org所在的ns服务器

-> 当请求到达org ns服务器时,org一看域名是在rootkit这个域下的,就会把rootkit所在的ns服务器再告诉我们的dns服务器

-> 再然后,我们的dns服务器就会去请求rootkit这个域的ns服务器

-> rootkit这个域的ns服务器一看是要访问www就直接找到了www对应的A记录的ip,并把它丢给我们的dns,上面逐个询问的过程,即 `迭代查询`

-> 最后,我们的dns再把最终解析到的这个ip丢给我们的客户端,然后客户端就直接拿着去访问了,如下,访问google.com时的简易流程图

 


演示环境,此处暂以一主一从为例进行演示

 

1

2

 

DnsMaster ip : 192.168.3.60 主 DNS 服务器

DnsSlave ip : 192.168.3.61 从 DNS 服务器

 

0x02 几种常见的 DNS 功用类型

 

1

2

3

4

 

主dns,主要负责实际的正反向域名解析

从dns,主要从其它的主dns或者从dns中同步解析数据库,`即区域传送`,一般是通过序列号递增来判断主dns是否有更新

缓存DNS服务器...

转发器...

 

0x03 理解DNS区域解析流向

 

1

2

3

4

5

 

正向 : FQDN -> IP

反向 : IP -> FQDN

FQDN 即 `完整合法域名`,如 `www.rootkit.org.` 最后面的`.`表示根,意思就是根下的org下的rootkit

不管是正向还是反向区域都需要有一个单独的解析数据库去解析

 

0x04 认识DNS中一些常见的资源记录类型,说到底就是用它们来标记某个主机类型

 

1

2

3

4

5

6

7

 

A 记录 FQDN -> ipv4

AAAA 记录 FQDN -> ipv6

NS 记录 标明当前区域的NS服务器是谁

MX 记录 标明当前域内谁是邮件服务器

PTR 记录 ip -> FQDN

SOA 记录 一个解析库有且只有一个SOA记录,且必须为解析库的第一条记录

CNAME 记录 别名

 

0x05 如何在区域配置文件中定义上述各种资源记录

记录定义标准格式,如下

 

1

 

name TTL值[缓存时长可省] IN 记录类型 值

 

定义SOA记录,一般会配合DNS主从同步来用

 

1

2

3

4

5

6

7

 

admin.org. IN SOA ns.admin.org. admin.admin.org. (

2017122309 ; 序列号

2H ; 刷新时间

10M ; 重试时长

1W ; 过期时间

1D ; 否定答案的TTL值

)

 

定义NS记录,如果连续两条紧挨着的记录相同,后面一个的name可省略,另外NS记录需要在后续有一个对应的A记录

 

1

2

 

admin.org. IN NS ns1.admin.org.

admin.org. IN NS ns2.admin.org.

 

定义MX记录,注意,此记录有优先级,数字越小,优先级越高,同样,后面也需要指向一条A记录

 

1

2

 

admin.org. IN MX 10 mx1.admin.org.

admin.org. IN MX 6 mx2.admin.org.

 

定义A记录,注意,对于A记录,同一个name可以对应多个不同的ip,访问时会自动实现轮询的效果

 

1

2

3

4

 

www.admin.org. IN A l.2.3.4

www.admin.org. IN A l.2.3.4

*.admin.org. IN A 1.2.3.4 泛解析,用户输入不存在的域名是全部都解析到这个ip上

admin.org. IN A 1.2.3.4 另外一种泛解析写法 admin.org

 

定义PTR记录,即反向区域解析,一定要注意,所有的ip地址必须反过来写,另外,都必须带上固有后缀in-addr.arpa.

 

1

 

4.3.2.in-addr.arpa. IN PTR www.admin.org.

 

定义CNAME记录,意思就是当访问web.admin.org.时就直接解析到www.admin.org.

 

1

 

web.admin.org. IN CNAME www.admin.org.

 

0x06 关于一些常见 dns 解析测试工具的基本使用

 

1

2

3

4

5

 

# dig -t 记录类型 要解析的域名 @用于解析该域名的dns服务器

# dig -t axfr 要解析的域名 @用于解析该域名的dns服务器 全量区域同步,可用来测试`区域传送漏洞`

# dig +trace 要解析的域名 跟踪指定域名的详细解析过程

# nslookup 交互式查询

# host -t 类型 要解析的域名 用于解析的dns服务器

 

0x07 因为后续还要做DNS主从实时同步,所以这里就先从配置正向区域解析开始

开始安装主DNS,bind是核心包,bind-devel是bind核心库,utils是dns测试工具包,工具包里包含了一些常用工具,如,nslookup,dig,host,另外,此处暂以yum方式进行安装,当然,你也可以自行采用源码编译的方式进行安装,不过编译安装不太好的地方就是,有很多关键目录和配置文件没法自动生成,配置起来比较繁琐

 

1

2

 

# yum install bind-utils bind bind-devel bind-chroot -y

# rpm -qa | grep bind

 

配置主DNS的主配置文件named.conf

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

 

# cat /var/named/named.ca 全球13组根DNS服务器解析地址的存放位置

# cp /etc/named.conf{,.bak} 先备份配置文件再编辑

# > /etc/named.conf bind的主配置文件,主要提供全局配置

# vi /etc/named.conf

// 全局配置段,注意,dns工作在tcp/53和udp/53端口上,tcp/53一般主要用来进行区域同步,而udp/53主要用来负责正常的解析请求和响应

options {

version "1.1.1";

listen-on port 53 { 192.168.3.60;127.0.0.1; }; // 把dns端口监听在本地指定的ip上

directory "/var/named/chroot/etc/";

pid-file "/var/named/chroot/var/run/named/named.pid";

allow-query { any; }; // 允许任意主机向我进行dns请求

Dump-file "/var/named/chroot/var/log/binddump.db";

Statistics-file "/var/named/chroot/var/log/named_stats";

zone-statistics yes;

memstatistics-file "log/mem_stats";

empty-zones-enable no;

forwarders { 114.114.114.114;8.8.8.8; };

};

// 设置rndc通信共享秘钥

key "rndc-key" {

algorithm hmac-md5;

secret "Eqw4hClGExUWeDkKBX/pBg==";

};

controls {

inet 127.0.0.1 port 953

allow { 127.0.0.1; } keys { "rndc-key"; };

};

// bind日志配置区段

logging {

channel warning {

file "/var/named/chroot/var/log/dns_warning" versions 10 size 10m;

severity warning;

print-category yes;

print-severity yes;

print-time yes;

};

channel general_dns {

file "/var/named/chroot/var/log/dns_log" versions 10 size 100m;

severity info;

print-category yes;

print-severity yes;

print-time yes;

};

category default {

warning;

};

category queries {

general_dns;

};

};

// 为了简化bind主配置文件,可以通过include的方式来引入区域文件

include "/var/named/chroot/etc/view.conf";

 

针对rndc 的简单配置,关于rndc其实就是个bind服务管理工具,可以通过它在本地或者直接远程来方便的对bind服务进行各种管理操作,如,重载,刷新缓存,关闭…默认工作在tcp/953端口上,比较危险,所以我们一般只让它监听在本地即可

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

 

# vi /etc/rndc.key

key "rndc-key" {

algorithm hmac-md5;

secret "Eqw4hClGExUWeDkKBX/pBg==";

};

# vi /etc/rndc.conf

key "rndc-key" {

algorithm hmac-md5;

secret "Eqw4hClGExUWeDkKBX/pBg==";

};

options {

default-key "rndc-key";

default-server 127.0.0.1; // 让它只监听在本地,禁止rndc远程连接,防止被利用

default-port 953;

};

 

0x08 定义正向区域文件

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

 

# vi /var/named/chroot/etc/view.conf

view "MasterView" {

zone "admin.org" {

type master;

file "admin.org.zone"; // 区域文件名,此处的文件名可以随意

allow-transfer { // 允许传送的主机,所谓的区域传送漏洞也就出在这里

192.168.3.61;

// any; // 如果此处设置为any,则允许任意主机来传送,这就是产生区域传送漏洞的根源

// 所以务必谨记,跟谁传送,就只写谁的ip

};

notify yes;

also-notify {

192.168.3.61;

};

};

};

 

0x09 定义正向区域文件,我们再来编写正向区域解析数据库,内部主要用于存放各种记录类型和宏,如下

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

 

# vi /var/named/chroot/etc/admin.org.zone

$TTL 3600 ; 1h

@ IN SOA ns1.admin.org. email.admin.org (

2003 ; serial // 时刻谨记,每次如果是手工修改完解析库文件以后都要自增一下

900 ; refresh (15 minutes)

600 ; retry (10 minutes)

86400 ; expire (1 day)

3600 ; minimum (1 hour)

)

IN NS ns1.admin.org.

IN NS ns2.admin.org.

IN MX 10 mx1.admin.org.

IN MX 20 mx2.admin.org.

ns1 IN A 192.168.3.3

ns2 IN A 192.168.3.61

mx1 IN A 192.168.3.4

mx2 IN A 192.168.3.5

www IN A 192.168.3.6

www IN A 192.168.3.3

ftp IN CNAME www.admin.org.

* IN A 192.168.3.110 //此处,即为泛解析的两种书写方式

admin.org. IN A 192.168.3.120

cacti IN A 192.168.3.16

zabbix IN A 192.168.3.18

 

0x10 配置完正向区域解析库以后,我们就可以来重载服务,测试解析了

 

1

2

3

4

5

6

7

8

9

10

11

12

13

 

# named-checkconf 此命令会自动检查bind主配置文件是否有语法错误

# named-checkzone "admin.org" admin.org.zone 检查指定区域解析库文件是否有错误配置

# ps -aux | grep named 我们看到bind默认是用named用户来运行的,我们改下区域解析库文件的权限

# chmod 640 /var/named/chroot/etc/admin.org.zone

# ll /var/named/chroot/etc/admin.org.zone

# chown named.named /var/named/chroot/etc/admin.org.zone

# /etc/init.d/named start 启动dns服务

# /etc/init.d/named reload 重载dns服务

# rndc reload 在dns服务启动的情况下,也可使用rndc来重载区域解析库

# chkconfig named on 加入系统自启动

# netstat -tulnp 看下端口有没正常起来

# dig -t A www.admin.org @192.168.3.60

# dig -t A mx2.admin.org @192.168.3.60

 

0x11 在正向区域测试解析没有任何问题之后,我们再来看如何定义反向区域,注意,反向区域的ip地址要全部反写,即 变化的区域不写,不变的区域反写,此区域不需要MX和A记录,只需要PTR记录即可,另外,通常都是先有正向解析再有反向解析

 

1

2

 

192.168.3.x => 3.168.192.in-addr.arpa

192.168.x.x => 168.192.in-addr.arpa

 

定义反向区域的方式很简单,先定义好反向区域文件

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

 

# vi /var/named/chroot/etc/view.conf

view "MasterView" {

zone "admin.org" IN {

type master;

file "admin.org.zone";

allow-transfer {

192.168.3.61;

};

notify yes;

also-notify {

192.168.3.61;

};

};

zone "3.168.192.in-addr.arpa" IN { // 一样要反写,此处就表示192.168.3.x这个网段

type master;

file "192.168.3.zone";

};

};

 

再来定义反向区域解析库

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

 

# vi /var/named/chroot/etc/192.168.3.zone

$TTL 3600

$ORIGIN 3.168.192.in-addr.arpa.

@ IN SOA ns1.admin.org. login.admin.org. (

2001 // 时刻谨记,每次如果是手工修改完解析库文件以后都要自增一下

900

600

86400

3600

)

IN NS ns1.admin.org.

IN NS ns2.admin.org.

6 IN PTR www.admin.org.

5 IN PTR mx2.admin.org.

4 IN PTR mx1.admin.org.

61 IN PTR ns2.admin.org. // 注意,这里必须要有一条ns记录指向我们后面的从DNS服务器

3 IN PTR ns1.admin.org.

31 IN PTR pop3.admin.org.

 

 

1

2

3

4

5

6

7

8

9

 

# chmod 640 192.168.3.zone

# chown :named 192.168.3.zone

# named-checkconf

# named-checkzone "3.168.192.in-addr.arpa" 192.168.3.zone 检查zone配置文件中是否有错误

# ll /var/named/chroot/etc/

# /etc/init.d/named reload

# netstat -tulnp

# host -t ptr 192.168.3.3 192.168.3.60

# dig -x 192.168.3.4 @192.168.3.60

0x12 当主DNS的正反向区域解析都没任何问题之后,我们开始来配置主从DNS实时同步

 

1

2

 

# yum install bind-utils bind bind-devel bind-chroot -y

# rpm -qa bind-utils bind bind-devel bind-chroot

 

开始配置从DNS,其实,在这里跟配置主DNS并没有太大区别,还是先按上面主DNS的配置方式来一遍

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

 

# > /etc/named.conf

# vi /etc/named.conf

options {

version "1.1.1";

listen-on port 53 { 192.168.3.61; 127.0.0.1; };

directory "/var/named/chroot/etc/";

pid-file "/var/named/chroot/var/run/named/named.pid";

allow-query { any; };

Dump-file "/var/named/chroot/var/log/binddump.db";

Statistics-file "/var/named/chroot/var/log/named_stats";

zone-statistics yes;

memstatistics-file "log/mem_stats";

empty-zones-enable no;

forwarders { 114.114.114.114;8.8.8.8; };

};

key "rndc-key" {

algorithm hmac-md5;

secret "Eqw4hClGExUWeDkKBX/pBg==";

};

controls {

inet 127.0.0.1 port 953

allow { 127.0.0.1; } keys { "rndc-key"; };

};

logging {

channel warning {

file "/var/named/chroot/var/log/dns_warning" versions 10 size 10m;

severity warning;

print-category yes;

print-severity yes;

print-time yes;

};

channel general_dns {

file "/var/named/chroot/var/log/dns_log" versions 10 size 100m;

severity info;

print-category yes;

print-severity yes;

print-time yes;

};

category default {

warning;

};

category queries {

general_dns;

};

};

include "/var/named/chroot/etc/view.conf";

 

配置rndc

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

 

# vi /etc/rndc.key

key "rndc-key" {

algorithm hmac-md5;

secret "Eqw4hClGExUWeDkKBX/pBg==";

};

# vi /etc/rndc.conf

key "rndc-key" {

algorithm hmac-md5;

secret "Eqw4hClGExUWeDkKBX/pBg==";

};

options {

default-key "rndc-key";

default-server 127.0.0.1;

default-port 953;

};

 

0x13 接着,再来配置主从DNS正向区域实时同步,务必要记得在主DNS的正向解析库中一定要先有一条ns记录的ip是指向从DNS服务器的,不然同步通知是无法完成的,也就是说,一旦主DNS发生改变,它会通知所有的ns服务器进行更新,这样就可以实现实时正向区域同步的效果

对于从DNS的配置就非常简单了,只需要在从DNS上编辑区域文件,在里面配置好主DNS服务器的ip,设置好从DNS正向区域文件名,然后启动服务即可,如下

 

1

2

3

4

5

6

7

8

 

# vi /var/named/chroot/etc/view.conf

view "SlaveView" {

zone "admin.org" IN {

type slave; // 这里的类型要选择从服务器

masters { 192.168.3.60; }; // 指定主DNS服务器ip

file "slave.admin.org.zone"; // 指定从DNS正向区域解析库文件名,重启服务后它会自动同步过来,不用手工编辑

};

};

 

上面配置没问题以后,我们来重载服务试试

 

1

2

3

4

5

6

7

8

9

 

# ps -aux | grep named

# cd /var/ && chown named.named named/ 为了能让它自动创建解析库文件需要改先权限

# ll /var/named/chroot/etc

# /etc/init.d/named start

# chkconfig named on

# cat /var/named/chroot/etc/slave.admin.org.zone 这个文件会在从dns重载之后自动被同步过来

# netstat -tulnp

# tail -f /var/log/messages 其实,从日志中我们是可以清晰的看到整个同步过程的

# dig -t MX admin.org @192.168.3.61 同步完成后,我们可以直接用本机来进行解析测试

 

正向区域实时同步搞定之后,我们再来看看如何实现反向区域实时主从同步,还是要先在主DNS上的反向区域解析库中定义一条指向从DNS服务器的PTR记录,如下

首先,到主DNS服务器上去编辑反向区域解析库文件,添加一条指向从DNS服务器的PTR记录,具体如下

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

 

# vi /var/named/chroot/etc/192.168.3.zone

$TTL 3600

$ORIGIN 3.168.192.in-addr.arpa.

@ IN SOA ns1.admin.org. login.admin.org. (

2001 // 时刻谨记,每次如果是手工修改完解析库文件以后都要自增一下

900

600

86400

3600

)

IN NS ns1.admin.org.

IN NS ns2.admin.org.

6 IN PTR www.admin.org.

5 IN PTR mx2.admin.org.

4 IN PTR mx1.admin.org.

61 IN PTR ns2.admin.org. // 先在主DNS的反向区域解析库中添加一条指向从DNS的PTR记录

3 IN PTR ns1.admin.org.

31 IN PTR pop3.admin.org.

 

之后,再回到从DNS服务器上编辑区域配置文件,添加一个反向区域,跟正向区域同步一样,依然是指明主DNS服务器ip和从DNS反向区域解析库文件名,之后再重载服务,测试解析即可

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

 

# vi /var/named/chroot/etc/view.conf

view "SlaveView" {

zone "admin.org" IN {

type slave;

masters { 192.168.3.60; };

file "slave.admin.org.zone";

};

zone "3.168.192.in-addr.arpa" IN {

type slave;

masters { 192.168.3.60; };

file "192.168.3.zone";

};

};

 

 

1

2

3

 

# rndc reload

# cat /var/named/chroot/etc/192.168.3.zone 依然是在重载服务以后,该反向区域解析库文件会被自动同步过来

# host -t ptr 192.168.3.3 192.168.3.61

0x14 关于DNS自身的安全问题

 

1

2

3

 

配置错误,修复简单

各类投毒污染攻击,需要多方配合,篇幅原因后续我们再详细说

bind工具自身的漏洞,时常注意官方发布的各类高危补丁,尤其是可以直接被远程利用的,而后进行适时修补或更新即可

 

0x15 基于 DNS 的各类渗透技巧,其实说来,底层的原理非常简单,因为在一些脚本或者数据库中有很多那种可以直接用于发起DNS请求的函数,而我们就可以通过此来构造自己的各种攻击语句,然后再从解析log中提取执行结果

 

1

2

3

 

基于DNS log的sql盲注,代码及命令执行...后续有空接着说

基于DNS隧道的各类远程,如,cobalt strike,关于这个,我们后续还会再单独抽出来详细说

更多,待续...

 

下面就是个简单的区域传送效果,不过像这种古董级漏洞,现在确实已经非常罕见了,属于敏感信息泄露的一种,容易直接被人看见内部的网络结构拓扑部署,祝大家好运吧 ^_^


 

后话:
    其实,像dns这种过于的基础服务,配置起来确实非常简单,不过,关键还是要能灵活应用,非常建议大家还是把绝大部分的时间都花在去深入理解dns的解析过程上,个人觉得那个才是真正的价值,因为所有的DNS高级应用场景,最底层全部都是基于这个,把最基础的东西搞通透以后,再去看各类高级应用就非常简单了,还是那句话不管上层怎么变化,但万变不离其宗,篇幅限制,此处仅仅也只是先带大家打个照面,更多高级应用,后续肯定还会有大量的篇幅说明,来日方长,我们待续……

你可能感兴趣的:(DNS)