Analysis of a Fresh Variant of the Emotet Malware

by certadmin

Emotet is not a new malware family. In fact, it’s been around for several years. We captured a JS file spreading Emotet in 2017, which I then analyzed it and published two research papers on it, Part I and Part II.

Recently, FortiGuard Labs captured a fresh variant of Emotet. This time, it’s embedded in a Microsoft Word document. I did a quick analysis on it, and in this blog I’ll show you how it works on a victim’s machine.

Word Sample with Macro

Fortinet FortiGuard Labs Threat ResearchFigure 1. The word file is opened with a security warning

The original file name of this infected document is PAY09735746167553.doc, and it contains malicious VBA code (Visual Basic for Applications) in a Macro. Figure 1 shows its content when it’s opened in Microsoft Word. The malicious VBA code is executed automatically using its “autoopen”  function once a victim clicks the button “Enable Content”, as shown in Figure 1. After a period of time it generates a ton of PowerShell code and then executes it. This generated PowerShell code downloads the actual Emotet file from several URLs that are dynamically generated, as shown in Figure 2.

Fortinet FortiGuard Labs Threat ResearchFigure 2. PowerShell code downloads and executes Emotet

Emotet is Relocated to %LocalAppData%

The downloaded file is the Emotet malware. The name it uses is random string, and it is located in the %temp% folder. When it runs, it compares the file path of current process, and if it is not the same as %LocalAppData%\culturesource\culturesource.exe, it moves the original exe file from the %temp% folder to the above folder (it even creates the folder if it doesn’t already exist) and renames it as culturesource.exe. The word “culturesource” is a constant string decrypted from its memory.

Below is the relevant ASM code snippet. It calls API SHFileOperationW to perform the file relocation. It is called in a Timer callback function, which I’ll talk more about later.


002FFB9A loc_2FFB9A:                             ; CODE XREF: sub_311D78+1Fj

002FFB9A   call  ds:memset

002FFBA0   call  sub_2F1250      ;;;CreateDirectoryW

002FFBA5   push  1Eh

002FFBA7   lea   eax, [ebp-20h]

002FFBAA   push  edi

002FFBAB   push  eax

002FFBAC   call  ds:memset

002FFBB2   add   esp, 18h

002FFBB5   mov   dword ptr [ebp-1Ch], 1  ;; FO_MOVE

002FFBBC   lea   eax, [ebp-20h]         ; SHFILEOPSTRUCTA structure

002FFBBF   mov   dword ptr [ebp-18h], offset unk_3083F8 ; ; current file path in %temp% folder.

002FFBC6   mov   esi, 0E14h

002FFBCB   mov   dword ptr [ebp-14h], offset

word_307EE0 ;  %LocalAppData%\culturesource\culturesource.exe.

002FFBD2   mov   [ebp-10h], si

002FFBD6   push  eax

002FFBD7   call  ds:SHFileOperationW

002FFBDD   test  eax, eax

002FFBDF   jnz   short loc_2FFBEA

002FFBE1   cmp   [ebp-0Eh], edi

002FFBE4   jz    loc_2FFCA0


Finally, it calls the API CreateProcessW to run the culturesource.exe file and it then exits the current process.

Anti-Analysis Technique

Next, the malware starts a second process of culturesource.exe, which is where holds and will perform Emotet’s major functions. Once the second culturesource.exe is running normally, the first one exits. Emotet then dynamically releases code and data into a number of memory blocks, which then take over the follow-up task for Emotet.

Most of the functions are split into multiple parts. I’ll pick one to show you how it uses this trick. Figure 3 shows that a normal function was split into seven parts, which are all connected using “jmp” instructions, to increase the difficulty of code analysis.

Fortinet FortiGuard Labs Threat ResearchFigure 3. A function split into seven parts

All strings are encrypted, and they are then decrypted before being used during the runtime.

All imported API are also encrypted, and are all also decrypted at the beginning of their execution. Figure 4 shows a code snippet that decrypts a string “user32.dll” from “unk_3031F0”. It calls the API LoadLibraryW to load “user32.dll”, and it then uses the decrypted API information to find the exported APIs in the module “user32.dll”.

Fortinet FortiGuard Labs Threat ResearchFigure 4. Decrypted string and loaded API from user32.dll

Timer Function

Emotet also uses a Windows Timer event to execute its code. In my previous analysis, it used the “WindowProc” function to capture a Timer message to perform malicious activities. It’s a little bit different in this version. Here, it directly uses the timer callback function.

When it calls the API SetTimer, it sets the interval time to 1000. This means that the callback function is called once every 1000 milliseconds. Below is the pseudocode of this callback function.

void __stdcall Timer_fun(int a1, int a2, int a3, int a4)


unsigned int v4; // esi@6

int v5; // eax@6

unsigned int v6; // esi@15

int v7; // eax@15

int v8; // esi@16

int v9; // eax@16


if ( qword_307C94 <= (unsigned __int64)(unsigned int)GetTickCount() )


switch ( HIDWORD(qword_307C94) )


case 1:

HIDWORD(qword_307C94) = 0;

if ( !sub_2F6BA0() || !sub_2F7170() || check_if_process_is_in_correct_path() )

goto LABEL_7;

v4 = GetTickCount() % 0xBB8u;

v5 = GetTickCount();

HIDWORD(qword_307C94) = 2;

LODWORD(qword_307C94) = v4 + v5 + 3000;


case 2:

HIDWORD(qword_307C94) = 0;

if ( sub_2F8300()

&& sub_2F8430()

&& sub_2F8B20()

&& sub_2F95B0()

&& sub_2FA320()

&& sub_2FB750()

&& sub_2F68D0() )


dword_307CC4 = (int)&unk_3080E8;

dword_307CC8 = (int)&unk_303430;

dword_307CCC = 106;

v6 = GetTickCount() % 0xBB8u;

v7 = GetTickCount();

HIDWORD(qword_307C94) = 3;

LODWORD(qword_307C94) = v6 + v7 + 3000;





HIDWORD(qword_307C94) = 4;



case 3:

HIDWORD(qword_307C94) = 0;

v8 = GetTickCount();

v9 = sub_2FCB20();

HIDWORD(qword_307C94) = 3;

LODWORD(qword_307C94) = v9 + v8;


case 4:








In case 0, one of its purposes is to relocate the process to the expected position with the file name that I mentioned before. It also collects the computer name, file system, and volume by calling the APIs GetComputerNameW and GetVolumeInformationW. It puts the two data sets together and saves them in a global variable, which is used in the C&C server as the ID for this victim. That ID will then be used in the packets that communicate with the C&C server. Emotet then calculates a CRC32 of its EXE file and saves it in another global variable, which is used when sending the first packet to the C&C server. I’ll talk about that in next section.

Another purpose is to set up a Windows service named “culturesource” for running Emotet at Windows startup, when it can open the “Service Control Manager” successfully (by calling the API OpenSCManagerW). Meanwhile, “culturesource.exe” is moved to the folder “%windir%\system32”. Figure 5 shows a screenshot of the installed service “culturesource”, whose Startup type is “Automatic”.

Fortinet FortiGuard Labs Threat ResearchFigure 5. Screenshot of the service “culturesource”

Case 1 is used to initialize a number of DLL modules and decrypt the exported API functions that Emotet uses, including “urlmon.dll”, “userenv.dll”, “wininet.dll” and so on.

Case 2 is the main branch. It collects data from the victim’s system and sends that data to its C&C server, as well as executes commands from the C&C server.

Communication with C&C server

The malware calls several API functions to collect information. For example, it calls “RtlGetVersion” to obtain the Windows version information, and “GetNativeSystemInfo” to gather system and CPU information. It also picks a DWORD value at offset 0x1D4 of PEB, which is defined as SessionID.

Emotet continues to collect the names of running processes by calling the APIs CreateToolhelp32Snapshot, Process32FirstW, and Process32NextW.  The next step is to put all collected data together into a structure and then encrypt the entire data set. Figure 6 shows that the data has been copied into a structure. The values in red rectangle are flags to indicate what the following data is. The string behind ‘12’ is the computer name, the data behind ‘18’ is the native system information, and the byte after ‘20’ is the SessionID from PEB. The DWORD value next to ‘2D’ is the CRC32 value of Emotet, the string following ‘32’ is the collected process name list, and the value with a blue underscore is the length of the following data, which uses a kind of utf-8 encoding.

As I mentioned in my previous blog, its C&C server can check if there are analysis tools (like wireshark, debuggers, etc.) running on the victim’s machine. If detected, it will not reply with available data.

Fortinet FortiGuard Labs Threat ResearchFigure 6. Put data together in a structure

After the data is encrypted, it is encoded using Base64. Moreover, it then disguises the Base64 code as a Cookies value of an HTTP header. You can see the Base64 code in Figure 7.

Fortinet FortiGuard Labs Threat ResearchFigure 7. Send collected data to C&C server

In Figure 7, you can also see the C&C server replies back with some data. When the device receives data for the first time from the C&C server, it creates an auto-run entry named “cultruesource” under the sub-key “HKCU\Software\Microsoft\Windows\CurrentVersion\Run” in the system registry. Now it has two ways to start Emotet, i.e. the system service and the auto-run in the system registry. In Figures 8 and 9 you can see more information about adding the auto-run entry to the registry.

Fortinet FortiGuard Labs Threat ResearchFigure 8. Adding the new auto-run entry
Fortinet FortiGuard Labs Threat ResearchFigure 9. Screenshot of the added auto-run entry “culturesource” in the Registry Editor

By decrypting the received data, I am able to get a PE file, as you can see in Figure 10. From my analysis, I found that the decrypted PE file is another Emotet. It is just used to upgrade itself.

Fortinet FortiGuard Labs Threat ResearchFigure 10. Decrypted data from the C&C server

So far, this is my analysis for this new variant. I will continue to monitor this Emotet campaign for additional functions and changes.



Interdit de copier  ce contenu