The Initial DLL
Everything starts with a DLL. The DLL passes itself off as one of the standard Windows libraries, winmm.dll or apphelp.dll. Since in the vast majority of cases the samples that we detected disguised themselves as winmm.dll, we will assume that the malicious library hides under this name in the rest of this document.
Winmm.dll is a Windows system library which provides multimedia functions. It is located in the %WINDIR%System32 folder. The attackers counted on this being a library providing basic system functions and hence the probability of it being loaded by some program is very high (the same is true of apphelp.dll). For example, winmm.dll is loaded by explorer.exe, which is launched during operating system startup.
If a malicious DLL named winmm.dll is located in the same folder as the program that depends on the system library of that name, the malicious DLL will be loaded when this program is executed instead of the original library that is located at %WINDIR%System32winmm.dll.
Taking advantage of their control of an infected computer, cybercriminals place a malicious library in the %WINDIR% folder. The same folder also hosts the program explorer.exe. This enables the attackers to ensure that the malicious DLL is loaded at system startup: explorer.exe loads the malicious winmm.dll from the %WINDIR% folder as soon as it launches during system startup.
But how can a program which depends on the original library work correctly if a malicious winmm.dll is loaded instead of the original library? The malware authors have an answer to that: the malicious library is designed to load the original winmm.dll from the %WINDIR%System32 folder.
The cybercriminals did not bother to do any development of their own to ensure that the original winmm.dll is loaded. Instead, they used the well-known AheadLib program.
This program, which is designed to facilitate the analysis of malicious libraries, was created by a Chinese developer employed by an antivirus vendor. The program accepts a DLL as its input and creates C code which hooks the functions included in the library. The C code can be compiled back into a DLL, which can then be used to analyze the behavior of malicious files.
Hook functions (code generated by the legitimate program AheadLib)
The flexibility of this tools allows to customize the logics of malicious application during analysis and overload functions code to provide some debugging output. Some code can be added to display parameters of the hooked functions in order to find out which values are passed to the original functions when they are called. This method is used in so called dynamic analysis of malicious applications.
Determining the addresses of the real functions
(error message in the frame: “Function %hs cannot be found,
the program will not operate correctly”)
Modified module loading the original DLL
(error message in the frame: “%s cannot be loaded, the program will not operate correctly”)
Ironically, malware authors have found this to be the ideal application for creating malicious libraries. They fed a real library (e.g., winmm.dll) to the program and obtained a source code template to create a modified DLL – in the shape of a C file – as the output. By adding a malicious payload, the attackers created a complete piece of malware that included all the features of the real DLL in addition to its malicious functionality.
Bizarrely, the attackers kept the code for AheadLib debug messages in the early versions of their malware (marked with a red border in the screenshots above). These strings can also be found in compiled malicious binaries:
The function %hs cannot be found, the program will not operate correctly
%s cannot be loaded, the program will not operate correctly
Later, these fragments were removed from the C file generated by AheadLib.
The winmm.dll malicious library maintains another library in its body, which is decrypted on-the-fly and loaded into the process memory. The original name of this additional library is PlusDLL. This is the platform’s main control component. When the additional DLL has been properly allocated in the memory, winmm.dll passes control to it with a parameter – a string which contains bot settings. The settings string, in encrypted form, is also located in the winmm.dll body – after the word PLUSUNIT.
Encrypted bot settings
After decryption, the string looks like this:
Apparently, Winnti malware has attracted the attention of researchers before: the cybercriminals made minor modifications to the methods used to store these initial settings. In some samples, the settings were hidden in the executable file’s header:
Encrypted settings at the beginning of the malicious program
In other variants, the ‘PLUSUNIT’ string was modified:
UUUSUN”” instead of PLUSUNIT
The PlusDLL library has an embedded driver. The driver is stored in %WINDIR%System32 file, registered as a service and started by NtLoadDriver system API function. Immediately after that, the driver’s file is removed, as well as all the registry entries created during service registration. The executable preserved the original driver names which are “PortLess” and “PointFilter”; however, the driver files used during infection are saved with as “sp1itter.sys” and “acplec.sys”.
The purpose of the driver is to hide network connections established by the malware. For example, if the user decides to check a list of established connections (e.g., using the ‘netstat -a’ command or the tcpview program) while the bot is communicating to the control center, the driver will protect and hide the malware connections. This approach is used by many rootkits on Windows platform.
The driver uses an unusual method to determine which addresses should be concealed and which shouldn’t. This information is available in the PlusDLL control library, which normally operates in the context of the explorer.exe process when the infection is active on the computer. This information is sent from the user mode, in which PlusDLL works, to the kernel level, at which the driver works, via the NtSetQuotaInformationFile function, which is available in both modes.
When starting, the driver hooks the NtSetQuotaInformationFile function:
Hook on NtSetQuotaInformationFile function
Every time the function is called, the driver checks its parameters, specifically, HANDLE FileHandle and PVOID Buffer.
The FileHandle parameter holds a descriptor describing the partition of the hard drive where the function is to set disk quotas.
The Buffer parameter is a buffer containing information about which new quotas need to be set. The driver checks whether the value of the FileHandle parameter is equal to minus two. When the system calls the NtSetQuotaInformationFile function in order to actually change the quotas, the descriptor must be associated with one of the disks, which obviously means that it cannot be equal to minus two. The negative value is set by the PlusDLL library in order to make the driver detect that the NtSetQuotaInformationFile function was called by that library. When calling NtSetQuotaInformationFile, PlusDLL sends information about the network addresses to be concealed to the driver via the Buffer parameter. If FileHandle is not equal to minus two, the hook function in the driver passes control to the system the way it should be on an uninfected system.
Sending data from the PlusDLL.dll library to the sp1itter.sys driver
Note that 64-bit versions of Windows do not allow unsigned drivers to run. The malicious driver’s 64-bit versions were signed using stolen certificates. During the time that we have been tracking the Winnti group, we found 11 certificates that were used to sign the malware used by the group (not necessarily drivers only). Ten of them belong to various companies in the gaming industry.
Launching the Main Function
As mentioned above, the PlusDLL library is a control module. Let’s look at how the cybercriminals implemented the transition to perform the malicious DLL’s main tasks. They could have simply called an appropriate function directly or created a separate thread in which to execute it, but for some reason they resorted to a trick: the code of the SetWindowStationUser function in the user32.dll library was modified. After modification, the function’s first command became jmp , where is the address of the function in the PlusDLL library which implements the malicious library’s main features.
Hook on SetWindowStationUser
Immediately after this modification, a thread is created (CreateThread) executing code starting from the SetWindowStationUser function address. As a result, when control is eventually passed to this function, the inserted command jmp returns control back to the PlusDLL code.
Malicious DLL launching its own code by creating a thread that supposedly calls SetWindowStationUser
The same method is used to execute two more functions in the PlusDLL library. One of them is used to initialize network routines; the other executes procedures terminating the malicious program at the very end. The only difference is that instead of SetWindowStationUser, the code of two other functions from user32.dll is modified – EndTask and WinHelpW, respectively.
It is likely that this was done in order to hide the real addresses of functions in PlusDLL in case its code was analyzed based on its execution logs using an automatic system (sandbox) that looks at all function calls. If this trick is used, an execution log would only show threads launched from the addresses of the functions SetWindowStationUser, EndTask and WinHelpW, which could potentially confuse researchers.
Another possibility is that this is an anti-emulation feature. Perhaps the emulators built into some antivirus products are unable to cope with these ‘leaps’ – in this case, emulation will not result in the execution of malicious functions, which also suits the cybercriminals’ purposes.
So what does PlusDLL control? It turns out that the target functionality is implemented in different files. Each file provides a specific remote control feature and is downloaded from the attackers’ server every time the system starts up. These files are not saved on disk or in the registry but are loaded directly into the memory.
At the very start of the operation, after launching the driver, PlusDLL collects information about the infected system. A unique identifier for the infected computer is generated based on information about the hard drive and the network adapter’s MAC address, e.g., TKVFP-XZTTL-KXFWH-RBJLF-FXWJR. The attackers are interested primarily in the computer’s name, the program which loaded the malicious library, as well as information about remote desktop sessions (session name, client name, user name and session time). All of this data is collected in a buffer, which is then compressed and sent to the attackers’ control center. The buffer may look like this:
The bot sends information about an infected system to the control center
In reply to this initial message from the bot, the control center sends the list of available plugins. Plugins are DLL libraries that provide specific remote control functions. Upon receiving the list of plugins, the bot downloads them, allocates them in the memory and passes control to these libraries.
Different C2 servers could push different plugins. In total we have discovered eight functional libraries:
|Gives the operator (attacker) access to the console, i.e., the infected computer’s command line.
|Works with the infected computer’s file system: makes it possible to view folder contents, open and remove files.
|Provides the operator with information on the processes running on the infected machine. Can stop processes.
|Provides the operator with information on the services installed on the infected machine.
|Redirects traffic using port forwarding
|The remote desktop GUI enables the attacker to view what is happening on the infected computer’s screen, as well as enabling the attacker to work with the infected machine’s desktop.
|Library for transferring data over the network using a SOCKS5 proxy server.
|Enables the attacker to transfer files: receive files from the infected machine, download/create/save files, as well as execute programs on the infected computer.
These plugins form the core toolkit which is used by the perpetrators during attack.
Operation of the Malicious Platform
Operation flowchart at the initial stage
As you can see, the cybercriminals use an entire inventory of malicious tools to effectively control the remote computer. Moreover, they have taken measures to conceal their activities: the plugins do not explicitly appear anywhere except in the computer’s memory; they do not get saved to the hard drive; the driver is deleted immediately after launch; all traces in the registry that could indicate this launch get deleted. Only the initial DLL remains on the disk that kick starts the entire process and contains an encrypted version of PlusDLL which is the control DLL.
One of the weak points in this architecture is that the driver does get saved to the hard drive before it launches, so antivirus products can detect the emergence of this file. The situation is further exacerbated by the fact that the malicious drivers may be signed (although not all drivers in the Winnti samples that we detected were in fact signed). An unsigned driver in itself does not have the means to counter antivirus products and its code can be easily recognized as malicious, whereas signed drivers stand a better chance of remaining undetected by antivirus products: certain antivirus products consider properly signed programs legitimate by default, so as to minimize the chances of false positive responses.
Kaspersky Lab’s products detect the malicious programs described above under the following verdicts:
The initial DLLs winmm.dll and apphelp.dll, the PlusDll.dll control DLLs, and functional loadable modules (CmdPlus.dll etc.) are detected as Backdoor.Win32.Winnti or Backdoor.Win64.Winnti.
The drivers sp1itter.sys and acplec.sys are detected as Rootkit.Win32.Winnti or Rootkit.Win64.Winnti.
Communication with the C&C Server
The data transmitted during the communication between the bot and the C&C server, naturally, do not manifest themselves in any explicit form in online data traffic. Since an active remote control practice can generate substantial traffic, cybercriminals compress communication data with the algorithm LZMA, though they do not include the appropriate header inherent to this algorithm.
The data is transmitted over the TCP protocol. The samples that we analyzed established connections between C&C servers and ports 53, 80 and 443. This port selection is not surprising: they are associated with the protocols DNS, HTTP and HTTPS respectively. All three are routinely used in everyday operations, so they are enabled under most firewall policies. Besides, large amounts of data typically pass through these ports (with the possible exception of port 53), which makes it easier for the malicious traffic to remain inconspicuous.
Although the ports are associated with certain protocols, the actual content of the traffic generated by the malicious program does not correspond to them. Early versions of the Winnti platform exhibited the following traffic structure when communicating with C&C: each block of transmitted data started with the magic number 0xdeadface, followed by the number of blocks (in a DWORD), then the hash of the transmitted block (8 bytes), the size of compressed data (DWORD), the size of source data (DWORD) and, finally, the actual compressed data.
The unit structure of a data block transmitted online in early versions of Winnti
This is where another weak point of the Winnti family of backdoors becomes apparent. With this data structure, malicious network traffic could easily be spotted by, for example, the magic number 0xdeadface. The cybercriminals probably lost control over victim computers fairly frequently as corporate system administrators identified the intrusion by the unique headers in data packets with the help of IDS/IPS systems, and cleaned their networks. In 2011, new versions of Winnti backdoors appeared that, while still based on the same platform, started to use an updated protocol which included extra encryption to communicate with C&C, so the transmitted data no longer had static marks in them. Prior to encryption, the data has the following structure (very similar to the earlier format): the first 4 bytes are taken by the magic number 0xaced1984, then a DWORD of data packet description, the next DWORD carries a zero value, 8 bytes of the hash of the transmitted block, then a DWORD with the size of the compressed data, a DWORD with the size of the source data and then the actual compressed data:
The unit structure of a data block transmitted online in newer versions of Winnt
Then the data is encrypted with regular XOR with a random DWORD size value, and in this form transmitted to the C&C. Knowing that the first four bytes in the source data must represent the value 0xaced1984, it is easy to restore the key for the XOR operation when the data were encrypted. This is how the above data (the XOR value was 0x002a7b2e) looked when it was intercepted in network traffic:
Encrypted data block transmitted online, in the newer versions of Winnti
Since the encryption key (the value with which the source data are encrypted with the XOR operation) is different each time a fragment of data is transmitted, no more static unique labels can be found in the network traffic which would quickly identify the transmitted data as belonging to the Winnti backdoor. Employing this fast, basic method, the cybercriminals have made it much harder to expose their programs’ traffic.
Whichever protocol is used (with or without extra encryption), the workflow of communication between the bot and the C&C stays the same at the initial stage of operation:
- The bot sends the first data block, thus signaling itself;
- In response, the C&C sends back the list of available plugins
- The bot starts to download plugins, sending one request at a time to download each plugin
- The C&C sends the requested plugin
- The bot sends a message that the plugin has arrived.
We should note here that, to expedite data downloading, the creators of this platform have quite skillfully implemented asynchronous data transmission in their protocol. For instance, the message that the bot has received the first plugin may only arrive at the C&C when nearly all the plugins have been already sent to the bot.
Having downloaded the malicious payload, the bot deploys the plugins in the memory and initializes them. Now it’s all set for complete remote control over the victim computer, and the bot switches to standby mode, waiting for the operator to connect and maintaining communication with the C&C by sending “empty” messages every 15 seconds or so.
Apart from supplying the plugins, no more automatic actions are performed by the C&C: all of the work to examine the infected computers is done manually by the attackers.