Case study: TDSS Rootkit
- Family overview
- Family traits
- Family divergence & recent updates
- Sample analysis
- Trojan installation & protection bypassing
- The driver
- Rootkit functionality
- Ring0 communication gateway
- Persistent functionality
- Blocking security solutions
- Manual disinfection
The article is also available in Russian
This is a case study for the TDSS malware, also known as Tidserv, TDSServ and Alureon. Some of the mal-named detections for components include Trojan.Win32.DNSChanger and Trojan.FakeAlert.
Here are some reasons why I decided to conduct a deep study of this malware.
- TDSS seems to be very problematic to disinfect for modern antivirus solutions.
Searching the internet by the malware name will give you a considerable list of “Help me!” kind of forum posts from users whose antivirus solutions succeeded to detect the malware, but failed to remove it.
- At the same time, there is no public detailed description of this malware provided by vendor security response.
- A regular malware posing problems to defense is an alarm.
TDSS is not a rocket science! Being quite advanced, it still does not engage any outstanding, new generation techniques.
- TDSS is actively spreading in-the-wild, developing into a wide and mighty botnet.
According to Kaspersky Lab, they are adding 100 to 300 signature detections per day for new/modified components.
Thus, TDSS is kind of a borderline case of threat. Advanced enough to turn an AV into a helpless crier or defeat it completely, but not looking critical enough to trigger a detailed study. Widespread enough to provoke numerous user issues, but not outrageous enough to trigger an epidemic alert.
TDSS is known for its durable capability to bypass active protection/HIPS, outstanding persistence and rootkit functions. Users with all kinds of AV solutions report problems disinfecting the system. Observable activity typically includes website redirects, ad popups and AV updating/loading problems. The functionality may vary widely though, since TDSS is designed as a modular unit and may easily download and install components providing extra features.
First reports of TDSS infection date back to mid-2008. Even at that time the malware exposed extraordinary persistence causing public user issues, and capabilities for bypassing antivirus protection. Given that the malware owners manage to keep this advanced functionality up-to-date for almost a year now, and also given its obviously skilful code architecture and implementation, we can assume that TDSS is being developed through a clear vision, under a steady plan and by a team of proficient engineers.
TDSS by itself is actually but a very advanced modular downloader. Its main goal is to persist into a system and then to provide a means for remote control (via a downloaded configuration file) and a framework for downloading/installing extra functionality modules.
TDSS is delivered to a user PC through a wide and elaborate distribution network. Known attack vectors include website iframe attacks   and bundling malware with pseudo-legitimate video codecs, warezly distributed legitimate software and cracks.
- TDSS original name is ‘TDL’. Most recent samples call themselves ‘TDL2’.
- The trojan files are protected from binary analysis. Code obfuscation and encrypting are used.
- Some files contain a fake Microsoft version stamp.
- TDSS installs through allowing msiexec.exe (Microsoft Installer) service to load a legitimate, but maliciously patched DLL. 
- After installation, the trojan effectively prevents antivirus software from launching or updating their bases.
- The trojan is persistent through a variety of techniques. As an example, some of the family members survive Safe Boot, which is done via registering the trojan’s driver in the HKLM\SYSTEM\ControlSet001\Control\SafeBoot\Minimal and HKLM\SYSTEM\ControlSet001\Control\SafeBoot\Network registry keys.
- The trojan creates a (hidden) registry key to store its configuration information, such as AV modules to be denied of Internet access, and malicious modules to be injected into browsers.
- The trojan hides its files and registry values by means of quite a few system hooks.
- The trojan uses a hooked function ZwFlushInstructionCache as a communication gateway to its own kernel driver.
Family divergence & recent updates
Back to 2008, a TDSS specimen presence in a box used to be marked by a driver named TDSSserv.sys, after which the malware actually got its name. Since then, malware-related file names changed several times, and included clbdriver.sys, seneka*.sys, UACd*.sys, gaopdx*.sys, tdlserv.sys and others.
Another naming change consists in that recent samples patch msi.dll for their installation, while the first samples used to patch advapi32.dll. Probably it’s a reaction to the newly added behavioral heuristics in protection solutions.
In the most recent samples the code protection is designed in a way that makes the trojan look like a regular system file or a device supporting utility. The unpacker stub is a big piece of regular code, which means there is no extra entropy throughout the file’s byte array, the latter being a sign of a packed file visible to a human eye. Furthermore, the code is enriched by random pseudo-legitimate ASCII strings and random API calls to fool a hasty analyst into thinking it's a legitimate code.
The code protection itself is trivial, being but an easily removing envelope with normal code inside.
Most recent samples contain worm functionality. The malware tries to distribute to removable drives by copying its own body into all available drives as a hidden *.com file in the hidden RECYCLER directory, and creating a file autorun.inf with the file reference on the same drive.
Most recent TDSS samples change system’s DNS addresses, thus making all the hostname requests to filter through a malicious service. It’s a brilliant solution, probably inspired by the much-talked-of DNS root server vulnerability and the Evilgrade PoC. Distributing a spoofed DNS provider throughout the network by means of a DHCP service gives an attacker control of a whole network’s web traffic, up to delivering malware to clean machines under the guise of a legitimate software update.
For analysis, I took a fairly recent sample, dating March/April 2009 (MD5: 1DE66FC07C7B5893F5F83B397AC38F3D). It is a specimen of the TDSS variety quoted by Symantec/Russia as one of the most notable as of end-March .
General execution flow of an average TDSS specimen has already been exposed, as well as its basic mechanisms in userland. Summary of high-level functions for my particular sample is available from any public sandbox. So, I will be focusing on the trojan’s most important features and driver functionality.
Trojan installation & protection bypassing
Notable is the trojan’s initial installation routine, since it allows to bypass behavioral protection/firewall. The idea is to force a legitimate service to load a legitimate, but maliciously patched DLL. This is done by modification of the msi.dll file in \knowndlls directory, followed by a regular launch of the “Microsoft Installer” service.
NtCreateSection(..”\knowndlls\dll.dll”..) // new section for a malicious dll CopyFile(..”msi.dll”, ..) // preparing the dll to patch WriteFile(.., ..) // patching The injected code will call LoadLibrary, which will invoke the malicious dll mapped into the \knowndlls\dll.dll section. Shellcode is quite elegant: push 7c906cbc ; pointer to “dll.dll” – really it’s a calculated pointer to the last part of the “ntdll.dll” name in the regularly mapped ntdll.dll call $+5 ; call next instruction so that its address was on the stack sub dword ptr [esp], 0a ; now the first dword on stack points to the first shellcode instruction, meaning that LoadLibrary will return there. Shellcode will be replaced by original code by then. mov eax, LoadLibrary jmp eax ; call LoadLibrary (“dll.dll”) After the infected dll is prepared, the \knowndlls\msi.dll section is recreated to point to an infected dll, and the msiexec.exe service is started to force loading of the now infected library. NtOpenSection(..”\knowndlls\msi.dll”..) NtMakeTemporaryObject(..) // clear the OBJ_PERMANENT flag from section CloseHandle(..) NtCreateSection(..”\knowndlls\msi.dll”, .. ..) //re-create the msi.dll section, now pointing to the infected msi.dll library in .. StartService (..”Windows Installer”..)
The main idea of this technique is that, being executed in the context of the Windows Installer, the malicious code has all the privileges to download and install anything. So it downloads and installs a fresh build of TDSS kernel component. Another idea of the technique is that it does not provide an obviously malicious behavior, so a HIPS will fail here until it ‘learns’ this particular trick.
The dll.dll functionality itself is quite simple, as seen from the flowchart (fig.1).
TDSS does not have its own userland executable file. All core functions are provided by a driver, which is loaded automatically at startup. High-level functions are provided by additional DLL module(s) injected into processes.
Core functions provided by the driver include:
- hiding the trojan’s signs
- providing a gateway into the kernel
- shoving spoofed DNS servers to network services
- blocking antiviruses listed in a configuration key from loading
- injecting a DLL into browser executables
- installation of new DLL modules.
The Trojan hooks the following functions in kernel:
The latter 3 hooks are implemented via SDT modification. NtEnumerateKey hook is used to hide all the TDSS registry keys (‘gaopdx*’ in my case), except for trusted processes, listed in the trojan’s configuration key. NtQueryValueKey hook is used to spoof DNS addresses without modifying the registry (and therefore without triggering a HIPS registry alert), via a ‘DhcpNameServer’ and ‘NameServer’ registry values substitution.
Hooks to IofCallDriver and IofCompleteRequest are implemented via splicing the kernel code in ntkrnlpa.exe in memory. They are used to hide the trojan’s files and probably network TCP activity.
Hook to IofCallDriver is used to infiltrate all the IRPs systemwide, which allows the trojan to hide its own files (beginning with the string “gaopdx*” in my case) when it catches an IRP to a file system driver.
If ( FsRtlIsNameInExpression (.."*\\gaopdx*" or "*\\TEMP\\gaopdx*"..) ) Then return (STATUS_TOO_MANY_SECRETS)
IofCompleteRequest has a similar functionality.
Ring0 communication gateway
NtFlushInstructionCache hook is slightly more interesting, providing a non-typical communication gateway to the driver. To make use of the gateway, one should call the NtFlushInstructionCache API as follows:
push 0 ; argument to the command push 'VERG' ; 4-byte command, allowing to prove the hook’s in place push 'TDL2' ; a magic value which leads execution to the command processor and not to the original API call ds:ZwFlushInstructionCache ; this is actually a piece of code from the dll.dll component, checking the presence of the core driver.
The scope of available commands is very limited and will not allow to take control over the driver (in contrast to some security drivers). Available commands include passing trojan-related variables from kernel to userland, inserting a termination job (via kernel APC) into a given process or thread, and maintaining installation of new DLL modules.
The driver engages ExQueueWorkItem to launch a number of kernel threads. Execution flow of the work items is looped to provide periodic execution. The 3 work items provide periodic renaming and re-registering the trojan’s driver (“\registry\machine\system\currentcontrolset\services\gaopdxserv.sys”), disabling of a system firewall (“\registry\machine\system\currentcontrolset\services\sharedaccess\parameters\firewallpolicy\”) and other functions.
Blocking security solutions
The driver installs a system-wide callback for new modules loaded, via PsSetLoadImageNotifyRoutine. In the hook, a check is performed whether the module being loaded is listed in the ‘disallowed’ list in the trojan’s configuration registry key. The driver will then prevent a disallowed module from loading.
Since antivirus vendors do not pay proper attention to the problem, users have to face the difficulties of the beast elimination on their own. Howewer, TDSS manual disinfection is trivial. Below is a generic algorithm, which allows to completely remove any specimen of the TDSS family, given (or not given) its core files names. The algo is suitable for any end-user, since it is really simple and requires neither special skills nor specific tools.
- Go to Device Manager and turn off and delete any unappropriate "Non PnP driver" there.
You may look for a specific name (quadraserv.sys in my case, or gaopdx*/TDSS*/clbdriver/seneka/etc .sys in case of a typical TDSS family member), but the name is always subject to change, so better not rely on it.
After this manipulation, the worm's files and registry values that used to be hidden by a rootkit before, become visible, and possible to be removed by hands.
Notice: An antirootkit can be used to reliably locate the trojan’s core files. GMER or RkU make the best choice; Avira Antirootkit is also coping with the task.
- Remove the file corresponding to the device just deleted. If there is no such file, try sorting system32/drivers and system32/ files by 'creation date' and remove whatever looks suspicious by its name and content. TDSS core files are a .sys and one or more .dll’s.
- Search throughout the Registry using the malicious device and files name strings found on steps 1 and 2. Delete all the appropriate keys.
- Remove all the://autorun.inf and://RECYCLER/*.com, if any.
- Launch your AV, and let it clean the rest (TMP files etc.)
Notice: steps 1..4 are necessary to carry out by hands, without any antivirus, because if an antivirus lacks a single signature for a trojan’s core file, the file will not be removed and thus the malware will return after reboot.
- TDSS’ success proves that durable bypassing of a protection is an ordinarily solvable task, for which no kind of advanced invention is necessary.
- Malware writers continue to explore the unobtrusive way of protection bypassing, consisting in that instead of fighting a problem, an attacker just extends his/her mind context so that the problem was solved easily, dismissed, or turned into a helpful springboard. In the case of TDSS, a skilful utilization of a white-listed application to download and install malware is observed.
- Bundling malware together with legitimate software is a great idea (though not new at all), and is also an example of unobtrusive bypassing approach. The idea is that if a user is launching an application by intent, s/he will most probably skip any security alerts, including driver installation alerts (which are quite normal in case of a video codec installation) and UAC. Plus, some behavioral protections might be fooled because of the visible application window.
- Redirecting a whole network’s DNS traffic to an attacker’s service is an extremely important innovation, since it allows transparent delivery of malware to clean machines, apart from serving malicious redirects. In some way it’s a new kind of worm functionality.
Behavior protection / HIPS developers should consider keeping an eye on the actions that allow TDSS to succeed.
- NtOpenSection, NtMakeTemporaryObject and other functions allowing tampering with system sections.
- Accessing a system DLL file.
- LoadLibraryEx with a parameter of DONT_RESOLVE_DLL_REFERENCES, which is used by dll.dll to load the original msi.dll.
- Tampering with system DNS and DHCP configuration.
- PsSetLoadImageNotifyRoutine. Though a protection may probably be turned off by the time of this API call, it may as well be not.
Though most of these actions are not malicious by themselves, they clearly pose a minor threat and thus should be considered in combinations, supplied with reasonable threat weights, and within a particular process execution context.
 Dancho Danchev, Embassy of India in Spain Serving Malware
 Malware Analysis & Diagnostic, Etude de cas - Infection rootkit TDSS
 ThreatExpert, http://www.threatexpert.com/report.aspx?md5=2c5c874235a73fc50a69780c7ad1488a
 ThreatExpert, http://www.threatexpert.com/report.aspx?md5=d2ada2dba8e036d37726ebddbcc9e9d6
 ThreatExpert, http://www.threatexpert.com/report.aspx?md5=b17d76537ef5d94547fc4ca8851b35da
 F-Secure, Backdoor:W32/TDSS Virus Description
 Symantec, Backdoor.Tidserv Technical Details
 Virustotal.com, http://www.virustotal.com/analisis/122e4ade1c0fa88cbab02880a3b2ed98
 Anti-malware.ru, История информационной безопасности за 4-ю неделю марта от Symantec
 MSDN, DhcpNameServer registry key
 Virus Bulletin January 2009. Shevchenko A., Advanced malware techniques 2008.