Reviving MuddyC3 Used by MuddyWater (IRAN) APT

Estimated Reading Time: 10 minutes

Note : This article contain two parts one for Blue Teams and the other for red teams. go to the part you interested in or read both if you are purple team guy 😀 .

MuddyWater is a well-known threat actor group founded by Iran. “that has been active since 2017. They target groups across Middle East and Central Asia, primarily using spear phishing emails with malicious attachments. Most recently they were connected to a campaign in March that targeted” organizations in Turkey, Pakistan, and Tajikistan.[0]

MuddyWater attacks are characterized by the use of a slowly evolving PowerShell-based first stage backdoor we call “POWERSTATS”. Despite broad scrutiny and reports on MuddyWater attacks, the activity continues with only incremental changes to the tools and techniques. [1]


In June 26 2019 a group called “Green Leakers” on telegram published screenshots of the C2 admin panel as you can see below along with screenshot of the muddyc3 c2 source code . they announced that they are selling all the leaked tools for 0.5BTC.

At that time i got the source code from github , so i tried the code to find that the core of the c2 which is powershell payload is messing ( the leaker didn’t include the payload in order to by all the tools ). so i didn’t have time to reverse engineer the source code and i left it. last week i got 3 days off from my work ( working in SOC will keep you for ever busy ) so i started analyzing the code which will be discussed below and i was able to understand how it works in order to create the messing powershell payload and make the c2 come to life. I didn’t just revive the C2 but also added more advanced functionality which will be released as separate tool soon.

Lets start by giving a summary about the muddyc3 tool :

  • Coded with python2.7
  • works as C2 server that serve a powershell agent script when requested
  • i didn’t find any function to encrypt the traffic between the the agent and the C2 but there are variables with name private_key , public_key so i suspect the functions removed.
  • every function has its own url : modules , commands , result…
  • its make use of HTA and bas64 encoded powershell code to bypass the AV ( right now AV can catch HTA )
  • It use threading so many agent can connect and controlled at the same time.
  • the agent must collect information about the system when it first start then report it to the C2
  • there is template for agent which will be filled with ip and port when the C2 run.
  • include functions but not all implemented in the initial POC : upload , download , load modules , get screenshot
  • The initial powershell agent POC i created can bypass the AV including Kaspersky, Trendmicro

Analysis Part ( Blue Team ):

Now we dig deep in the C2 to explain how it work and how i created the agent based on the function available in the C2 :

C2 interface  : simple CLI interface that ask when started for IP,Port and proxy configuration to generate the initial payloads.

Ask for IP and Port to generate the payload
Payloads generated based on the IP:Port
simple Command menu which include the basic commands needed to run the C2

the source code for the interface is in the muddyc3.py which is clear and doesn’t need explanation :

will generate the initial payloads then add them to array and finally print them to the user
this part of the code will check if the pointer in Main or an agent and get the command from the user then check if the command in the list of menu command, it will run the menu command function defined in the cmd.py . if the command does not match the menu commands and the pointer in main then it will not do anything . if the pointer in agent menu then it will add the command to agent command queue in order to be requested and executed by the agent.
this screenshot from the cmd.py which shows the list of commands and the function it should run

Webserver.py Functions : the web server has a list of urls for each module some of the URLs will work with GET and other with POST depending how the function configured. below is a summary of the functions i created an agent for it :

its start by defining the web server listener and urls variable that include the url with its module
for example in the urls variable /get url will run the function payload so if we tried to access this link on the muddyc2 server we will get the payload
accessing the server with url /get provided us with payload
the same with /getc we got the payload encoded with base52
/hjf and /hjfs will run these function that include powershell code that run as powershell job in the background
/hta will run mshta function to generate payload from mshta.exe

Now i will explain the core the URLs along with their code in the agent :

/info/(.*) URL will run the function info which is register function for new agents , it expect agent id name to be in the URL along with machine information in the body of the POST request. the body must contain below information separated by ** :
1) OS
2) Machine IP
3) system architecture
4) hostname
5) domain name
6) username

the C2 will get the information along with agent ID and save it in array to be used to server commands and other implemented function cause each agent has its own commands queue .


This code from the powershell POC agent which collect the information requried by the C2 from windows machine then generate random name for the agent. finally it will do post request to URL /info/<agent id> with post request including the required information separated by **
This URL ( /cm/(.*) ) will accept GET request with agent ID in order to serve the commands for this agent ( from command queue ) , if the agent is not registered or if the C2 goes down then up and old agent reconnected, it will send REGISTER as response which will force the agent to register by sending request to /info/ URL as you will see below in agent code.
also it will get the current time when the agent ask for command to determine when the last time agent probed to give information if the agent died or still alive.
this part of code from powershell POC agent which will run in loop and keep probing the C2 for new commands using URL /cm/<agent id> 
Now if the command is REGISTER then it will contact URL /info/<agent id > to register and get the commands ( this is very important in order to not lose the agent when the C2 is down ).
if the command is empty it will wait 2 seconds before probing again for command.
at last the command will be executed using Invoke-Expression and the output data will be encoded in base64 then uploaded to URL /re/<agent id> which will be explained below
URL /re/(.*) will run result function which will wait for the result of the executed commands in base64 then decode it and present it to the user
URL /md/(.*) will wait for a POST request that include agent ID in the URL and in the request body the name of the module requested then it will use the name of module to load from Module/ folder in the C2 directory
this code from the powershell POC agent which will check if the command got from the C2 is load then it will get the second argument splited by space to request and download the required module. the request will be handled by the function load which will be explained below. the output of load function will include the module which will be executed by Invoke-Expression
this code from the powershell POC agent will request the module by POST request to URL /md/<agent id> with request body contain module name.

Now after we finished the analysis part of this article i will walk you through using muddyc3 with POC powershell agent. please note that this just POC and the full tool written on top of muddyc3 will be released soon. i finished implementing many cool features but i will wait until i add more and to be fully tested before the release.

Using MuddyC3 to get domain admin ( Red Team ) :

i will use simple scenario to show the usage of muddyc3 powershell agent POC.

run the muddyc3 using python2.7 , it will ask you for the IP and Port will be used to create the payloads ( this will be your public IP or the IP reachable by the devices you want to hack )
you can use any of the printed payloads but the last 3 undetectable from AVs the others is detectable by kaspersky
as you can see am testing on kaspersky free with no detection but this also applicable for the total security and enterprise edition. also i tested it on trendmicro maximum security.
as you can see we got a connection from the agent
using list command we can see the list of agents we have and the last time the contacted the C2
using ” use ” command we move the agent prompt and we can issue command like pwd and get result .
lets see the the users in this domain to find the domain admin by using : net user /DOMAIN command
Ok so we checked the user ahmedkl and he is domain admin , now we will check if he had logged in to this machine
you can load powershell modules by copying the modules to Modules/ folder in C2 directory then use ” load <module name.ps1> ” command to load it directly into the agent session. but you can see it didn’t work here because kaspersky intercepted the data as its clear text ( this solved by encrypting the data in my upcoming tool )
this picture shows kaspersky blocking /md/ url because mimikatz detected by AV so we will pause to complete the demo
now that mimikatz loaded
Now we load Invoke-WMIExec.ps1 to do pass the hash attack using wmi
Now in order to use Invoke-WMIExec we need to encode our payload so we don’t have issue with characters escaping so we use python ( make user to utf-8 encode )
as you can see the payload executed and the agent connected

Thank you for reading my article . you can find the muddyc3 with payload.ps1 ( powershell agent POC ) here : Muddyc3-Revived

i will release my tool which built on top of muddyc3 soon. right now it include below features and there is more am working on :

  • full encryption of modules and command channel
  • get encryption key on the fly ( not hard coded )
  • take screenshots and send it encrypted to C2
  • upload files from C2
  • download files from the victim
  • staged payloads to bypass detection
  • bypasses AVs ( tested on kaspersky and trendmicro )
  • set the beacon interval dynamically even after the agent connected
  • dynamic URLs
  • set the configuration one time ( will not ask for IP:port each time )
  • bug fixes and stable version
  • global kill switch to end campaigns

Leave a Reply

Your email address will not be published. Required fields are marked *