{
	"id": "10e25e99-d238-42e2-9a49-ddfab2e014e3",
	"created_at": "2026-04-06T00:12:58.048088Z",
	"updated_at": "2026-04-10T03:24:23.626932Z",
	"deleted_at": null,
	"sha1_hash": "2cc8379b16f4e4fe650747e28d37e65bbd9dde74",
	"title": "Return of Emotet: Malware Analysis | Zscaler Blog",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 1064974,
	"plain_text": "Return of Emotet: Malware Analysis | Zscaler Blog\r\nBy Dennis Schwarz, Avinash Kumar\r\nPublished: 2021-12-13 · Archived: 2026-04-05 23:01:26 UTC\r\nKey Points\r\nEmotet is a downloader malware used to download and execute additional modules and payloads.\r\nIn January 2021, a law enforcement action disrupted the malware, its infrastructure, and some of its threat actors.\r\nAfter almost a year-long hiatus, Emotet returned to the threat landscape in November 2021.\r\nEmotet modules focus on credential theft, email theft, and spamming.\r\nSecondary Emotet payloads have reportedly been Cobalt Strike.\r\nThreatlabz has continued its analysis of the return of the prolific Emotet malware. In January 2021, a law enforcement\r\naction disrupted the Emotet malware and its infrastructure. This included the arrest of some of the threat actors involved\r\nwith Emotet. Emotet has returned to the threat landscape as of November 14, 2021 and picked up where it left off after\r\nalmost a year-long hiatus.\r\nThis blog is a follow up to our November 16, 2021 “Return of Emotet malware” post and focuses on the technical aspects of\r\nthe new version of the Emotet malware.\r\nAnti-Analysis Techniques\r\nTo make malware analysis and reverse engineering more difficult, Emotet uses a number of anti-analysis techniques. One of\r\nthe first ones that stands out is control flow flattening where the structure of the program’s control flow is removed, making\r\nit difficult to trace its execution. Figure 1 shows an example function where a randomized “control_flow_state” variable is\r\nused along with various while loops, if-else, switch, and other statements to confuse the analysis:\r\nFigure 1: Example function using control flow flattening\r\nAnother technique that stands out is Windows API function call hashing with randomized function argument ordering. The\r\nOpen Analysis HashDB IDA Plugin supports Emotet’s hashing algorithm which helps defeat this anti-analysis mechanism.\r\nEmotet encrypts all its important strings using an XOR-based algorithm and a per-string key. Figure 2 is an example IDA\r\nPython function that can be used to decrypt strings:\r\nimport struct\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 1 of 10\n\ndef decrypt_str(addr):\r\n    tmp = get_bytes(addr, 8)\r\n    xor_key = struct.unpack(\"I\", tmp[0:4])[0]\r\n    enc_len = struct.unpack(\"I\", tmp[4:8])[0]\r\n    str_len = xor_key ^ enc_len\r\n    plain_buf = b\"\"\r\n    enc_buf = get_bytes(addr+8, str_len)\r\n    num_dwords = int(str_len / 4)\r\n    for i in range(num_dwords):\r\n        enc_dword = struct.unpack(\"I\", enc_buf[i*4:i*4+4])[0]\r\n        plain_dword = xor_key ^ enc_dword\r\n        plain_buf += struct.pack(\"I\", plain_dword)\r\n    remaining_bytes = str_len % 4\r\n    if remaining_bytes:\r\n        last_enc_dword = struct.unpack(\"I\", enc_buf[-remaining_bytes:] + b\"\\x00\"*(4-remaining_bytes))[0]\r\n        last_plain_dword = xor_key ^ last_enc_dword\r\n        plain_buf += struct.pack(\"I\", last_plain_dword)[:remaining_bytes]\r\n    return plain_buf\r\nFigure 2: IDA Python function to decrypt strings\r\nConfiguration\r\nUsing the same encryption algorithm as for strings, Emotet stores three encrypted configuration items:\r\nCommand and Control (C2) IP addresses, ports, and “use TLS” flags\r\nAn Elliptic Curve Diffie Hellman (ECDH) public key used in C2 communications\r\nAn Elliptic Curve Digital Signature Algorithm (ECDSA) public key used to verify responses from a C2\r\nCommand and Control\r\nC2 communications is via HTTP requests. An example request looks like Figure 3:\r\nFigure 3: Example C2 request\r\nThe URI is randomly generated and data is encrypted in the Cookie header (a POST request is used for larger amounts of\r\ndata). The Cookie header contains a randomly generated key name and base64 encoded key value. Once decoded, the key\r\nvalue contains:\r\nA generated ECDH public key\r\nAES encrypted request data\r\nRandom bytes\r\nThe AES key used to encrypt request data is generated via the following method:\r\nThe generated ECDH private key and embedded ECDH public key are used with the BCryptSecretAgreement\r\nfunction to generate a shared secret between the malware and C2\r\nThe AES key is derived from the shared secret using the BCryptDeriveKey function\r\nPlaintext request data, command data, and response data use a basic data encoding to encode DWORDs and variable length\r\ndata. Request data contains the following:\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 2 of 10\n\nCommand number\r\nCommand data SHA256 hash\r\nCommand data\r\nAs an example, a “command poll” (command number 1) contains the following command data:\r\nBot ID (computer name and volume serial number)\r\nHash of malware process path\r\nBuild date (e.g. 20211114)\r\nMalware version (e.g. 10000)\r\nEncoded Windows version and architecture\r\nMalware process session ID\r\nOptional module acknowledgement\r\nResponse data is encrypted similarly to requests and once decrypted, the data is verified using the embedded ECDSA public\r\nkey. Once verified, the data contains a command number and optional arguments.\r\nCommands\r\nEmotet has three broad commands:\r\nRemove self\r\nNo operation / sleep\r\nProcess subcommand\r\nMost of the functionality is implemented in seven subcommands:\r\nSubcommand Notes\r\n1 Update self\r\n2 Load and execute Emotet module\r\n3 Download and execute an EXE\r\n4 Download and execute an EXE (as console user)\r\n5 Download and inject a DLL (DllRegisterServer export)\r\n6 Download and execute a DLL with regsvr32.exe\r\n7 Download and execute a DLL with rundll32.exe (Control_RunDLL export)\r\nThe core component of Emotet is a downloader used to download and execute additional modules and payloads (e.g. likely\r\nCobalt Strike).\r\nModules\r\nModules are DLL executables but require data from the Emotet core component and the received C2 command to run:\r\nBot ID\r\nEmbedded elliptic curve public keys\r\nModule ID (from C2 command)\r\nModule hash (from C2 command)\r\nModule argument (from C2 command)\r\nThey use the same set of anti-analysis features as the core component and contain their own list of C2s to send and receive\r\nadditional data and responses. Analysis of the modules is ongoing, but at the time of research, Threatlabz has observed the\r\nfollowing Emotet modules and functionality:\r\nModule ID Notes\r\n2 Process listing module\r\n19 Mail PassView module\r\n20 WebBrowserPassView module\r\n21 Outlook account stealer module\r\n22 Outlook email stealer module\r\n23 Thunderbird account stealer module\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 3 of 10\n\n24 Thunderbird email stealer module\r\n28 Email reply chain spam module\r\n29 Typical spam module\r\n36 Possibly a network proxy module\r\nMost of the observed modules focus on mail and web browser credential theft, stealing emails, and spamming. The stolen\r\nmail credentials and emails are most likely used to fuel the spam modules.\r\nSpam Module Analysis\r\nAs a deeper dive into one of the modules, let’s look at module ID 29. It is used to send typical spam messages (not reply\r\nchain spam). To download data for a spam campaign, the module sends command number “1007” with the following\r\ncommand data to its module specific C2 list:\r\nModule ID\r\nModule hash\r\nBot ID\r\nHardcoded 0\r\nOptional SMTP account identifier and status\r\nOptional spam message identifier\r\nThe C2 responds with encoded data in three lists:\r\nPresumably stolen SMTP account information used to send the spam (Figure 4)\r\nTo and from email addresses for the spam (Figure 5)\r\nSpam message details and attachment (Figure 6)\r\nFigure 4: Example of post-processed stolen SMTP account list\r\nFigure 5: Example of post-processed To/From email list\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 4 of 10\n\nFigure 6: Example of post-processed spam message template\r\nThe lists are used to create and execute a spam campaign. In the example above, the attachment was a maldoc with the\r\nSHA256 hash of eb8107b9e3162bd5b746d1270433cc26c961331c24fd4c9e90b2bf27902a7bc3.\r\nReply Chain Spam Module Analysis\r\nThe reply chain spam module (module ID 28) works similarly to the module just described. Let’s take a closer look at an\r\nexample spam campaign generated by this module.\r\nThe victim is tricked with a malspam using a reply-chain attack where an email thread has been stolen and pretends to be an\r\noriginal reply of the ongoing conversation (Figure 7):\r\nFigure 7: Stolen mail used in the campaign\r\nThe attached malicious document uses social engineering to get the victim to enable macros (Figure 8):\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 5 of 10\n\nFigure 8: Document with legitimate looking content to trick the user\r\nThe malicious macros are obfuscated (Figure 9):\r\nFigure 9: Macro code to deobfuscate HTML code\r\nThe deobfuscated macros show that Emotet is downloaded and executed (Figure 10):\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 6 of 10\n\nFigure 10: Partially deobfuscated HTML code to download and execute the Emotet payload\r\nConclusion\r\nAfter a law enforcement disruption and almost a year long hiatus, it seems Emotet is picking up where it left off. The\r\nmalware’s core functionality is downloading additional modules and payloads. Emotet modules focus on credential theft,\r\nemail theft, and spamming. Stolen credentials and emails are most likely used with the spamming modules to further the\r\nspread of Emotet. Stolen credentials along with Emotet’s secondary payloads (reportedly Cobalt Strike) are most likely used\r\nto provide initial access to ransomware operators and affiliates.\r\nCloud Sandbox Detection\r\nIndicators of Compromise\r\nIOC\r\nc7574aac7583a5bdc446f813b8e347a768a9f4af858404371eae82ad2d136a01\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 7 of 10\n\n81.0.236[.]93:443\r\n94.177.248[.]64:443\r\n66.42.55[.]5:7080\r\n103.8.26[.]103:8080\r\n185.184.25[.]237:8080\r\n45.76.176[.]10:8080\r\n188.93.125[.]116:8080\r\n103.8.26[.]102:8080\r\n178.79.147[.]66:8080\r\n58.227.42[.]236:80\r\n45.118.135[.]203:7080\r\n103.75.201[.]2:443\r\n195.154.133[.]20:443\r\n45.142.114[.]231:8080\r\n212.237.5[.]209:443\r\n207.38.84[.]195:8080\r\n104.251.214[.]46:8080\r\n138.185.72[.]26:8080\r\n51.68.175[.]8:8080\r\n210.57.217[.]132:8080\r\n-----BEGIN PUBLIC KEY-----\r\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEQF90tsTY3Aw9HwZ6N9y5+be9Xoov\r\npqHyD6F5DRTl9THosAoePIs/e5AdJiYxhmV8Gq3Zw1ysSPBghxjZdDxY+Q==\r\n-----END PUBLIC KEY-----\r\n-----BEGIN PUBLIC KEY-----\r\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE86M1tQ4uK/Q1Vs0KTCk+fPEQ3cuw\r\nTyCz+gIgzky2DB5Elr60DubJW5q9Tr2dj8/gEFs0TIIEJgLTuqzx+58sdg==\r\n-----END PUBLIC KEY-----\r\n8f683e032dd715da7fb470b0fb7976db35548139d91f4a1a3ad5d64f1ce8daad\r\n3c755a3a4bc5a4d229b98563262227d64ac18f5ff97d3b1f8fa37cfd30148142\r\n6f998e7f3aea5f5100e352135b089e585a7f95257d59a6c7b79a2fe3ae1445f4\r\nbc0c8796411e71eb962909b0db3b281a2eb68facd402cc88768867cdd1848431\r\n0ea7d56ea6cc2d838964dda792e148d872ebaab769a0d29abaf29009d6766ce7\r\nfe5c53781c3ea6def61f69f78ec92eb7a711f898190443bb67ff266494bf2a35\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 8 of 10\n\n8ea4c69f707693b58cac94842f88e63f49b893adf95cf5a9ba0adbe61ee0a0a9\r\ne730fb1b7466975558b9e22732c84c88ef6c447261f94bbb8b6d4cbc17fc95fd\r\n461648507a0ea26c886f1aeab55206a63457f1842106cb48533eb991cdf7d2d6\r\n40148daea1d5e04b0a756b827bd83a1e0f3c0bad3cd77361c52b96019eb7d1cc\r\n5b5fa30bf12f13f881708222824517d662f410b212a0f7f7ce5c611fd809f809\r\n{\r\n    \"BeaconType\": [\r\n        \"HTTPS\"\r\n    ],\r\n    \"Port\": 443,\r\n    \"SleepTime\": 5000,\r\n    \"MaxGetSize\": 1403644,\r\n    \"Jitter\": 10,\r\n    \"MaxDNS\": \"Not Found\",\r\n\"PublicKey\": \"MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCbcI0B4jpE0I6Ioj0qYRjoDYlN52X78HX2BZ1bBLV60oOeXcvOGi7Rxcz/\r\nmSpsw9M4x0dnUWFYPL2HUxzufEfchGPyxEnH6ASasVbS0OWqIkUsuri/5vJUvisrcKT9Ebodon8Z2AUqOaZZ8s37VUxJhSm4IxsLJ6WRgFkwIDA\r\nAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\r\n==\",\r\n    \"C2Server\": \"lartmana\\.com,/jquery-3.3.1.min.js\",\r\n    \"UserAgent\": \"Not Found\",\r\n    \"HttpPostUri\": \"/jquery-3.3.2.min.js\",\r\n    \"HttpGet_Metadata\": \"Not Found\",\r\n    \"HttpPost_Metadata\": \"Not Found\",\r\n    \"SpawnTo\": \"AAAAAAAAAAAAAAAAAAAAAA==\",\r\n    \"PipeName\": \"Not Found\",\r\n    \"DNS_Idle\": \"Not Found\",\r\n    \"DNS_Sleep\": \"Not Found\",\r\n    \"SSH_Host\": \"Not Found\",\r\n    \"SSH_Port\": \"Not Found\",\r\n    \"SSH_Username\": \"Not Found\",\r\n    \"SSH_Password_Plaintext\": \"Not Found\",\r\n    \"SSH_Password_Pubkey\": \"Not Found\",\r\n    \"HttpGet_Verb\": \"GET\",\r\n    \"HttpPost_Verb\": \"POST\",\r\n    \"HttpPostChunk\": 0,\r\n    \"Spawnto_x86\": \"%windir%\\\\syswow64\\\\dllhost.exe\",\r\n    \"Spawnto_x64\": \"%windir%\\\\sysnative\\\\dllhost.exe\",\r\n    \"CryptoScheme\": 0,\r\n    \"Proxy_Config\": \"Not Found\",\r\n    \"Proxy_User\": \"Not Found\",\r\n    \"Proxy_Password\": \"Not Found\",\r\n    \"Proxy_Behavior\": \"Use IE settings\",\r\n    \"Watermark\": 0,\r\n    \"bStageCleanup\": \"True\",\r\n    \"bCFGCaution\": \"False\",\r\n    \"KillDate\": 0,\r\n    \"bProcInject_StartRWX\": \"False\",\r\n    \"bProcInject_UseRWX\": \"False\",\r\n    \"bProcInject_MinAllocSize\": 17500,\r\n    \"ProcInject_PrependAppend_x86\": [\r\n        \"kJA=\",\r\n        \"Empty\"\r\n    ],\r\n    \"ProcInject_PrependAppend_x64\": [\r\n        \"kJA=\",\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 9 of 10\n\n\"Empty\"\r\n    ],\r\n    \"ProcInject_Execute\": [\r\n        \"ntdll:RtlUserThreadStart\",\r\n        \"CreateThread\",\r\n        \"NtQueueApcThread-s\",\r\n        \"CreateRemoteThread\",\r\n        \"RtlCreateUserThread\"\r\n    ],\r\n    \"ProcInject_AllocationMethod\": \"NtMapViewOfSection\",\r\n    \"bUsesCookies\": \"True\",\r\n    \"HostHeader\": \"\",\r\n    \"version\": 4\r\n}\r\nExplore more Zscaler blogs\r\nZscaler ThreatLabz 2024 Phishing Report\r\nThe Threat Prevention Buyer's Guide\r\nSource: https://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nhttps://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis\r\nPage 10 of 10",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.zscaler.com/blogs/security-research/return-emotet-malware-analysis"
	],
	"report_names": [
		"return-emotet-malware-analysis"
	],
	"threat_actors": [
		{
			"id": "610a7295-3139-4f34-8cec-b3da40add480",
			"created_at": "2023-01-06T13:46:38.608142Z",
			"updated_at": "2026-04-10T02:00:03.03764Z",
			"deleted_at": null,
			"main_name": "Cobalt",
			"aliases": [
				"Cobalt Group",
				"Cobalt Gang",
				"GOLD KINGSWOOD",
				"COBALT SPIDER",
				"G0080",
				"Mule Libra"
			],
			"source_name": "MISPGALAXY:Cobalt",
			"tools": [],
			"source_id": "MISPGALAXY",
			"reports": null
		}
	],
	"ts_created_at": 1775434378,
	"ts_updated_at": 1775791463,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/2cc8379b16f4e4fe650747e28d37e65bbd9dde74.pdf",
		"text": "https://archive.orkl.eu/2cc8379b16f4e4fe650747e28d37e65bbd9dde74.txt",
		"img": "https://archive.orkl.eu/2cc8379b16f4e4fe650747e28d37e65bbd9dde74.jpg"
	}
}