Emotet is a downloader malware which has been used in many spam campaigns. A couple of weeks back my colleague uncovered the delivery mechanism and the initial components of the Emotet kill chain in this blog. We noticed that Emotet has been actively evolving its delivery mechanism to avoid detection. In 2019, right before the take down, it changed its payload from EXE to DLL. Right after that, botnets like Qbot and IcedID followed this pattern.  In the week prior to writing this blog, we observed Emotet making a sudden shift to 64-bit payloads. However, there is no change in its overall kill chain

Figure 1: Emotet  workflow
Figure 2: Emotet payload unpack flow

First level payload (Custom packed)

The first level payload was a 64-bit DLL executed by the spam document having the Emotet payload using regsvr32.exe.  First level payload was a custom packed DLL with a lot of random export functions with junk code. The malicious component was found only in WinMain and DllRegisterServer functions. 

Figure 3: 64bit Custom packed DLL export functions

The main function contains a lot of byte variables containing encrypted shell code which then allocates heap memory with “PAGE_EXECTUABLE_READWRITE” permission and proceeds to decrypt and execute the shell code.

Figure 4: Shell code decryption by custom packed DLL

Second level payload (Shell code) 

The shell code’s purpose is to load the DLL and API used in the next level of the payload, which decrypts the Emotet’s core payload.


Figure 5: Shell code load encrypted data from resource section

The shell code’s function was to decrypt and execute the 64-bit DLL payload which has Emotet’s main functionality. In order to avoid detection, the shell code copies the decrypted DLL file content to a heap memory without the DOS header. It then sets permission to regions of the copied file based on PE sections characteristics in the section header having the partial copied file using VirtualProtect API.

Figure 6: Decrypt third level payload which is Emotet’s main DLL
Figure 7: Copy decrypted PE file without DOS header to another heap memory
Figure 8: Partially Copied PE file

Then the shell code executes the main function of the third level DLL (partially copied DLL) which only checks the parameter and returns to the shell code. With this the main function and shell code execution is completed. After this regsvr32.exe executes the “DllRegisterServer” of first level Emotet export function which in turn executes the third level “DllRegisterServer”. 

Figure 9: Execution of third level payload from first level DLL

Emotet uses the control flow flattening technique to execute functions. All the function flow works based on setting random values in variables. After every function value is changed it checks the value and finds the next function to execute. Flow diagram of the control flow flattening is as shown below

Figure 10: Control flow flattening flow graph

Emotet also uses different functions for each API call. Every time it searches the API from PEB memory, It changes the windows DLL export name into a hash value to find the required API.

Figure 11: Get API address from loaded memory

Every string used in the Emotet for API argument is decrypted at the time it is needed and removed from memory after it is used. Below is the screenshot of string “%s %s”, used in string concatenation, being decrypted.

Figure 12: String decryption loop

Emotet then copies itself to the ProgramData folder on its first run. It does so by comparing GetSystemTimeAsFileTime and GetFileInformationByHandleEx(_FILE_BASIC_INFO) with a constant value. Based on the result, the Emotet binary is self-copied in the folder ProgramData and deletes the “Zone.Identifier” component of the copied file or executes the Emotet’s main functionality. GetFileInformationByHandleEx(_FILE_BASIC_INFO) is used to retrieve file creation time from the zone identifier. Now the copied file will be less than the saved constant value.

Figure 13: Delete zone identifier of copied file

It then collects following information from the victim’s system  

  • Computer name
  • Volume information of OS directory
  • RtlGetVersion 
  • System native information
  • Malware execution path with file name 

All the collected information is encrypted using the Elliptic Curve Cryptography Algorithm. Following API flow is used to encrypt the data. Finally, they convert the encrypted data  to base64. 

  • BCryptOpenAlgorithmProvider
  • BcryptDeriveKey
  • BcryptGetproperty
  • BCryptImportKey
  • BcryptGetproperty
  • BCryptCreateHash 
  • BCryptHashData
  • BCryptEncrypt
  • CryptBinaryToStringW
Figure 14: Encrypt user information

C2 communication 

This third level payload decrypts a self-contained list of IP addresses which is used for C2  communication.

The converted base64 data is sent to the C&C.

Following APIs are used for C&C communication

  • HttpOpenRequestW
  • InternetOpenW
  • InternetConnectW
  • InternetQueryOptionW
  • InternetSetOptionW
  • InternetSendRequestW
Figure 15: Send user data to C&C

After this stage, emotet is known to use Cobalt Strike beacons to deploy ransomware payloads.

In K7labs we keep on monitoring Emotet and its changes, we detect it in every layer like core malware behavior to custom packer.


Indicators of Compromise (IOCs)

SHA256: 7ba37f9a23ec25972d767bbc32a1eb5b3840455bac9b93fddc5d81fd3d21b261


Like what you're reading? Subscribe to our top stories.

If you want to subscribe to our monthly newsletter, please submit the form below.

    0 replies on “Emotet takes the 64-bit Route”