2014-06-09

Author: Jakub Kroustek

In this analysis, we focus on a recently discovered cyber-espionage threat named Turla that is also called Uroburos or Snake. It has a tight connection with Agent.BTZ that infiltrated Pentagon in 2008. Turla is an advanced malware with sophisticated rootkit features for hiding its presence. Furthermore, it is based on a distributed C&C architecture that can be used for a wide range of purposes such as cyber espionage or credentials theft. Based on the investigation of other Turla samples, it is highly probable that this is not a work of an individual, but it was rather developed by an experienced team.

After infecting the system, the architecture of Turla consists of two parts:

Kernel-mode part operating as a rootkit that hides Turla’s activity in the Windows kernel. After successful infection of a target system (both 32-bit and 64-bit Windows can be infected), it deploys the second part as a dynamically linked library (DLL) and injects it into the predefined processes.

User-mode part is responsible for communication with its other instances in the same machine as well as reporting to remote C&C servers and fulfilling their orders.

Several Turla samples have already been analyzed in the previous reports (1, 2, 3, 4, 5, and 6). However, most of these studies were focused on analysis of the kernel-mode part and exploits used for infection. In this report, we focus on analysis of the user-mode part of a newer Turla version. We do not give a complete analysis of all of its functions (more than 1000). Rather than that, we focus on the most important parts.

Brief Overview of Turla

At first, we give a brief overview of Turla as a complete package. Initially, the Turla dropper tries to exploit the target system by one of the supported vulnerabilities: MS09-025 and MS10-015. If it is successful, it installs and registers the kernel-mode part (the driver). This driver places several hooks to hide its presence (e.g.

,

,

) and sniffing for a system state and other sensitive information (e.g. packet inspection and filtering). Furthermore, it sets itself as a service via registry key

and setting several mutexes (e.g.

) to avoid repetitive infection by the dropper.

The driver also prepares a channel for communication with the user-mode part such as creating virtual partitions for storage of logs and configuration files (e.g.

,

). Furthermore, it creates a device

for communication with instances of the user-mode DLL. As we will see later, this device is referred to as

from the user mode and it provides multiple functions based on the internal communication protocol between the kernel-mode driver and user-mode DLL.

The dropper also extracts the user-mode DLL, which is injected into some of the system processes (e.g.

,

,

) and browsers (e.g.

,

,

) by the kernel-mode part. These instances of the injected DLL can run in two modes (“manager” or “transport”) with different tasks and communicate together by using Windows named pipes. This communication has a form of command messages from a client to a pipe server. Based on the command, the pipe server performs the desired action, such as communication with the remote C&C server. This part is tricky because the communication with the remote C&Cs is only done at the same time as the infected process communicates online. This makes detection of this infection quite hard because Turla’s traffic is interleaving with the user’s traffic.

Technical Analysis of the User-mode Part

For the analysis of the user-mode part, we use a DLL that tags itself as a version

(more precisely,

). It is a 32bit WinPE DLL with MD5 checksum

and size 428 kB. It has been compiled by the MS Visual C++ compiler, but it was developed mostly in the C language. Based on the PE header, the original file name was

. Furthermore, this file has four export functions that represent the basic interface of this library when running as a Windows service.



The authors of this malware also try to confuse us by proclaiming that this binary is a

. On the other hand, the file is not packed, which makes its reverse engineering easier.



When we look into the resources, we can notice that one of the dialogs (ID 117) has set the language to Russian while the others are set to English. Even though these dialogs are completely useless for the execution, this can be a clue about the origin of this application. However, there are no Russian texts in the code of this file, which differs from the previous study. We can also notice that the resources contain two binary files (IDs 104 and 105) of sizes 1981 and 1945 bytes respectively. Each file starts with text sequence

and ends with

.



Communication Between Kernel-mode and User-mode Parts

The communication between the kernel driver and the injected DLL is quite tricky and we will describe it in a deeper detail. The device

serves as a communication channel between both parts. The communication is always initiated from the user-mode side by the function

(note: most of the function names are reconstructed by us based on their behavior). This function uses the WinAPI function

for opening this device and function

for sending and receiving messages (e.g. commands, information retrieval, logging). To distinguish a particular driver functionality, it uses a special

code that is set in some of the more abstract functions like

and

. The decompiled codes were retrieved by using are our Retargetable Decompiler and manually tweaked to improve their comprehensibility.

As an example of the

code, we can describe the value

. It is used as a request for creating a directory that is hidden by the rootkit part. Within the function

, this number breaks down into several parts according to the definition of the

macro:

Therefore, the effective command code for the driver is

. We found the following control codes used in the DLL file, but there are probably more such functions supported by the driver:

=>

~ get driver name

=>

~ update driver

=>

~ set service status

=>

~ get service status

=>

~ create registry key

=>

~ hide registry key

=>

~ delete file

=>

~ hide process (PID)

=>

~ switch to a stealth mode for X days (avoid online communication)

=>

~ create hidden directory

Analysis of the Main Thread

One of the first thing we noticed during the analysis is a presence of many debugging messages that have been (unwillingly?) left by the authors. These messages are printed via the WinAPI function

and they are only visible when the DLL is being debugged. Furthermore, Turla heavily uses logging of every its activity and it saves these logs into multiple destinations. In the following text, we simplify the usage of multiple destinations by simply referring to them by

. Some of the known log destinations are:

– logging of C&C communication

and

– logging pipe server communication

– logging the execution state of Turla when running as a service

– the main log file

The logged text is often abbreviated and we can only guess what does a particular abbreviation mean (e.g.

,

,

). Our guesses are noted as comments in the decompiled code listings.

We start our analysis from the function

. This function has two different purposes based on the type of its call: (1) attach the DLL to a process (i.e. it is injected into a running process) and (2) detach from a running process (e.g. process exits or the DLL is forced to unload from the running process). The first case is more interesting for us because it tries to detect if there is a running instance of the pipe server in any other process and if not, it starts one. Secondly, it checks the name of the process it is injected in. If it finds that it is not injected in a system process (i.e.

,

,

), then it creates a new thread by executing function

. When the injection is done in a system process, it also gets to the same function (

), but from the export function

.

While analyzing the other function, we found out that the malware authors implemented some tricks to make reverse-engineering of their code harder. One of these tricks is the way the API library calls are performed. These calls are not performed directly by calling the desired function, but indirectly via function pointers obtained from the

function

. Furthermore, the function names (i.e. strings) are stored as encrypted strings. The same applies to other strings (e.g. registry keys, communication commands, log file names, registry entries). To make it even more difficult, different strings are encrypted by different encryption algorithms. However, the difference between these algorithms is minimal because all of them are based on the XOR encryption by a hard-coded key. Most of the strings are encrypted by a one-byte XOR key

. An example of such a decryption function is shown next:

However, the authors were not thorough because they sometimes forgot to encrypt some of the API names:

We can continue with analysis of the function

, which represents the core of this user-mode part. This function has about 2000 lines of code so we will slice it into smaller code snippets and discuss only the most important ones.

At first, the aforementioned decryption is performed for function names and other used strings.

Next, Turla creates one of its temporary files, which is used for logging its execution state.

In the following piece of code, Turla tries to stay low while being asleep, probably to wait until some of the running AV software finishes its behavioral scan. Afterwards, it tries to figure out if the injected process is running with administrator privileges. Finally, it contacts the kernel-mode part via the driver

for the first time. Another interesting fact about the function

is that it uses Windows registry key

as a back-up plan to store information about service status whenever the device is not accessible.

Based on the reply, it detects if it is running as a service or not. We can also notice a preparation of a string with version of this DLL

.

Afterwards, it tries to get information about the network adapters (both virtual and physical) installed in the local system. It iterates over them and log the first MAC address that does not belong to any Bluetooth adapter. This may be because it tries to find something unique for identification of every machine in the local network. Furthermore, it creates several registry files

that store Turla’s settings. Creation of these keys is done by the kernel module.

In the next part, it tries to hide its logs and configuration files (

) inside of a directory that looks like a directory, where the Windows updates are stored. Such a location is of the form

or

, where

denotes five random digits. Moreover, it avoids using an existing directory and it tries to create a very similar directory to an existing one instead, e.g.

for an existing directory

. This can be hard to manually detect because there may be dozens of such legitimate directories with Windows updates.

In the next step, Turla obtains the default browser from the following Windows registry key. Afterwards, it extracts just the name of the browser’s executable (e.g.

) and compares it with its internal list of supported browsers. Items in this list are XOR-encrypted as well as most of the other strings.

At this point, Turla once again tries to detect the name of the process it is injected in. More precisely, it tries to detect if it is running in one of the processes marked as browsers. Note: this detection can be easily fooled by renaming the executable file. If Turla detects that it is running in a browser, it switches into the “transport” mode. Otherwise, it is probably running inside of a system process (e.g.

) and it switches into the “manager” mode.

From this point forward, the rest of the DLL code differs based on the detected mode. We briefly describe both modes separately.

Manager Mode

In the manager mode, when Turla DLL is injected into a system process such as

, it acts as a pipe server that communicates with other DLL instances that are running in the transport mode by using Windows named pipes.

The name of the communication pipe is of the form:

, where the question mark denotes either

when running with administrator privileges or

in other cases. Its creation is done in function

, but this will be described in a separate section for better readability. Turla also creates a corresponding file for logging pipe events

or

in directory

.

Afterwards, Turla sets the

flag in order to allow enumeration of running process, which is critical for the subsequent parts.

In the next part, we can find the main (endless) loop of the manager mode. Based on the configuration, it may start the system browser and hide its process by using the kernel driver (once again by using function

) or it will wait until the user starts the browser manually. Furthermore, in function

, it tries to inject a 3 kB of code into any of these running processes that are matched as a browser (it is the same list of browsers as previously:

,

, etc.). The injection is done by WinAPI functions

,

, and

. The injected code executes a sequence of calls

that performs a load of Turla’s DLL. This code is executed by

and the injecting process checks for results of injection by using functions

and

. This is basically the way Turla infects other processes that communicate online and that may hide Turla’s own communication with C&C servers.

The last part of the manager mode is a clean up of all the injected processes. This is basically done in the same way as their infection, by injecting another chunk of code (1 kB) into the same process. This injected code performs unloading of the Turla’s DLL by using a sequence of WinAPI calls

.

Transport Mode

In the transport mode, Turla makes most its information gathering activities as well as communication with C&C servers.

First of all, when there is no other running pipe server, it starts its own via the same function

as used in the manager mode. It names the pipe

. The transport mode also creates a different file for logging its activity:

.

Furthermore, it uses the global configuration stored in the Windows registry keys

, where

stands for a digit in range

. There, we can find multiple entries, such as

or

. The content of these entries is stored in an encrypted form. The decryption is done by using the XOR key:

It is the same key that has been found in Agent.BTZ. Some of the registry keys are also encrypted by a more sophisticated encryption algorithm that is based on the Number Theory Library (NTL), which is statically linked to the DLL file. Some of theses entries are also checked for consistency via the CRC32 algorithm, whose table is hard-coded in the file:

Within these registry entries, we can find the configuration and logs, such as the communication frequency, information about host, activation of a stealth mode, and additional addresses of C&C servers. These settings are initialized to default values at the beginning of the transport mode and they are updated from registry values afterwards. The code below contains a shortened list of these settings.

Another settings are read from the file

. Regardless the file’s extension, it is a textual INI file containing configuration in the following form:

After the initialization, it starts using the virtual partition with name

created by the kernel-mode part. Most of the log and configuration files are moved from the default location (e.g.

) into this partition:

Afterwards, if configured in this way, Turla tries to add a new service via adding a key into Windows registry.

In the next step, Turla starts its communication with C&C servers based on its communication mode (active, passive, stealth). We found five hard-coded addresses of remote C&C servers in this sample, while others are obtained in command messages from one of these servers:

The fist successful connection is obviously a big event for Turla and it is appropriately logged.

The commands received from the remote C&C has to be decrypted multiple times, at first by the previously mentioned XOR key

and also by the NTL-based encryption algorithm. Turla also checks the CRC checksum of this message. After that, the commands are extracted from these messages and logged into file

that is located either in

or in the virtual partition

.

By analyzing the function responsible for execution of these commands, we found more than thirty commands with a wide range of usage, such as execution of commands (

,

), manipulation with files and registry keys (

,

,

,

), manipulation with running processes (

,

), setting Turla modes (

,

,

), and network analysis (

). The complete list of detected commands follows:

The first two commands

and

are responsible for execution of the given application. It is performed either via execution in the command-line (

) or via the function

. These commands also include additional parameters specifying the mode of execution:

– immediately load library by using function

. This can be used for adding a new functionality that has been obtained from the remote C&C.

– execute a command-line argument as a given user by using the function

.

– run under the transport mode and use its pipe

.

– run under the manager mode and use its pipe

.

The executed command is run inside the directory

, its outputs are saved in a temporary file with pseudo-random name

, and sent to a C&C server if needed. Furthermore, the created process is hidden by using kernel-mode function

.

Named-Pipe Communication

The creation of the named pipe is done in the aforementioned function

, which basically checks whether there is an another instance of the pipe server running on the same machine. If there isn’t, it starts a new thread running function

.

This function creates a new pipe named as

by using WinAPI function

. Furthermore, it waits in an endless loop for messages from other Turla DLL instances. Each received message is handled in a new thread.

The handling of messages is done in the function

. By using the named pipes, these DLLs are sending two types of messages: (1) control messages of size 1332 bytes and (2) larger messages containing data. The first type of messages precedes the other one because it contains information about the size of the following message.

This first type of messages has a fixed start sequence

and the end sequence

to check correctness of message delivery. Its first message is, however, encrypted by the random XOR key included in the same message. After decryption, the command is extracted from this message. These commands control operation of the pipe server in a similar way as commands from C&C control local Turla instances, e.g. manipulation of files (

,

,

), execution of commands (

,

), and network communication with C&C (

,

). In our analysis, we detected the following set of commands:

(yet another

command)

As a brief example of one such command, we can describe the behavior of the

command that sends data to a remote C&C server. Its execution is once again done in a new thread running function

. Within this function, the connection is established with the remote server by using the HTTP protocol. The second message passed to the pipe server is very important for this type of command because it contains the fragmented message that has to be sent as well as specification of the target address, port, username, password, URI and several others.

Turla itself is able to detect the system proxy based on the appropriate registry keys. Moreover, it uses the same user agent as defined in the system to stay undetected in the network traffic. After the initial test of connection (i.e. accessing the remote file

), Turla may use a username/password authentication where these values are associated with a particular C&C server. If the test is successful (i.e. server-response code

), the content of the message is sent to the server as a sequence of message fragments. Each fragment is encrypted by a random XOR key that is sent together with the encrypted-message fragment. Furthermore, it contains a CRC checksum to validate the delivery. These messages are sent as a cookie to

.

Turla also supports a second way of sending POST messages. In this mode, the message is XOR encrypted, Base64 encoded, URL encoded, and finally sent as a request similar to this one:

At the end, Turla reads an encrypted confirmation from the server. It is one of these answers:

,

,

,

,

,

, or

.

Conclusion

In this analysis, we tried to give a brief (but still quite lengthy) insight into the internals of a very sophisticated rootkit that is spreading in these days. Turla is definitely a result of a serious development process dating back in 2006 and, despite its age, Turla will be probably highly active in a near future. Based on its features, Turla must be taken as a serious threat.

Show more