標籤:

Cobalt Strike的特殊功能(external_C2)探究

譯者:WisFree

預估稿費:200RMB

投稿方式:發送郵件至linwei#360.cn,或登陸網頁版在線投稿

寫在前面的話

本文所介紹的內容並非Cobalt Strike官方支持的功能,而且我們還沒有對這些功能進行完整的測試。如果你想要自己動手進行實驗的話,你可以參考@armitagehacker給出的這份參考文檔【點我獲取】。

無論怎樣,研究的過程都是充滿樂趣的。本文將要介紹的功能可以給我們提供很大的靈活性,並允許我們在一個高度安全的環境中充分利用Cobalt Strike的強大功能。除此之外,我們也希望這個功能在將來能夠正式成為Cobalt Strike官方支持的功能。

External_C2

我們首先遇到的問題就是需要給C2流量選擇一種標準信道,我們的選擇對象有DNS、HTTP或HTTPS,但我們認為Mallable格式也許對C2流量的支持會更好,尤其是當我們向一個真實的網站發送非C2流量時(配合Haproxy),效果會比較好。當然了,我們還需要構建我們自己的通信信道並讓Cobalt Strike接管它。除此之外,我們甚至還打算自己搭建一台代理並對特殊的Mallable內容進行解碼,將數據通過我們自己的信道發送,然後在我們的重定向器中對Mallable數據重新進行解析,最終將其轉發給Cobalt Strike的Team Server。

當時我還專門向 @armitagehacker 諮詢了有沒有其他方法可以讓我們跟Mallable數據引擎進行交互,他當時提到了一部分實驗代碼,也許我們可以用這些實驗代碼來試試看。這個介面名叫「External_C2」,它允許我們使用beacon數據包並通過可選埠與Team Server進行交互。下面給出的是整個交互過程中的External_C2數據流圖:

我們的第三方控制器名叫C2_server,而客戶端為C2_client。C2_client將會要求進行第一階段的通信操作,載入shellcode並與beacon的指定管道進行連接。接下來,C2_client將會從這個指定管道中讀取數據包並將其轉發給C2_server,然後C2_client便會收到響應數據包以及beacon。C2_clinet與C2_server之間的通信完全取決於開發人員的實現方式,我們可以將beacon數據當作是一種「黑盒」,而你需要確保將其當作一種二進位數據來處理(不能使0x00終結字元串)。

在Cobalt Strike中,這種「未公開的代碼」可以被用來運行下面這個腳本:

大家可以看到,現在我們已經設置了一個external_C2監聽器,並且正在監聽teamserver的2222埠。

PoC:beacon與文件共享功能

@armitagehacker給我們提供了一些樣本代碼(C語言),其中包含有客戶端和伺服器端進程代碼。將代碼按照客戶端跟伺服器端劃分完成之後,我們嘗試通過我們自己的通信連接來獲取一個可用的beacon通信。實際上,為了方便進行下一步的調試,我決定要將C2_client的數據存儲在一份文件之中,然後讓C2_server的代碼每隔X秒就對該文件的大小進行一次檢測。如果大小超過了兩個位元組,則準備捕獲一個新的數據包,然後將其發送給Team Server。響應數據將會被存儲在另一份文件中,而這個文件則交由C2_client來進行處理。這也就意味著,為了讓整個通信過程能夠正常運行,客戶端和伺服器端必須要能夠對同一目錄進行讀取和寫入。我已經在Samba共享目錄以及Owncloud同步目錄中進行了測試,測試過程均沒有出現任何問題,只不過有時候速度會比較慢罷了。

為了加快開發進度,我用Python對代碼進行了重寫。這樣不僅簡化了代碼,而且還可以幫助我們更輕鬆地訪問各種通信信道,因為相比於C語言,Python能夠讓我們的開發變得更加簡單。目前為止,我還沒有用Python完整實現C2_client,而且Python版的C2_client也無法正常訪問指定管道。不過我可以將這些功能放在一個DLL文件之中,然後再在Python代碼中調用這些功能就暫時解決這一問題了。

PoC代碼:【點我獲取

我們的Python代碼目前仍然需要從DLL文件中調用@armitagehacker給我們提供的功能以執行shellcode,這樣就可以正確地與指定管道進行交互了。

當然了,完整的Python版本還是非常好的,但是我自己沒有那麼多時間去解決指定管道的問題,而且這也是我第一次使用Python來實現C語言下的DLL,再加上我並不是專業的開發人員,所以大家先將就著用吧!

不過就我個人而言,我還是比較希望使用純Python代碼來實現的。

PoC演示

就在我們發布了這個PoC的幾個月之後,我們突然發現在客戶端部分似乎還可以優化一下。現在你需要知道的是,客戶端的網路安裝架構其實並不是默認狀態的,其中還涉及到高度安全的數據處理流程以及安全風險管控。簡單來說,在整個目標網路架構中存在多個「超級安全空間」(Super Secure Zone),這些空間與普通的組織IT網路以及IT管理空間進行了嚴格的劃分。下面的圖片顯示的就是這種安裝架構:

對於這種特殊的場景,客戶端在訪問IT管理空間時,我們就可以通過一些網路嗅探以及SMB-relay攻擊來嘗試接管IT管理空間內的某些賬號,並最終登錄Bastion主機。

接下來,我們需要從Bastion主機開啟一個beacon,並嘗試重新連接到我們的Team Server(處於IT管理空間之中)。但有意思的是,整個系統就跟Bastion主機一樣,我們很容易就實現了入侵和重連,而且這裡並沒有部署任何的管理協議(SMB、WinRM或WMI等等)。除此之外,例如ARP欺騙、ICMP重定向、LLMNR和其他類型的流量攻擊方式在網路層也被屏蔽了。唯一可行的出站流量就是從Bastion主機發往超級安全空間(Super Secure Zone)的網路數據,而入站流量則是針對中央共享文件的web-RDP流量以及SMB流量。

我們將特定文件存放到了共享目錄中,然後執行了以下命令:

1. 攻擊者的設備:開啟Team Server,載入external.cna文件。

2. 攻擊者的設備:運行C2_server.py。

3. Baston主機:c2file.exe sharesystemsharesubdirTEMPFILENAME

運行完之後,我們就得到了一個新的beacon!

在下面這張截圖中,你可以看到Cobalt Strike的介面,其中有一個beacon連接到了Bastion主機。下圖中已打開的標籤截圖表明我們使用的是Cobalt Strike的內置命令。主機桌面上的cmd.exe運行了c2file.exe,而資源管理器窗口中顯示的就是共享文件的內容。請注意其中的bea,be*文件,這些文件就是數據交換髮生的地方。

繞過空氣間隙設備

雖然本文所介紹的場景是非常特殊的,但我們也在想辦法如何將同樣的PoC應用到其他場景中。比如說,在面對空氣間隙設備時,你可以使用一個攜帶型的USB設備來當作數據傳輸載體。但是此時,我們可以讓c2file指向這個U盤驅動器的路徑,然後通過Team Server來完成數據的傳輸。我們在實驗室中的測試是成功的,但是數據的傳輸速率很可能因為環境的不同而發生變化。但從技術角度出發,這也是一種利用Cobalt Strike的external_C2繞過了空氣間隙保護的實例。


推薦閱讀:

從Chrome源碼看DNS解析過程
我所在地區DNS為202.100.64.68,路由器中默認的是118.118.118.11?
顯性URL和隱性URL有什麼區別?
為什麼源站域名和加速域名不能相同?

TAG:DNS | HTTP | Python |