It provides a lot of technical details to follow Sakula evolution. Some parts of the article can be a bit long to read, but the fact to put constants, pathes, algorithms or others indicators in it is useful for reversers when they google some artefacts.

Type Version Seen Target’s activity *
RAT Sakula 2.0 11/07/2013
RAT Sakula 2.1 16/07/2013 Aerospace
RAT Sakula 2.2 24/09/2013
RAT Sakula 3.0a 07/01/2014
RAT Sakula 3.0b 27/02/2014
RAT Sakula 3.1a 16/05/2014
RAT Sakula 3.1b 09/07/2014 Healthcare
RAT Sakula 3.1c 10/07/2014 Healthcare
RAT Sakula 3.1d 18/09/2014 Government
RAT Sakula 3.2 09/01/2015

* Targets activity is only suspected from campaign ID found in binaries, and even if some of them are quite explicit, we cannot take them as direct evidences.

Version 2.0 to 2.2

Versions 2.x bring some minor features but implement essentially some protection mechanisms through the use of droppers, packers, stolen certificates and DLL Hijacking vulnerability.

After analysis, it appears that versions v2 and v3 evolved from the v1 (i.e. v3 doesn’t follow v2), as v2 updates are not present in v3.

v2.0 (11/07/2013)

The RAT has multiple layers of protection:

  • it is packed by UPX
  • it is embedded in a custom shellcode PE loader
  • it is embedded in a dropper

blackvinev2 2 arch

 

The dropper is a simple executable which:

  • Extract the payload which is located after the last section of the binary file
  • Decrypt it using a single-byte XOR-encryption (key=0x33)
  • Execute it by making a JMP on it

The custom PE loader is designed as a shellcode which:

  • loads its needed imports from a custom GetProcAddress routine
    • get the PEB (Process Environment Block) structure’s address (from FS[30])
    • get the LDR (PEB_LDR_DATA) structure’s address (from the PEB)
    • get each LDR_DATA_TABLE_ENTRY structure from the field LDR.InLoadOrderModuleList (list of loaded module)
    • look for each LDR_DATA_TABLE_ENTRY.BaseDllName and search for a module with a specific name checksum
    • get the module’s LDR_DATA_TABLE_ENTRY.DllBase which is the base address of the module
    • get the DOS_HEADER.lfa_new field (baseaddress+0x3C) which contains the PE header offset
    • get the IMAGE_DIRECTORY_ENTRY_EXPORT struture’s address (peheader+0x78)
    • get the AddressOfNames field (dd_export+0x20) (list of strings)
    • look for each procedure’s name and search for the index of the procedure with a specific name checksum
    • use the AddressOfNameOrdinals field (dd_export+0x24) to get the offset of the procedure from the found index
  • extracts its payload (the original PE file) located at the end of the shellcode
  • loads the PE payload in memory

The packer UPX is used on the previous payload, probably to reduce its size and obfuscate it.

Since its version 1.4, Sakula core has undergone some updates.

It is signed with a stolen certificate:

  • Certificate issued to NexG by VeriSign Class 3 Code Signing 2010 CA

sakula 3 0a 1 cert

 

It uses a new algorithm to decrypt its embedded exploits:

def decrypt_plugx(self, data, key):
    v1 = v2 = v3 = v4 = key
    decrypted = ""
    for c in data:
        v1 = (v1 + (v1 >> 3) - 0x1ACDF531) & 0xFFFFFFFF
        v2 = (v2 + (v2 >> 5) - 0x2CAFDCF2) & 0xFFFFFFFF
        v3 = (v3 + 0x34712393 - (v3 << 7)) & 0xFFFFFFFF
        v4 = (v4 + 0x46ADC7A4 - (v4 << 9)) & 0xFFFFFFFF

        xkey = (v1 + v2 + v3 + v4) & 0xFF

        decrypted += chr(ord(c) ^ xkey)

    return decrypted

This algorithm is not custom, as it was already seen in a PlugX sample (19d340cdc82d72705d0add94c8a43b0afe7e4f8cabc7c0f9abbb79cc55fc3c0d), dated 07/06/2013, with a different key (0xDF1D89DE). The key used in this version is 0x128933DF.

Before dropping its exploit to bypass UAC, it creates an event named Sakula and exits only if the exploit notifies its success via the event in the next 60 seconds.

When executed, the malware moves 3 files to a new location: itself, ./log.bin and ./OLEPRO32.DLL. At this moment, we don’t have these 2 last files, so their usefulness cannot be determined.

The method used to delete itself has been updated. It now gets the cmd path through %COMPSPEC% and executes it with the command /c del [FILENAME] > nul.

The configuration structure is:

struct ConfigV2_0
{
    CHAR    cc_domain[50];              //  115.47.35.117
    CHAR    uri_get1_folder[50];        //  /photo/
    CHAR    uri_get3_file[50];          //  script.asp
    CHAR    uri_get2_file[50];          //  /script.asp
    CHAR    uri_get3_arg[50];           //  imageid
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    CHAR    copy_file_path[50];         //  %Temp%\MicroMedia
    CHAR    campaign_id[12];            //  [REMOVED]
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
}

An example of used URIs:

  • POST /script.asp?imageid=[HASH_MACHINE_NAME]&type=[CMD_ID]&resid=[CMD_SEQ_NUM]&nmsg=up
  • GET (1) /photo/[HASH_MACHINE_NAME].jpg?resid=[CMD_SEQ_NUM]
  • GET (2) /script.asp?resid=[CMD_SEQ_NUM]&nmsg=del&photoid=[HASH_MACHINE_NAME]

v2.1 (16/07/2013)

All updates made in this version have been designed only for a unique use, and are not reused in other versions.

The dropper and the custom PE loader have been merged and UPX is not used anymore.

blackvinev2 1 arch 2

 

The code of the PE loader has been inserted into the dropper code. Consequently, we can suppose that the authors are the same.

There is a minor update on the old dropper code. Before decrypting its payload with the key 0x33, it decrypts 0x1000000 times its data with the key 0x32. This action is cryptographically useless (as two xor cancel themselves), but is equivalent to a Sleep.

This version is signed with stolen certificates:

  • Certificate issued to MICRO DIGITAL INC. by VeriSign Class 3 Code Signing 2010 CA

sakula 2 1 1 cert 1

Sakula drops an ActiveX file named ./MicroSoftSecurityLogin.ocx (only in this version). It has no interaction with the RAT and is almost empty. Its usefulness cannot be determined. However, Sakula extracts it from its resource from the type DLL and the name 0x45A. It is encrypted like embedded exploits with the PlugX algorithm. Attackers have the possibility to pop up a MessageBox containing the message fail to install activex.\n maybe you should reinstall it, independantly of the true result of the installation. This feature is not used in this version.

Sakula modifies the file \\drivers\\etc\\hosts by adding some hosts (only in this version):

csg.secure.[VICTIM DOMAIN]         217.108.[REMOVED]
ctx.secure.[VICTIM DOMAIN]         217.108.[REMOVED]
fdm.secure.[VICTIM DOMAIN]         217.108.[REMOVED]
qa.fdm.secure.[VICTIM DOMAIN]      217.108.[REMOVED]
qa.indigo.secure.[VICTIM DOMAIN]   217.108.[REMOVED]
pi.secure.[VICTIM DOMAIN]          217.108.[REMOVED]
qa.secure.[VICTIM DOMAIN]          217.108.[REMOVED]
qasd.secure.[VICTIM DOMAIN]        217.108.[REMOVED]
sd.secure.[VICTIM DOMAIN]          217.108.[REMOVED]
int.tcua.secure.[VICTIM DOMAIN]    217.108.[REMOVED]
qa.tcua.secure.[VICTIM DOMAIN]     217.108.[REMOVED]
secure.[VICTIM DOMAIN]             217.108.[REMOVED]

It uses the same configuration structure than the v2.0, but with different data:

struct ConfigV2_1
{
    CHAR    cc_domain[50];              //  login.qzbwcq.com
    CHAR    uri_get1_folder[50];        //  /photo/
    CHAR    uri_get3_file[50];          //  script.asp
    CHAR    uri_get2_file[50];          //  /script.asp
    CHAR    uri_get3_arg[50];           //  imageid
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    CHAR    copy_file_path[50];         //  %Temp%\MicroMedia
    CHAR    campaign_id[12];            //  [REMOVED]
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
}

struct ConfigV2_1
{
    CHAR    cc_domain[50];              //  oa.ameteksen.com:80
                                        //  oa.ameteksen.com:443
    CHAR    uri_get1_folder[50];        //  /photo/
    CHAR    uri_get3_file[50];          //  script.asp
    CHAR    uri_get2_file[50];          //  /script.asp
    CHAR    uri_get3_arg[50];           //  imageid
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    CHAR    copy_file_path[50];         //  %Temp%\MicroMedia
    CHAR    campaign_id[12];            //  [REMOVED]
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
}

struct ConfigV2_1
{
    CHAR    cc_domain[50];              //  sinmoung.com
                                        //  secure.devpia.com
                                        //  secure.devpia.com:443
    CHAR    uri_get1_folder[50];        //  /photo/
    CHAR    uri_get3_file[50];          //  script.asp
    CHAR    uri_get2_file[50];          //  /script.asp
    CHAR    uri_get3_arg[50];           //  imageid
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    CHAR    copy_file_path[50];         //  %Temp%\MicroMedia
    CHAR    campaign_id[12];            //  [REMOVED]
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
}

An example of used URIs:

  • POST /script.asp?imageid=[HASH_MACHINE_NAME]&type=[CMD_ID]&resid=[CMD_SEQ_NUM]&nmsg=up
  • GET (1) /photo/[HASH_MACHINE_NAME].jpg?resid=[CMD_SEQ_NUM]
  • GET (2) /script.asp?resid=[CMD_SEQ_NUM]&nmsg=del&photoid=[HASH_MACHINE_NAME]

v2.2 (24/09/2013)

The code of the v2.2 comes from the v2.0 with the same protection mechanisms except UPX.

blackvinev2 2 arch 1

This version is signed with the same stolen certificates as in version 2.1.

A new encryption algorithm has been implemented in the dropper. Instead of the single-byte XOR-encryption, it uses the RC4 algorithm from OpenSSL with the key goldsunfucker.

This algorithm is also implemented in Sakula with the same key to decrypt payloads, instead of the PlugX algorithm used in v2.0. This indicates that the authors of the protection mechanisms are the same as those of the Sakula RAT.

Payloads are now embedded in resource under the type RES and names 0x458 and 0x459.

Some dirty updates can be observed in the installation mechanism. The configuration system is still in place, but some hardcoded paths have been inserted and are used instead. This is the case for the malware copy path and name, the exploit drop location and name, and the autorun key. Depending on samples, there may be different values:

  • %ALLUSERPROFILE%\SensrSvc.exe
  • %ALLUSERPROFILE%\Utmm.ocx
  • SensrSvc

or

  • %APPDATA%\SensrSvc2013.exe
  • %APPDATA%\Utmm.ocx
  • SenseSvc

It uses the same configuration structure than the v2.0 and 2.1, but with different data:

struct ConfigV2_2
{
    CHAR    cc_domain[50];              //  oa.ameteksen.com:80
                                        //  login.ameteksen.com:443
    CHAR    uri_get1_folder[50];        //  /photo/
    CHAR    uri_get3_file[50];          //  script.asp
    CHAR    uri_get2_file[50];          //  /script.asp
    CHAR    uri_get3_arg[50];           //  imageid
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    CHAR    copy_file_path[50];         //  %Temp%\MicroMedia
    CHAR    campaign_id[12];            //  [REMOVED]
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
}

struct ConfigV2_2
{
    CHAR    cc_domain[50];              //  115.47.35.117
    CHAR    uri_get1_folder[50];        //  /photo/
    CHAR    uri_get3_file[50];          //  script.asp
    CHAR    uri_get2_file[50];          //  /script.asp
    CHAR    uri_get3_arg[50];           //  imageid
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    CHAR    copy_file_path[50];         //  %Temp%\MicroMedia
    CHAR    campaign_id[12];            //  [REMOVED]
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
}

An example of used URIs:

  • POST /script.asp?imageid=[HASH_MACHINE_NAME]&type=[CMD_ID]&resid=[CMD_SEQ_NUM]&nmsg=up
  • GET (1) /photo/[HASH_MACHINE_NAME].jpg?resid=[CMD_SEQ_NUM]
  • GET (2) /script.asp?resid=[CMD_SEQ_NUM]&nmsg=del&photoid=[HASH_MACHINE_NAME]

Version 3.0 to 3.2

All changes made in versions 2.x are not implemented in versions 3.x.

v3.0 (07/01/2014 & 27/02/2014)

Two samples have been found having the same code. We named them 3.0a and 3.0b. They were compiled at different dates (07/01/2014 and 27/02/2014), have a different configuration and are signed by different certificates.

Sample 3.0a is distributed through a fake installer:

blackvinev3 0a installer 1

A protection layer has been added on the RAT with The “Go” Tools, a tool used for manipulating ASM and PE.

The layer which is located at the beginning of the section code:

  • implements some anti-sandboxing tricks
    • check with a Sleep between 2 GetTickCount if the Sleep function has not been hooked
    • check if there is a foreground window
    • check if the mouse cursor moves
  • Decrypt some Sakula known strings using the Sakula XOR algorithm (v1) with the key 0x1E
  • Decrypt the Sakula code using the Sakula XOR algorithm (v1) with the key 0x7C

It is signed with a stolen certificate, as in versions 2.x:

  • (v3.0a) Certificate issued to DTOPTOOLZ Co.,Ltd. by VeriSign Class 3 Code Signing 2010 CA

sakula 3 0a 1 cert 2

  • (v3.0b) Certificate issued to SJ SYSTEM by Thawte Code Signing CA – G2

sakula 3 0b 1 cert 2

Installation

Some changes have been made on the installation process.

It no longer uses the Windows API to create the autorun key, but uses a cmd.exe with commands:

  • cmd.exe /c reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v [AUTORUN_KEY] /t REG_SZ /d [MLWR_PATH] (if admin)
  • cmd.exe /c reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v [AUTORUN_KEY] /t REG_SZ /d [MLWR_PATH] (if not admin)

Sakula cannot load an external configuration from the file rss.tmp anymore.

Exploits are embedded in data, and not in resource anymore. They are encrypted with a new version of its single-byte XOR algorithm:

def decrypt_xor_v2(data, key):
    rol = lambda val, r_bits, max_bits: \
          (val << r_bits%max_bits) & (2**max_bits-1) | \
          ((val & (2**max_bits-1)) >> (max_bits-(r_bits%max_bits)))
    return "".join([chr(rol(ord(c), 1, 8) ^ key) for c in data])

The key used in this version is 0x28.

Before copying itself to another location, it modifies its 4 last bytes with the value returned by GetTickCount. This feature was present in the version 1.4 (with the last 8 bytes instead 4 last), but not in 2.0. This supports the idea that version 2.x is a fork.

It resolves some imports dynamically with GetProcAddress at its start:

  • WinExec
  • WriteFile
Commands

Command N°8 (interact through a reverse shell) has been removed.

The maximum waiting time between commands has been up to 24 hours and 1 second (0x5265C01), which is 2 milliseconds more than the old value.

The uninstall command deletes autorun keys in HKEY_CURRENT_USER and HKEY_LOCAL_MACHINE (only in HKEY_CURRENT_USER in previous versions).

Communication

A new User Agent is used: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; SV1).

Data are encrypted using the single-byte XOR algorithm v1 with the key 0x66.

From versions 1.0 to 2.2, Sakula used 3 URIs to communicate:

  • a GET request used to ask for a command from the C&C
  • a GET request used to acknowledge the received command
  • a POST request used to send back a command output

From version 3.0, the GET request used to acknowledge a command has been removed. Instead, it uses the POST request with a command ID equal to 0xFF.

It uses a new configuration structure:

struct ConfigV3_0a
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \MicroMedia
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    DWORD   port                        //  0x1BB (443)
    CHAR    uri_post[200];              //  /view.asp?cookie=%s&type=%d&vid=%d
    CHAR    url_post[200];              //  http://www.we11point.com:443/view.asp?cookie=%s&type=%d&vid=%d
    CHAR    url_get[100];               //  http://www.we11point.com:443/photo/%s.jpg?vid=%d
    CHAR    cc_domain[100];             //  www.we11point.com
}
struct ConfigV3_0b
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x3A98 (15000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]
    CHAR    copy_file_path[100] ;       //  %ALLUSERSPROFILE%
    CHAR    copy_file_folder[100];      //  \CitrixReciever
    CHAR    copy_file_name[50];         //  CitrixReciever.exe
    CHAR    autorun_key[50];            //  CitrixXenAppReciever
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /news/view.asp?cookie=%s&type=%d&vid=%d
    CHAR    url_post[200];              //  http://www.huchin.com/news/view.asp?cookie=%s&type=%d&vid=%d
    CHAR    url_get[100];               //  http://www.huchin.com/news/photo/%s.jpg?vid=%d
    CHAR    cc_domain[100];             //  www.huchin.com
}

An example of used URIs for v3.0a:

  • POST /view.asp?cookie=[HASH_MACHINE_NAME]&type=[CMD_ID]&vid=[CMD_SEQ_NUM]
  • GET /photo/[HASH_MACHINE_NAME].jpg?vid=[CMD_SEQ_NUM]

An example of used URIs for v3.0b:

  • POST /news/view.asp?cookie=[HASH_MACHINE_NAME]&type=[CMD_ID]&vid=[CMD_SEQ_NUM]
  • GET /news/photo/[HASH_MACHINE_NAME].jpg?vid=[CMD_SEQ_NUM]

v3.1 (16/05/2014 & 09/07/2014 & 10/07/2014 & 18/09/2014)

Many samples have been found having the same code. We can group them by compilation timestamp (16/05/2014 and 09/07/2014, 10/07/2014, 18/09/2014). We named them respectively 3.1a, 3.1b, 3.1c and 3.1d. They are distributed through different installers signed by stolen certificates and have a different configuration.

Sample 3.1a is distributed through a fake installer (compiled the 23/05/2014):

blackvinev3 1a installer 2

We don’t have the installer corresponding to the sample 3.1b.

Sample 3.1c is distributed through 2 signed fake installers (compiled the 06/08/2014 and 19/08/2014):

blackvinev3 1c installer 2

blackvinev3 1c2 installer 1

Sample 3.1d is distributed through a signed fake installer (compiled the 27/10/2014):

  • Certificate issued to Career Credit Co,.Ltd. by VeriSign Class 3 Code Signing 2010 CA

blackvinev3 1d installer 1

In versions 3.1 and 3.2, Sakula is distributed through a dropper and is not signed with a stolen certificate anymore. It contains a legit binary (vulnerable to DLL hijacking), a rogue DLL and a Sakula embedded in a PE loader. The legit binary loads the rogue DLL which loads and executes the PE loader which loads and executes the RAT.

blackvinev3 1 arch 1

The dropper:

  • does not execute while the mouse does not move (anti-sandbox trick)
  • extracts the payload located after the tag EEEEEEEE, decrypts it, and writes it to the file %TEMP%\s.exe
  • extracts the payload located after the tag LLLLLLLL, decrypts it, and writes it to the file %TEMP%\msi.dll
  • extracts the payload located after the tag TTTTTTTT and writes it to the file %TEMP%\setup.msi
  • executes %TEMP%\s.exe
  • uninstall itself with the command ping 127.0.0.1 & del /q [PATH]

The dropper uses the same single-byte XOR-algorithm than the RAT (with the key 0x68) and the same deletion method. These facts support the assumption that it is custom-made.

The legit binary %TEMP%\s.exe is a digitally signed executable from Kaspersky Lab originally called setup.exe.

sakula legitkasperkyexe 3 1 cert 1

The file %TEMP%\msi.dll is a simple DLL which decrypts and executes setup.msi (hardcoded). It uses the single-byte XOR-algorithm with the key 0x88.

The file %TEMP%\setup.msi is Sakula embedded in a PE loader. This PE loader is different from the PE loader used for version 2.x, but acts in the same way. It extracts the payload located after the shellcode and loads it in memory.

Installation

Some changes have been made on the installation process:

  • it injects itself in a new process created from %WINDIR%\system32\svchost.exe (3.1a -> 3.1c) or from %WINDIR%\explorer.exe (3.1d)
  • it executes its exploit with the command cmd.exe /c rundll32 [EXPLOIT_PATH] ActiveQvaw [MLWR_PATH]
  • it does not change anymore the 4 last bytes of its copy

To move itself to its new location, it moves dropped files to %Temp%\MicroSoftMedia (depending on configuration):

  • s.exe -> %Temp%\MicroSoftMedia\MediaSoft.exe
  • msi.dll -> %Temp%\MicroSoftMedia\msi.dll
  • setup.msi -> %Temp%\MicroSoftMedia\setup.msi
Communication

A new User Agent is used: Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/4.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)

It uses the same configuration structure than the v3.0x, but with different data:

struct ConfigV3_1a
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED])
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \MicroMedia
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_post[200];              //  http://192.199.254.126/view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_get[100];               //  http://192.199.254.126/photo/%s.jpg?id=%d
    CHAR    cc_domain[100];             //  192.199.254.126
}

struct ConfigV3_1b
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x3A98 (15000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \MicroSoftMedia
    CHAR    copy_file_name[50];         //  MediaSoft.exe
    CHAR    autorun_key[50];            //  MicroSoftMedia
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_post[200];              //  http://180.210.206.246/view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_get[100];               //  http://180.210.206.246/photo/%s.jpg?id=%d
    CHAR    cc_domain[100];             //  180.210.206.246
}

struct ConfigV3_1c
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x3A98 (15000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \JuniperACX
    CHAR    copy_file_name[50];         //  JuniperSafeACX.exe
    CHAR    autorun_key[50];            //  JuniperSafeACX
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_post[200];              //  http://23.27.112.143/view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_get[100];               //  http://23.27.112.143/photo/%s.jpg?id=%d
    CHAR    cc_domain[100];             //  23.27.112.143
}

struct ConfigV3_1c
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x3A98 (15000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]t
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \MicroMedia
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_post[200];              //  http://23.226.65.197/view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_get[100];               //  http://23.226.65.197/photo/%s.jpg?id=%d
    CHAR    cc_domain[100];             //  23.226.65.197
}

struct ConfigV3_1d
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x7530 (30000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \MicroMedia
    CHAR    copy_file_name[50];         //  MediaCenter.exe
    CHAR    autorun_key[50];            //  MicroMedia
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_post[200];              //  http://www.xha-mster.com/view.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_get[100];               //  http://www.xha-mster.com/photo/%s.jpg?id=%d
    CHAR    cc_domain[100];             //  www.xha-mster.com
}

An example of used URIs:

  • POST /view.asp?cstring=[HASH_MACHINE_NAME]&tom=[CMD_ID]&id=[CMD_SEQ_NUM]
  • GET /photo/[HASH_MACHINE_NAME].jpg?id=[CMD_SEQ_NUM]

v3.2 (09/01/2015)

Version 3.2 is distributed through a signed fake installer (compiled the 15/01/2015):

  • Certificate issued to U-Tech IY Service by SGTRUST CODE SIGNING CA

sakula 3 2 cert 1

blackvinev3 2 arch 1

The dropper has been adapted to launch a DLL:

  • does not execute while the mouse does not move (anti-sandbox trick)
  • extracts the payload located after the tag NNNNNNNN, decrypts it, and writes it to the file %TEMP%\Emabout.dll
  • extracts the payload located after the tag AAAAAAAA, decrypts it, and writes it to the file %TEMP%\shutil.dll
  • extracts the payload located after the tag BBBBBBBB and writes it to the file %TEMP%\Thumbs.db
  • executes %TEMP%\Emabout.dll with the command rundll32.exe [%TEMP%]\Emabout.dll CloseAbout
  • uninstall itself with the command ping 127.0.0.1 & del /q [PATH]

The XOR key used to encrypt payloads has been changed and is now equals to 0x18.

The legit binary %TEMP%\Emabout.dll is a digitally signed executable from McAfee (Virus Scan Entreprise v8.7.0.570).

The file %TEMP%\shutil.dll is a simple DLL which decrypts and executes Thumbs.db (hardcoded). It uses the single-byte XOR-algorithm with the key 0x88.

The PE loader is the same than the v3.1.

Installation

Some changes have been made on the installation process. Sakula does not drop exploits anymore when the user does not have administrator rights. This feature has been dirtily removed. The code is still present but never executed (a return or goto has been placed at the beginning of the function).

To move itself to its new location, it moves dropped files to %Temp%\MicroWhoKnow (given in configuration):

  • Emabout.dll -> %Temp%\MicroWhoKnow\MicroWhoKnow.dll
  • shutil.dll -> %Temp%\MicroWhoKnow\shutil.dll
  • Thumbs.db -> %Temp%\MicroWhoKnow\Thumbs.db

Then it sets up autorun keys pointing to %Temp%\MicroWhoKnow\MicroWhoKnow.dll using cmd.exe with commands:

  • cmd.exe /c reg add HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v “MicroWhoknow” /t REG_SZ /d “mshta vbscript:CreateObject(\”WScript.Shell\”).Run(\”cmd /c cd %Temp%\MicroWhoknow “&&” rundll32 MicroWhoknow.dll Plugupdate”,0) (window.close)” (if admin)
  • cmd.exe /c reg add HKCU\Software\Microsoft\Windows\CurrentVersion\Run /v “MicroWhoknow” /t REG_SZ /d “mshta vbscript:CreateObject(\”WScript.Shell\”).Run(\”cmd /c cd %Temp%\MicroWhoknow “&&” rundll32 MicroWhoknow.dll Plugupdate”,0) (window.close)” (if not admin)

The command used in previous versions 3.0 and 3.1 to set up autorun keys is still present in data, but never used:

  • cmd.exe /c reg add %s\Software0\Microsoft\Windows\CurrentVersion\Run /v “%s” /t REG_SZ /d “rundll32 \”%s\” PlugUpdate”

It uses the same configuration structure than the v3.0 and v3.1, but with different data:

struct ConfigV3_2
{
    DWORD   nb_config;                  //  1
    DWORD   waiting_time;               //  0x2710 (10000 milliseconds)
    DWORD   unk;                        //  0
    CHAR    campaign_id[12];            //  [REMOVED]
    CHAR    copy_file_path[100] ;       //  %Temp%
    CHAR    copy_file_folder[100];      //  \MicroWhoknow
    CHAR    copy_file_name[50];         //  MicroWhoknow.dll
    CHAR    autorun_key[50];            //  MicroWhoknow
    DWORD   port                        //  0x50 (80)
    CHAR    uri_post[200];              //  /update.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_post[200];              //  http://104.128.233.4/update.asp?cstring=%s&tom=%d&id=%d
    CHAR    url_get[100];               //  http://104.128.233.4/x0x/%s.jpg?id=%d
    CHAR    cc_domain[100];             //  104.128.233.4
}

An example of used URIs:

  • POST /update.asp?cstring=[HASH_MACHINE_NAME]&tom=[CMD_ID]&id=[CMD_SEQ_NUM]
  • GET /x0x/[HASH_MACHINE_NAME].jpg?id=[CMD_SEQ_NUM]

This is the end of this long blogspot on 2.x and 3.x Sakula. This is probably not the last one, so keep in touch !

Please, feel free to give us your feedback, report any bug or mistake you find and/or share new samples with us.