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