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.
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.
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.
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.
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.
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”.
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
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.
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.
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.
It then collects following information from the victim’s system
- Computer name
- Volume information of OS directory
- 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.
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
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)