Deep Analysis of Emotet Banking Trojan (TA542 APT)
Emotet Live Cycle
First Stage: Microsoft Word Document [Downloader]
Fingerprint | Value |
---|---|
MD5: | 57be28414e61ff58a6b52fc3c1b70b7f |
SHA-1: | c4fbb54b194c1303897ac869811a274303d27f38 |
SHA-256: | 01b1232dee4ac560ba34061aa65f5de79c7182de3b6f313ad1a83c39ce61550c |
File Type: | Composite Document File V2 Document |
Create Time/Date: | Fri Mar 15 16:04:00 2019 |
The first stage of this malware is an microsoft Word formats (.doc) use VBA (Visual Basic for Applications) AutoOpen macros to execute code that downloads the Emotet loader. Emotet Word documents contain embedded images that request the user to click the Enable Editing
button to disable Microsoft Word’s read-only mode (Protected View) and Enable Content
to cause the macro to run.
To view the macro click on Developer tab, click Visual Basic and you can see the macro.
![]() |
![]() |
VBA Analysis
The documents contain obfuscated VBA code let’s analysis the most important parts in it
autoopen()
function which gets executed when the document is opened
powershell -e
first thing after execution the code creation of string by “powershell -e”.
dBCWQQZ = winmgmts:Win32_Process
then variable dBCwQQZ is defined with the string “winmgmts:Win32_Process”.
TCXD_U =GetObject(winmgmts:Win32_ProcessStartup)
then variable TCXD_U is defined with the string “GetObject(winmgmts:Win32_ProcessStartup)”.
GetObject(winmgmts:Win32_ProcessStartup).ShowWindow = 0
then sets the parameter of “GetObject(winmgmts:Win32_ProcessStartup).ShowWindow” to a value of 0.
jDD_UwDB = GetObject(winmgmts:Win32_Process).Create
Variable jDD_UwDB is defined with the string “GetObject(winmgmts:Win32_Process).Create”.
We can conclude from those parts the VBA code references Windows Management Instrumentation (WMI) classes winmgmts:Win32_ProcessStartup and winmgmts:Win32_Process. The macro uses WMI (Windows Management Instrumentation) to indirectly run PowerShell. The process is launched as a child process of WmiPrvSe.exe (WMI Provider Host).
PowerShell Analysis
extract powershell string:
Base64 encoded, after decoded:
After decoding the Base64 encoded string, the output illustrated in Figure is produced. The command is obfuscated using the same string joining and case mismatch techniques to evade detection. The decoded string contains many +
characters that are used to concatenate strings, and a mixture of uppercase and lowercase characters. By removing all the +
and ''
characters the deobfuscated command is revealed:
![]() |
![]() |
The PowerShell command above compress and decodes another Base64 encoded string and reads it as a flow until it reaches the end of the chain. Then it runs the resulting output in memory using the iex
alias of the Invoke-Expression cmdlet. This is a technique for executing commands in memory without saving files to disk. The command uses the variable $Verbosepreference
which contains the string SilentlyContinue
. The first and third characters (i
and e
) are identified from the string, which are then joined by X
, to form the text string ieX
.
The de obfuscated PowerShell script first splits the string assigned to the variable $XXQCZAxA using the “@” character as a delimiter and then enters a ForEach loop, which iterates the resulting array of URLs(hxxp://dautudatnenhoalac[.]com/wp-admin/DYAsI/)(hxxp://www.bewebpreneur[].]com/wp-admin/daHN/) to download the Emotet loader to the victim’s filesystem using the Net.WebClient
class. The script uses the environment variable $env:userProfile
to fetch the user profile directory of the currently logged-in user. The downloaded file is saved to the victim’s user profile directory (typically C:\Users\[Username])
and set the file name with variable TQQZoAGU
and this variable it equal 15 so the file will drop it called 15.exe
![]() |
![]() |
![]() |
As we can see when we run the command, it sends a HTTP GET request to retrieve the second-stage Emotet executable from (hxxp://dautudatnenhoalac[.]com/wp-admin/DYAsI). The response from the web server indicates that the file served is called s17zjCTuWfNF.exe and that the payload is a PE format file as indicated by the ASCII representation of the magic bytes 0x4D5A MZ
at the start of the file.
Notice: The ForEach loop exits when check the file is large than 40 KB but when used fake net you will see the file is 2kb cause it's fake simulation. run the file to see real executable file
And here it is, as we mentioned before the macro uses WMI (Windows Management Instrumentation) to indirectly run PowerShell. The process is launched as a child process of WmiPrvSe.exe (WMI Provider Host).
Second Stage: Executable File
Fingerprint | Value |
---|---|
MD5: | 322f9ca84dfa866cb719b7aecc249905 |
SHA-1: | 147ddeb14bfcc1ff2ee7ef6470ca9a720e61aeaa |
SHA-256: | af2f82adf716209cd5ba1c98d0dcd2d9a171bb0963648bd8bd962edb52761241 |
File Type: | PE32 executable (GUI) Intel 80386, for MS Windows |
File Size: | 428808 bytes |
Compiled: | Fri Mar 15 19:49:00 2019 |
Static Analysis
in sections, notice in the .rsrc
(resource) the file in front of us occupies only 51% of the real file space, which means that the program is packed.
![]() |
![]() |
We notice in the resource label, there are two unfamiliar resources called EXCEPT and CALIBRATE, the EXCEPT
have high entropy and large size This makes you think that it is encrypted payload. After dumbed the resource we notice there are encrypted data.
Behavioral Analysis
First: After, downloading the emotet it lunches itself and first launcher lunches another instance from the same location(C:\Users[username]) as a child process and copied itself to C:\Windows\SysWOW6
with different name, in my stat the name is devneutral.exe
The process creates a service to indirectly launch the loader. In the call to CreateService
, the BinaryPath points to C:\Windows\SysWOW64\devneutral.exe
and the DesiredAccess is 18. This value grants SERVICE_CHANGE_CONFIG
and SERVICE_START
access permissions to the service.
And, create some libraries, read them as we can see:
After, read the created libraries, we notice in threads and process activity it loaded it and their some interesting libraries like: kernall32.dll - crypt32.dll - mswsock.dll - urlmon.dll
.
And, here all registries it implementation with emotet and interesting one is {aa5b6a80-b834-11d0-932f-00a0c90dcaa9}
which is passed as a parameter to RegOpenKeyA
. This registry key is required for the Windows scripting engine interface
After registering itself as service, devneutral.exe
is launched by services.exe. and downloads the next stage payload from a remote server.
Then collects system information and sends it through an encrypted channel to its command and control (C2) servers in the data section of HTTP POST requests and receives further commands and payloads from the servers as a response. The loader also downloads modules to extend the functionality of the loader as well as other malware families.
![]() |
![]() |
Notice: Emotet sent encrypted C2 data as cookie values in the headers of HTTP GET requests.
Binary Analysis
The start
function that generates an array of characters and has a conditional while (true) infinite loop. The function works by reading a Windows Registry key through a call to RegOpenKeyA
. If the key is not found, the malware enters an infinite loop
![]() |
![]() |
The sub_401A90
function decodes a string with the value interface\{aa5b6a80-b834-11d0-932f-00a0c90dcaa9}
(mentioned it before) which is passed as a parameter to RegOpenKeyA
![]() |
![]() |
The important function, It sparked my attention is VirtualAllocEx
. This function is used to allocate memory in a remote process and is often used by emotet for process injection. We will start by putting a breakpoint on the return address for VirtualAllocEx
.
First: After, open 15.exe
in x32dbg go to symbols
, search for VirtualAlloc
, but breakpoint on the address of function VirtualAllocEx
and run.
Then: but breakpoint on ret
(return of function) and run.
If we run until the breakpoint, we see that emotet creates an allocation of memory at 0x00011200
. It then copies a code stub from the .data section of the mapped image at 0x00470000 to the newly allocated memory space and gives control to it.
![]() |
![]() |
Before breakpoint:
Emotet then deobfuscates API and DLL names from the code copied to 0x00011200
, like LoadLibraryExA
, kernel32.dll
and VirtualAlloc
![]() |
![]() |
It then calls GetProcAddress
from kernel32.dll
to get the addresses of the decoded API names.
The functions decoded:
LoadLibraryExA
GetProcAddress
VirtualAlloc
GetModuleHandleA
UnmapViewOfFile
WriteFile
SetFilePointer
Sleep
LstrlenA
LstrcatA
VirtualProtect
CloseHandle
VirtualFree
GetTempPathA
CreateFileA
The emotet loader calls GetProcAddress
for an invalid function name called mknjht34tfserdgfwGetProcAddress
. Since this is invalid, the function returns a null value with an error code of 0000007F (ERROR_PROC_NOT_FOUND)
.
Once the code stub has retrieved the function addresses, VirtualAlloc
is called to allocate another memory region where it writes the decrypted PE file from the .data section of 15.exe, rather than from the .rsrc
section.
Third Stage: Unpacked Executable File
Fingerprint | Value |
---|---|
MD5: | D623BD93618B6BCA25AB259DE21E8E12 |
SHA-1: | BBE1BFC57E8279ADDF2183F8E29B90CFA6DD88B4 |
SHA-256: | 01F86613FD39E5A3EDCF49B101154020A7A3382758F36D875B12A94294FBF0EA |
Dumping the executable and examining it reveals that it is another packed Emotet binary that contains the main loader.
After API name resolution, GetCurrentProcessId is called to get the process ID (PID) of Emotet‘s running process. Afterwards, Emotet iterates through all running processes to find its module name and parent PID. Once it finds its parent PID, it creates two mutexes with the format PEM%X. One of the mutexes is created using the parent process ID (PEM[PPID]) and the other uses its own PID (PEM[PID]).
After creating these mutexes, it calls CreateEventW to create an event using the format PEE%X, where %X is its parent PID. If both mutexes are successfully created, it launches 15.exe again from the same path. After launching the child process, it calls WaitForSingleObject on the PEE%X event.
We have seen in some of the Emotet samples that it launches child process with a command line switch. This command line switches are an indication that an Emotet process has been launched as a child process and has to perform a designated task.
The launched child process does everything same until it evaluates whether to create the two mutexes described above. This time the call to CreateMutex for mutex PEM[PPID] fails with the error “ERROR_ALREADY_EXISTS”. After the mutex creation fails in the child process, it signals the event PEE[PPID] to the parent process 15.exe. The parent process exits from a waiting state and then terminates itself.
IOCs
Hashes (MD5):
First Stage: 57be28414e61ff58a6b52fc3c1b70b7f
Second Stage: 322f9ca84dfa866cb719b7aecc249905
Third Stage: D623BD93618B6BCA25AB259DE21E8E12
Domains Requests:
hxxp://dautudatnenhoalac[.]com/wp-admin/DYAsI/
hxxp://www.bewebpreneur[.]com/wp-admin/daHN/
hxxp://82.78.228[.]57:443/free/tlb/
IPs
103.237.145.132
192.241.233.63
82.78.228.57
References
https://app.any.run/tasks/1879ad1f-ac52-4fba-9230-9cffee29e6cc
https://medium.com/swlh/static-analysis-of-the-emotet-malware-f94b16aa8f70
https://www.malwarebytes.com/emotet/
https://www.fortinet.com/blog/threat-research/deep-dive-into-emotet-malware
https://www.fortinet.com/blog/threat-research/deep-dive-into-emotet-malware and Part [1,2]