1. 程式人生 > >DNS 深度理解

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高階應用場景,最底層全部都是基於這個,把最基礎的東西搞通透以後,再去看各類高階應用就非常簡單了,還是那句話不管上層怎麼變化,但萬變不離其宗,篇幅限制,此處僅僅也只是先帶大家打個照面,更多高階應用,後續肯定還會有大量的篇幅說明,來日方長,我們待續……