Threat Research

Analysis of a Fresh Variant of the Emotet Malware

By Xiaopeng Zhang | February 18, 2019

Breaking Threat Analysis research paper by FortiGuard Labs    

 

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

Figure 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.

Figure 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.

Figure 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”.

Figure 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;

        break;

      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;

        }

        else

        {

LABEL_7:

          HIDWORD(qword_307C94) = 4;

        }

        break;

      case 3:

        HIDWORD(qword_307C94) = 0;

        v8 = GetTickCount();

        v9 = sub_2FCB20();

        HIDWORD(qword_307C94) = 3;

        LODWORD(qword_307C94) = v9 + v8;

        break;

      case 4:

        SetEvent(dword_304C0C);

        break;

      default:

        return;

    }

  }

}

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”.

Figure 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.

Figure 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.

Figure 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.

Figure 8. Adding the new auto-run entry
Figure 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. 

Figure 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.

As in its previous version, the IP list of C&C servers is hardcoded into its memory and is saved in a global variable. Each IP and port pair uses 8 bytes, and there are 62 C&C servers in total. Below is the IP and port list hardcoded in this version:

01> 71.91.161.118 : 21

02> 70.164.196.211 : 995

03> 175.101.79.120 : 80

04> 187.233.136.39 : 143

05> 5.107.250.192 : 995

06> 50.224.156.190 : 8080

07> 5.107.161.71 : 993

08> 186.179.243.7 : 995

09> 71.240.202.13 : 443

10> 190.215.53.85 : 80

11> 133.242.164.31 : 7080

12> 115.71.233.127 : 443

13> 69.136.227.134 : 22

14> 216.49.114.172 : 443

15> 153.121.36.202 : 7080

16> 181.119.30.27 : 995

17> 70.164.196.211 : 20

18> 98.157.215.153 : 80

19> 62.75.187.192 : 8080

20> 189.234.165.149 : 8080

21> 154.72.75.82 : 20

22> 45.123.3.54 : 443

23> 217.13.106.160 : 7080

24> 75.99.13.124 : 7080

25> 198.74.58.47 : 443

26> 69.195.223.154 : 7080

27> 172.114.175.156 : 8080

28> 73.124.73.90 : 20

29> 74.80.16.10 : 80

30> 24.11.67.222 : 443

31> 181.143.53.227 : 21

32> 173.76.44.152 : 20

33> 208.78.100.202 : 8080

34> 47.44.164.107 : 993

35> 45.63.17.206 : 8080

36> 50.31.0.160 : 8080

37> 62.75.191.231 : 8080

38> 98.142.208.27 : 443

39> 78.187.172.138 : 7080

40> 67.205.149.117 : 443

41> 98.186.90.192 : 443

42> 5.230.147.179 : 8080

43> 50.240.162.242 : 995

44> 94.76.200.114 : 8080

45> 178.62.37.188 : 443

46> 83.222.124.62 : 8080

47> 70.184.83.93 : 20

48> 173.255.196.209 : 8080

49> 208.107.230.235 : 20

50> 186.179.80.102 : 443

51> 72.95.118.97 : 21

52> 162.250.19.59 : 80

53> 134.129.126.86 : 443

54> 69.198.17.7 : 8080

55> 8.17.46.42 : 53

56> 70.90.183.249 : 7080

57> 47.149.54.132 : 8080

58> 200.116.160.31 : 80

59> 175.143.84.108 : 50000

60> 178.254.31.162 : 8080

61> 175.110.104.150 : 20

62> 211.115.111.19 : 443

Solution:

This malicious Word document has been detected as “VBA/Agent.AFD!tr.dldr”, and the original Emotet file has been detected as “W32/Emotet.GBUH!tr” by the FortiGuard AntiVirus service.

We also developed an IPS signature named “Emotet.Botnet” to detect the traffic between the C&C server and the victim.

The URLs to download Emotet have been rated as “Malicious Websites” by the FortiGuard WebFilter service.

IoC:

URL:

"hxxp://muathangnhom.com/6DOpkmOL9_yfO"

"hxxp://gmcvietnam.vn/abMbIaTzHSDkAq"

"hxxp://hugoclub.sk/yCq4xkYzeqAJK_v"

"hxxp://foreprojects.webedge.com.ng/Lc3UYXyQixr_Dp"

"hxxp://evonline.liceoriosdechile.com/NpDgofVhpankbq_I8AaJbzQj"

Sample SHA256:

PAY09735746167553.doc:

1194bab2c4a8e63e59ef01220ebe8e4d3511b12a16da30e713c2fbee6c2cb520

Downloaded Emotet/Original Exe file:

7C5CDC5B738F5D7B40140F2CC0A73DB61845B45CBC2A297BEE2D950657CAB658

 

Learn more about FortiGuard Labs and the FortiGuard Security Services portfolioSign up for our weekly FortiGuard Threat Brief. 

Know your vulnerabilities – get the facts about your network security. A Fortinet Cyber Threat Assessment can help you better understand: Security and Threat Prevention, User Productivity, and Network Utilization and Performance.

Read about the FortiGuard Security Rating Service, which provides security audits and best practices.