1 The Bot

TDL4 injects two modules into processes in the system, cmd.dll and cmd64.dll, as described in corresponding subsections below. Firstly, though, we look at the configuration file cfg.ini, which stores configuration information within the hidden file system. The general structure of the file is essentially the same as in the TDL3/TDL3+ rootkit but includes some additions and modifications: // main section with information on kernel-mode driver and partner [main] version=0.03         // version of the kernel-mode driver aid=30067            // affiliate ID sid=0                // sub affiliate account ID builddate=351        // kernel-mode driver build date rnd=920026266        // random number knt=1298317270       // time of the last connection with the command server // list of the modules to inject into processes [inject] *=new_cmd.dll        // module to inject into 32-bit processes * (x64)=cmd64.dll    // module to inject into 64-bit processes // setcion specific to cmd.dll [cmd] srv=https://lkaturl71.com/;https://69b69b6b96b.com/;https://ikaturi11.com/;https://countri1l.com/;https://1il1il1il.com/ wsrv=http://gnarenyawr.com/;http://rinderwayr.com/;http://jukdoout0.com/;http://swltcho0.com/;http://ranmjyuke.com/ psrv=http://crj71ki813ck.com/ version=0.167        // version of the payload bsh=75adb55bf6a0db37c8726416b55df6dfc03e7d8a    // bot id delay=7200 csrv=http://lkckclcklii1i.com/ // setcion specific to cmd64.dll [cmd64]

1.1 Cmd.dll

According to cfg.ini, cmd.dll is injected into each 32-bit process in the system in which the kernel32.dll library is loaded. However, it is actually only able to operate inside processes where the executable names contain the following substrings: cmd.dll might perform a number of tasks:

requesting and dispatching commands from C&C servers; dispatching tasks received from C&C; clicking; Blackhat SEO (as described in the sectin “TDL4 and Glupteba” in the previous article); Injecting HTML code into an HTML document.

1.2 Network communication

All the communication between the bot and C&C is carried over the HTTP/HTTPS protocols. There are several types of C&C servers with which the bot can communicate:

Encryption

The data transmitted to and from C&C over HTTP/HTTPS are encrypted with the RC4 cipher, where the C&C server host name is used as the key, and are then encoded with BASE64 encoding (as shown in figure 1). In addition to the encryption, in some cases the data are mangled after encoding. Strings generated according to certain rules (described in the appendix) are prepended and appended to the data. This last measure is intended to avoid detection by IDS (Intrusion Detection Systems). Figure 1 – The Format of Requests to the C&C Server

1.2.1 Communication with command servers

The bot periodically requests commands from C&C servers. The configuration file contains parameters that determine how frequently the bot should connect to these servers: The request to a command server prior to encryption and encoding looks like this: “command|bid|aid|sid|tdl_ver|bot_ver|os_ver|locale|browser|tdl_build|tdl_installrnd” The command server replies with a list of commands separated by semicolons. Each command is formatted as follows command_name.method_name(Param1, Param2, …), where command_name can be either cmd or name of an executable in the hidden file system of the bootkit. method_name can take the following values: The method parameters can be of the following types:

String (Unicode, ASCII); Integers; Floats.

Here is an example of a set of commands received from the C&C:

1.2.2 Tasks

Once every 10 minutes the bot scans the “[tasks]” section of the configuration file to retrieve tasks for execution. The tasks are encoded as follows file_name=task_code|retry_count|para1|para2,

1.2.3 The Clicker

The module cmd.dll implements clicker functionality. It requests links from the servers listed under csrv key in cfg.ini file by using the URLs formatted as: clk=2.6|bid=bot_id|aid=aff_id|sid=sub_id|rd=Install_date, where bot_id, aff_id, sub_id, install_date have the same meaning as the corresponding values in communication with command server. The request is encoded and mangled. As a reply cmd.dll receives list of the values: x_url|x_ref|dword_1|dword_2, The clicker’s engine is implemented by means of the “WebBrowser” ActiveX control. For this purpose cmd.dll creates a window class with the name “svchost”. For each URL received from the click-servers the bot creates a window of class “svchost” with the name “svchost-XX”, where XX corresponds to the current thread ID passing target URL as lpParam to the CreateWindowEx function. Figure 2 – Creating a New WIndow for Clicker When the WindowProc function of the registered window class receives a WM_CREATE message, it creates the “WebBrowser” ActiveX control in the window and sets up properties: Silent – False, Visible – True. Then it navigates to the target URL by calling the Navigate method defined in the IWebBrowser2 interface with the following flags:

navNoHistory; navNoReadFromCache; navUntrustedForDownload; navBrowserBar; navHyperlink; navEnforceRestricted.

Then the clicker waits for the NavigateCoplete2 event, signifying that at least part of the document has been received from the server, and that the document viewer has been created. At this point the clicker compares the current URL with the one requested and if they match (i.e. the request has not been redirected) it emulates surfing the web:

It scans the downloaded HTML document for elements with the tags “object” or “iframe” and links pointing to objects inside the same security domain as the requested document; It emulates a user gradually moving mouse pointer to the element of the document and pressing the left mouse button.

1.2.4 Hooking mswsock.dll

In order to intercept and modify the data exchanged over the network the bot hooks several functions from the Microsoft Windows Socket Provider mswsock.dll:

WSPSend; WSPRecv; WSPCloseSocket.

WSPSend

By hooking the WSPSend routine the bot is able to intercept all the outgoing network traffic generated by the process into which cmd.dll is injected. Prior to forwarding the intercepted data to the destination host, the bot looks for the “windowsupdate” string in the data buffer. If it finds the string, then it immediately returns the error WSAENETRESET (normally signifying that the connection has been broken due to the remote host resetting), thereby disabling the Windows Update service. Otherwise it calls the original WSPSend routine and if the operation has been completed successfully, it parses the outgoing data buffer to determine whether this is an HTTP request. If so it gets the following parameters from the header:

requested resource; host; accept-language; referrer; cookie; user-agent.

Depending on the values these parameters may take, and information stored in additional files in the hidden files system, the bot performs the following actions:

injects additional functionality into HTML document through “iframe” tag; fetches keywords from requests to search providers and stores them in “keywords” file; substitutes results from search providers.

All these operations are performed in the WSPSend hook and stored in the binary tree data structure to be used in the WSPRecv hook.

WSPRecv

In the WSPRecv hook the bot actually replaces the data obtained from the destination with information it generates in WSPSend hook.

WSPCloseSocket

In the WSPCloseSocket hook the bot releases all the resources allocated to handling and interception of data for a specific connection.

1.3 Cmd64.dll

Cmd64.dll is the payload to be injected into 64-bit processes only. It is a limited version of cmd.dll and its functionality is restricted to communications with command servers and executing tasks (without hooking mswsock.dll and clicker). These communications functions, however, are fully equivalent to the corresponding functions in cmd.dll.

1.4 TDL4 Tracker

During our investigation of the malware, a TDL4 tracking system has been implemented which monitors and logs all the communication between the bot and C&C servers. The system is able to intercept and decrypt all kinds of messages, even those transmitted over HTTPS, which allows us to gain access to all commands, updates and additional downloaded modules. The output of the system is presented as an appendix to the third article in this series: “TDSS: Bootkit on the Other Foot.” However, here is an example of the kind of detail it shows. 21/02/2011 21:36:16 SEND: PID=820,MODULE=C:WINDOWSSystem32svchost.exe,P1=http://z0g7yalil0.com/clk=2.1&bid=noname&aid=40379&sid=0&rd=0,P2=Accept-Language: en-us,P3=00C7FE14,P4=00C7FE10,P5=(null),P6=(null) 21/02/2011 21:36:16 RECV: PID=820,MODULE=C:WINDOWSSystem32svchost.exe,FILEBUFFER=C:tdl421_02_2011_21_36_016_buf.txt,FILEDLL=NO 21/02/2011 21:41:41 SEND: PID=820,MODULE=C:WINDOWSSystem32svchost.exe,P1=https://zz87lhfda88.com/command|noname|40379|0|0.03|0.15|5.1 2600 SP3.0|en-us|iexplore|0|0|57989841,P2=(null),P3=00C3FEB4,P4=00C3FEA8,P5=(null),P6=noname 21/02/2011 21:41:44 RECV: PID=820,MODULE=C:WINDOWSSystem32svchost.exe,FILEBUFFER=NO,FILEDLL=NO

2 Kernel-mode components

In this section we describe the kernel-mode components of the bootkit, namely, drv32.sys and drv64.sys, which correspond to the x86 and x64 operating systems. The kernel-mode drivers constitute the most important part of the bootkit and execute the following tasks:

performing self-defense; maintaining the hidden file system in which the bootkit’s components are stored; injecting the payload into processes in the system.

In general the x86 and x64 binaries of the TDL4 are quite similar, and indeed are compiled from a single set of source files. Unlike the TDL3/TDL3+ kernel-mode component, which is stored in the hidden file system as a piece of code (independent of the base address), TDL4’s kernel-mode components are valid PE images.

2.1 Self-defense

2.1.1 Kernel-mode hooks

The bootkit conceals its presence in the system by setting up hooks to the storage miniport driver, in the same way as its predecessor TDL3/TDL3+. The hooks enable the bootkit to intercept read/write requests to the hard drive and thereby counterfeit data being read or written. Figure 3 represents the relationship between the miniport device object and its corresponding driver object after the bootkit sets up the hooks which modify the StartIo field of the target device’s driver object and the DriverObject field of the target device object. The bootkit also excludes the target device from the driver object’s linked list. After these manipulations, all the requests addressed to the miniport device object are dispatched by the corresponding handlers of the bootkit’s driver object. The bootkit controls the following areas of the hard drive:

The boot sector. When an application reads the boot sector, the bootkit counterfeits data and returns the original contents of the sector (i.e. as it was prior to infection), and it also protects the sector from overwriting; The hidden file system. On any attempt to read sectors of the hard disk where the hidden file system is located, the bootkit returns a zeroed buffer as well as protecting the area from overwriting.

Figure 3 ­– The Bootkit’s Kernel-mode Hooks The bootkit contains code that performs additional checks to prevent the malware from being detected, deactivated or removed. When the bootkit’s driver is loaded and properly initialized it queues WORK_QUEU_ITEM which performs the following tasks at one-second intervals:

Reads the contents of the boot sector, compares it to the infected image and if there is a difference between them writes an infected MBR into the boot sector (in case something managed to overwrite it); Sets the DriverObject field of the miniport device object to point to the bootkit’s driver object; Hooks the DriverStartIo field of the miniport’s driver object; Checks the integrity (the first 16 bytes) of the IRP_MJ_INTERNAL_DEVICE_CONTROL handler of the miniport’s driver object.

2.1.2 Cleaning up traces

The bootkit also takes care of cleaning up the traces it left during the loading of the bootkit at boot time (see the final article in this series, “TDSS: Bootkit on the Other Foot). Specifically:

It restores the original kdcom.dll library in kernel-mode address space. The bootkit loads the library and correspondingly fixes dependencies (imported symbols from the library) of ntoskrnl.exe and hal.dll; It modifies the registry value SystemStartupOptions of the HKLMSystemCurentControlSetControl registry key to remove the /MININT (IN/MINT) option, which was distorted at boot time, from the list of boot options which was used to load the kernel.

2.2 Maintaining the hidden file system

In order to covertly store its malicious components, the bootkit implements a hidden file system. The general structure of the file system remains the same as in the case of TDL3/TDL3+: the bootkit reserves some space at the end of the hard drive, regardless whether this space is being used by operating system. The bootkit’s file system is maintained by a set of device objects. Here we can see a volume device object representing a logical volume (partition) hosting TDL4’s files, and a so called physical device object responsible for handling IO requests from the bootkit’s payload. These two device objects are connected with each other by means of a volume parameter block – a special system structure linking a volume device object with the corresponding physical device object. This enhancement appeared for the first time when the TDL3+ version of the rootkit was released. Figure 4 – TDL4 File System Device Relationship As we can see from the figure above, the volume device object is created as a device object belonging to the DriverPnpManager driver object, so that all the requests are handled by this driver. In order to conceal the volume, the bootkit removes the device object from PnpManager’s device object linked list. The hidden file system is configured so that TDL4’s components access files stored on it using the following paths: ?globalrootdeviceXXXXXXXXYYYYYYYYfile_name – for user-mode components and deviceXXXXXXXXYYYYYYYYfile_name – for kernel-mode components. Here we can see that TDL4 appends 8 random hexadecimal digits to the volume device object, and these are generated on loading of the bootkit. If this condition is not met, a STATUS_OBJECT_NAME_INVALID error code is returned.

2.2.1 TDL4 file system layout

TDL4 uses the same technique for allocating space on a hard drive for its file system as its predecessor; namely, it starts at the last but one sector of the hard drive and grows towards start of the disk space. Figure 5 ­– Location of the Hidden File System on Disk There are some changes in the layout of the file system compared to the TDL3 file system layout. Each block of the file system has the following format: typedef struct _TDL4_FS_BLOCK { // Signature of the block // DC - root directory // FC - block with file data // NC - free bock WORD Signature; // Size of data in block WORD SizeofDataInBlock; // Offset of the next block relative to file system start WORD NextBlockOffset; // File table or file data BYTE Data[506]; }TDL4_FS_BLOCK, *PTDL4_FS_BLOCK; Here is the format of the root directory: typedef struct _TDL4_FS_ROOT_DIRECTORY { // Signature of the block // DC - root directory WORD Signature; // Set to zero DWORD Reserved; // Array of entries corresponding to files in FS TDL4_FS_FILE_ENTRY FileTable[15]; }TDL4_FS_ROOT_DIRECTORY, *PTDL4_FS_ROOT_DIRECTORY; typedef struct _TDL4_FS_FILE_ENTRY { // File name - null terminated string char FileName[16]; // Offset from beginning of the file system to file DWORD FileBlockOffset; // Reserved DWORD dwFileSize; // Time and Date of file creation FILETIME CreateTime; }TDL4_FS_FILE_ENTRY, *PTDL4_FS_FILE_ENTRY;

2.2.2       Encrypted File System

The bootkit protects the contents of its file system by encrypting its blocks. As with TDL3 it uses the RC4 encryption algorithm, which is a stream cipher with varying key length. Unlike TDL3, where the “tdl” string is used as a key, TDL4 uses the 32-bit integer LBA of the sector block being encrypted. (You may recall that TDL3+ encrypts its file system by XORing contents with a single byte incremented with each XOR operation).

2.3        Injecting payload into processes

The way TDL4 injects its payload into processes in the system hasn’t changed significantly since the previous version of the rootkit, but as it wasn’t described in our report on TDL3 (http://www.eset.com/us/resources/white-papers/TDL3-Analysis.pdf), we are going to address it here. To track creation of a new process in the system, TDL4 registers the LoadImageNotificationRoutine and waits until the “kernel32.dll” system library is mapped into memory. Once that happens, the bootkit obtains the addresses of exported symbols LoadLibraryEx, GetProcAddress, VirtualFree and queues a special kernel-mode APC ,which in turn queues a work item performing injection of the payload. The work item executing in the context of the “System” process attaches itself to the target process by calling the KeStackAttachProcess system routine. When the address space of the process is switched to that of the target process, the bootkit maps payload to it and applies relocations. The next step is to allocate a buffer in the user-mode address space of the process and fill it with the path to the payload, and code initializing the import address table and calling the payload’s entry point. When this is done the bootkit queues the user-mode APC executing user-mode code. To be precise the user-mode code initializes the import address table of the executable and calls its entry point, passing as parameters the following values:

Base address of the payload; DWORD set to 0x0000001 (DLL_PROCESS_ATTACH); Path to the payload in the hidden file system, i.e. ASCII string ?globalrootdeviceXXXXXXXXYYYYYYYYpaylod.dll.

If the entry point returns zero then the code frees memory allocated for the payload image and overwrites the path to the payload in the user-mode buffer with zeros. The following figure illustrates the overall process. Figure 6 – Process of Injecting Payload into Processes in the System

2.4 Comparison with TDL3/TDL3+

Compared to its predecessors (TDL3 and TDL3+) there are some significant changes in the kernel-mode components of the bootkit which affect the following aspects of its work: kernel-mode code layout, surviving a reboot, self-defense against removal from the system, and supported platforms. These points are summarized in the table below. Comparison of TDL kernel-mode components

Conclusion

In the final article of the series, we will discuss the normal boot process and how the bootkit exploits it. TDSS part 3: Bootkit on the Other Foot

Appendix: Mangling algorithm in python

from random import randint

mangle rules mangle_rules = [ (1, “”), (1, “AaKhQqYy”), (1, “”), (1, “123”), (1, “”), (3, “eElLdCUExX”), (1, “01”), (1, “”), (1, “34567”), (1, “mFyYjJqQXx”), (1, “*”), (2, “GgOoSsUu”), (1, “789”), (1, “@”), (1, “5678”), (1, “1234”), (1, “AchIwWqQ”) ]

def mangle_request(original_request): # mangled result mangled_request = ""

run through the list of rules for rule in mangle_rules: if rule[1] == “@”: # copy original request mangled_request += original_request else:       # add a number of random characters to the request according to the rule for i in xrange(rule[0]): if rule[1] == “*”: char_set = “ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890” else: char_set = rule[1] # select random character mangled_request += char_set[randint(0, len(char_set) - 1)]

return mangled_request