{
	"id": "6ec1b5cd-74d6-4796-8626-0d7ed06f8f82",
	"created_at": "2026-04-06T02:11:07.592697Z",
	"updated_at": "2026-04-10T13:11:51.965433Z",
	"deleted_at": null,
	"sha1_hash": "abe5c0cc8b169ac1d264a85bad0caf4c63f450e3",
	"title": "Reviving MuddyC3 Used by MuddyWater (IRAN) APT",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 5529240,
	"plain_text": "Reviving MuddyC3 Used by MuddyWater (IRAN) APT\r\nBy Ahmed Khlief\r\nPublished: 2020-01-13 · Archived: 2026-04-06 01:37:16 UTC\r\nEstimated Reading Time: 10 minutes\r\nNote : This article contain two parts one for Blue Teams and the other for red teams. go to the part you\r\ninterested in or read both if you are purple team guy\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 1 of 24\n\n.\r\nMuddyWater is a well-known threat actor group founded by Iran. “that has been active since 2017. They\r\ntarget groups across Middle East and Central Asia, primarily using spear phishing emails with malicious\r\nattachments. Most recently they were connected to a campaign in March that targeted” organizations in Turkey,\r\nPakistan, and Tajikistan.[0]\r\nMuddyWater attacks are characterized by the use of a slowly evolving PowerShell-based first stage backdoor we\r\ncall “POWERSTATS”. Despite broad scrutiny and reports on MuddyWater attacks, the activity continues with\r\nonly incremental changes to the tools and techniques. [1]\r\nIn June 26 2019 a group called “Green Leakers” on telegram published screenshots of the C2 admin panel as you\r\ncan see below along with screenshot of the muddyc3 c2 source code . they announced that they are selling all the\r\nleaked tools for 0.5BTC.\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 2 of 24\n\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 3 of 24\n\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 4 of 24\n\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 5 of 24\n\nAt that time i got the source code from github , so i tried the code to find that the core of the c2 which is\r\npowershell payload is messing ( the leaker didn’t include the payload in order to by all the tools ). so i didn’t have\r\ntime to reverse engineer the source code and i left it. last week i got 3 days off from my work ( working in SOC\r\nwill keep you for ever busy ) so i started analyzing the code which will be discussed below and i was able to\r\nunderstand how it works in order to create the messing powershell payload and make the c2 come to life. I didn’t\r\njust revive the C2 but also added more advanced functionality which will be released as separate tool soon.\r\nLets start by giving a summary about the muddyc3 tool :\r\nCoded with python2.7\r\nworks as C2 server that serve a powershell agent script when requested\r\ni didn’t find any function to encrypt the traffic between the the agent and the C2 but there are variables\r\nwith name private_key , public_key so i suspect the functions removed.\r\nevery function has its own url : modules , commands , result…\r\nits make use of HTA and bas64 encoded powershell code to bypass the AV ( right now AV can catch HTA )\r\nIt use threading so many agent can connect and controlled at the same time.\r\nthe agent must collect information about the system when it first start then report it to the C2\r\nthere is template for agent which will be filled with ip and port when the C2 run.\r\ninclude functions but not all implemented in the initial POC : upload , download , load modules , get\r\nscreenshot\r\nThe initial powershell agent POC i created can bypass the AV including Kaspersky, Trendmicro\r\nAnalysis Part ( Blue Team ):\r\nNow we dig deep in the C2 to explain how it work and how i created the agent based on the function available in\r\nthe C2 :\r\nC2 interface  : simple CLI interface that ask when started for IP,Port and proxy configuration to generate the\r\ninitial payloads.\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 6 of 24\n\nAsk for IP and Port to generate the payload\r\nPayloads generated based on the IP:Port\r\nsimple Command menu which include the basic commands needed to run the C2\r\nthe source code for the interface is in the muddyc3.py which is clear and doesn’t need explanation :\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 7 of 24\n\nwill generate the initial payloads then add them to array and finally print them to the user\r\nthis part of the code will check if the pointer in Main or an agent and get the command from the\r\nuser then check if the command in the list of menu command, it will run the menu command\r\nfunction defined in the cmd.py . if the command does not match the menu commands and the\r\npointer in main then it will not do anything . if the pointer in agent menu then it will add the\r\ncommand to agent command queue in order to be requested and executed by the agent.\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 8 of 24\n\nthis screenshot from the cmd.py which shows the list of commands and the function it should run\r\nWebserver.py Functions : the web server has a list of urls for each module some of the URLs will work with\r\nGET and other with POST depending how the function configured. below is a summary of the functions i created\r\nan agent for it :\r\nits start by defining the web server listener and urls variable that include the url with its module\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 9 of 24\n\nfor example in the urls variable /get url will run the function payload so if we tried to access this\r\nlink on the muddyc2 server we will get the payload\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 10 of 24\n\naccessing the server with url /get provided us with payload\r\nthe same with /getc we got the payload encoded with base52\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 11 of 24\n\n/hjf and /hjfs will run these function that include powershell code that run as powershell job in the\r\nbackground\r\n/hta will run mshta function to generate payload from mshta.exe\r\nNow i will explain the core the URLs along with their code in the agent :\r\n/info/(.*) URL will run the function info which is register function for new agents , it expect agent\r\nid name to be in the URL along with machine information in the body of the POST request. the\r\nbody must contain below information separated by ** :\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 12 of 24\n\n1) OS\r\n2) Machine IP\r\n3) system architecture\r\n4) hostname\r\n5) domain name\r\n6) username\r\nthe C2 will get the information along with agent ID and save it in array to be used to server\r\ncommands and other implemented function cause each agent has its own commands queue .\r\nThis code from the powershell POC agent which collect the information requried by the C2 from\r\nwindows machine then generate random name for the agent. finally it will do post request to URL\r\n/info/\u003cagent id\u003e with post request including the required information separated by **\r\nThis URL ( /cm/(.*) ) will accept GET request with agent ID in order to serve the commands for this\r\nagent ( from command queue ) , if the agent is not registered or if the C2 goes down then up and old\r\nagent reconnected, it will send REGISTER as response which will force the agent to register by\r\nsending request to /info/ URL as you will see below in agent code.\r\nalso it will get the current time when the agent ask for command to determine when the last time\r\nagent probed to give information if the agent died or still alive.\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 13 of 24\n\nthis part of code from powershell POC agent which will run in loop and keep probing the C2 for\r\nnew commands using URL /cm/\u003cagent id\u003e \r\nNow if the command is REGISTER then it will contact URL /info/\u003cagent id \u003e to register and get\r\nthe commands ( this is very important in order to not lose the agent when the C2 is down ).\r\nif the command is empty it will wait 2 seconds before probing again for command.\r\nat last the command will be executed using Invoke-Expression and the output data will be encoded\r\nin base64 then uploaded to URL /re/\u003cagent id\u003e which will be explained below\r\nURL /re/(.*) will run result function which will wait for the result of the executed commands in\r\nbase64 then decode it and present it to the user\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 14 of 24\n\nURL /md/(.*) will wait for a POST request that include agent ID in the URL and in the request body\r\nthe name of the module requested then it will use the name of module to load from Module/ folder\r\nin the C2 directory\r\nthis code from the powershell POC agent which will check if the command got from the C2 is load\r\nthen it will get the second argument splited by space to request and download the required module.\r\nthe request will be handled by the function load which will be explained below. the output of load\r\nfunction will include the module which will be executed by Invoke-Expression\r\nthis code from the powershell POC agent will request the module by POST request to URL\r\n/md/\u003cagent id\u003e with request body contain module name.\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 15 of 24\n\nNow after we finished the analysis part of this article i will walk you through using muddyc3 with POC\r\npowershell agent. please note that this just POC and the full tool written on top of muddyc3 will be released soon.\r\ni finished implementing many cool features but i will wait until i add more and to be fully tested before the\r\nrelease.\r\nUsing MuddyC3 to get domain admin ( Red Team ) :\r\ni will use simple scenario to show the usage of muddyc3 powershell agent POC.\r\nrun the muddyc3 using python2.7 , it will ask you for the IP and Port will be used to create the\r\npayloads ( this will be your public IP or the IP reachable by the devices you want to hack )\r\nyou can use any of the printed payloads but the last 3 undetectable from AVs the others is detectable\r\nby kaspersky\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 16 of 24\n\nas you can see am testing on kaspersky free with no detection but this also applicable for the total\r\nsecurity and enterprise edition. also i tested it on trendmicro maximum security.\r\nwhen the user click enable content you will get connection on the C2 using macro\r\nyou can also use macros to spread the agent which used by muddywater in their operations\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 17 of 24\n\nas you can see we got a connection from the agent\r\nusing list command we can see the list of agents we have and the last time the contacted the C2\r\nusing ” use ” command we move the agent prompt and we can issue command like pwd and get\r\nresult .\r\nlets see the the users in this domain to find the domain admin by using : net user /DOMAIN\r\ncommand\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 18 of 24\n\nOk so we checked the user ahmedkl and he is domain admin , now we will check if he had logged in\r\nto this machine\r\nyou can load powershell modules by copying the modules to Modules/ folder in C2 directory then\r\nuse ” load \u003cmodule name.ps1\u003e ” command to load it directly into the agent session. but you can see\r\nit didn’t work here because kaspersky intercepted the data as its clear text ( this solved by\r\nencrypting the data in my upcoming tool )\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 19 of 24\n\nthis picture shows kaspersky blocking /md/ url because mimikatz detected by AV so we will pause\r\nto complete the demo\r\nnow that mimikatz loaded\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 20 of 24\n\nalso we got user hamzag credentials\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 21 of 24\n\nnow we have domain admin credentials\r\nNow we load Invoke-WMIExec.ps1 to do pass the hash attack using wmi\r\nNow in order to use Invoke-WMIExec we need to encode our payload so we don’t have issue with\r\ncharacters escaping so we use python ( make user to utf-8 encode )\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 22 of 24\n\nas you can see the payload executed and the agent connected\r\nnow we are in the DC\r\nThank you for reading my article . you can find the muddyc3 with payload.ps1 ( powershell agent POC ) here :\r\nMuddyc3-Revived\r\ni will release my tool which built on top of muddyc3 soon. right now it include below features and there is more\r\nam working on :\r\nfull encryption of modules and command channel\r\nget encryption key on the fly ( not hard coded )\r\ntake screenshots and send it encrypted to C2\r\nupload files from C2\r\ndownload files from the victim\r\nstaged payloads to bypass detection\r\nbypasses AVs ( tested on kaspersky and trendmicro )\r\nset the beacon interval dynamically even after the agent connected\r\ndynamic URLs\r\nset the configuration one time ( will not ask for IP:port each time )\r\nbug fixes and stable version\r\nglobal kill switch to end campaigns\r\nPurple Teamer , coder who obsessed in information security and will never stop learning . certified : OSCP , CRTP\r\n, DFIRP , DFIRA , CEHV9 , CCNA R\u0026S , CCNA Cyber Ops , Splunk Power , SPlunk Core\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 23 of 24\n\nSource: https://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nhttps://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/\r\nPage 24 of 24\n\n https://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/     \nthis screenshot from the cmd.py which shows the list of commands and the function it should run\nWebserver.py Functions : the web server has a list of urls for each module some of the URLs will work with\nGET and other with POST depending how the function configured. below is a summary of the functions i created\nan agent for it :      \nits start by defining the web server listener and urls variable that include the url with its module \n   Page 9 of 24   \n\n  https://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/ \naccessing the server with url /get provided us with payload\nthe same with /getc we got the payload encoded with base52\n   Page 11 of 24",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"origins": [
		"web"
	],
	"references": [
		"https://shells.systems/reviving-leaked-muddyc3-used-by-muddywater-apt/"
	],
	"report_names": [
		"reviving-leaked-muddyc3-used-by-muddywater-apt"
	],
	"threat_actors": [
		{
			"id": "02e1c2df-8abd-49b1-91d1-61bc733cf96b",
			"created_at": "2022-10-25T15:50:23.308924Z",
			"updated_at": "2026-04-10T02:00:05.298591Z",
			"deleted_at": null,
			"main_name": "MuddyWater",
			"aliases": [
				"MuddyWater",
				"Earth Vetala",
				"Static Kitten",
				"Seedworm",
				"TEMP.Zagros",
				"Mango Sandstorm",
				"TA450"
			],
			"source_name": "MITRE:MuddyWater",
			"tools": [
				"STARWHALE",
				"POWERSTATS",
				"Out1",
				"PowerSploit",
				"Small Sieve",
				"Mori",
				"Mimikatz",
				"LaZagne",
				"PowGoop",
				"CrackMapExec",
				"ConnectWise",
				"SHARPSTATS",
				"RemoteUtilities",
				"Koadic"
			],
			"source_id": "MITRE",
			"reports": null
		},
		{
			"id": "2ed8d590-defa-4873-b2de-b75c9b30931e",
			"created_at": "2023-01-06T13:46:38.730137Z",
			"updated_at": "2026-04-10T02:00:03.08136Z",
			"deleted_at": null,
			"main_name": "MuddyWater",
			"aliases": [
				"TEMP.Zagros",
				"Seedworm",
				"COBALT ULSTER",
				"G0069",
				"ATK51",
				"Mango Sandstorm",
				"TA450",
				"Static Kitten",
				"Boggy Serpens",
				"Earth Vetala"
			],
			"source_name": "MISPGALAXY:MuddyWater",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		},
		{
			"id": "156b3bc5-14b7-48e1-b19d-23aa17492621",
			"created_at": "2025-08-07T02:03:24.793494Z",
			"updated_at": "2026-04-10T02:00:03.634641Z",
			"deleted_at": null,
			"main_name": "COBALT ULSTER",
			"aliases": [
				"Boggy Serpens ",
				"ENT-11 ",
				"Earth Vetala ",
				"ITG17 ",
				"MERCURY ",
				"Mango Sandstorm ",
				"MuddyWater ",
				"STAC 1171 ",
				"Seedworm ",
				"Static Kitten ",
				"TA450 ",
				"TEMP.Zagros ",
				"UNC3313 ",
				"Yellow Nix "
			],
			"source_name": "Secureworks:COBALT ULSTER",
			"tools": [
				"CrackMapExec",
				"Empire",
				"FORELORD",
				"Koadic",
				"LaZagne",
				"Metasploit",
				"Mimikatz",
				"Plink",
				"PowerStats"
			],
			"source_id": "Secureworks",
			"reports": null
		},
		{
			"id": "3c430d71-ab2b-4588-820a-42dd6cfc39fb",
			"created_at": "2022-10-25T16:07:23.880522Z",
			"updated_at": "2026-04-10T02:00:04.775749Z",
			"deleted_at": null,
			"main_name": "MuddyWater",
			"aliases": [
				"ATK 51",
				"Boggy Serpens",
				"Cobalt Ulster",
				"G0069",
				"ITG17",
				"Mango Sandstorm",
				"MuddyWater",
				"Operation BlackWater",
				"Operation Earth Vetala",
				"Operation Quicksand",
				"Seedworm",
				"Static Kitten",
				"T-APT-14",
				"TA450",
				"TEMP.Zagros",
				"Yellow Nix"
			],
			"source_name": "ETDA:MuddyWater",
			"tools": [
				"Agentemis",
				"BugSleep",
				"CLOUDSTATS",
				"ChromeCookiesView",
				"Cobalt Strike",
				"CobaltStrike",
				"CrackMapExec",
				"DCHSpy",
				"DELPHSTATS",
				"EmPyre",
				"EmpireProject",
				"FruityC2",
				"Koadic",
				"LOLBAS",
				"LOLBins",
				"LaZagne",
				"Living off the Land",
				"MZCookiesView",
				"Meterpreter",
				"Mimikatz",
				"MuddyC2Go",
				"MuddyRot",
				"Mudwater",
				"POWERSTATS",
				"PRB-Backdoor",
				"PhonyC2",
				"PowGoop",
				"PowerShell Empire",
				"PowerSploit",
				"Powermud",
				"QUADAGENT",
				"SHARPSTATS",
				"SSF",
				"Secure Socket Funneling",
				"Shootback",
				"Smbmap",
				"Valyria",
				"chrome-passwords",
				"cobeacon",
				"prb_backdoor"
			],
			"source_id": "ETDA",
			"reports": null
		}
	],
	"ts_created_at": 1775441467,
	"ts_updated_at": 1775826711,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/abe5c0cc8b169ac1d264a85bad0caf4c63f450e3.pdf",
		"text": "https://archive.orkl.eu/abe5c0cc8b169ac1d264a85bad0caf4c63f450e3.txt",
		"img": "https://archive.orkl.eu/abe5c0cc8b169ac1d264a85bad0caf4c63f450e3.jpg"
	}
}