2008-06-01
Abstract
The rootkit that has been dubbed one of the stealthiest ever seen in the wild is back – with improved defences and new stealth code. Aditya Kapoor and Rachit Mathur look at recent developments in the MBR rootkit.
Copyright © 2008 Virus Bulletin
In the Star Wars film, the character Obi-Wan Kenobi famously says to arch enemy Darth Vader: ‘If you strike me down, I shall become more powerful than you could possibly imagine.’ In a twisted sense of life imitating art, with the roles of good and evil played out in reverse, the rootkit that has been dubbed one of the stealthiest ever seen in the wild is back – with improved defences and new stealth code.
Early variants of Mebroot (aka StealthMBR) appeared in late 2007 and achieved notoriety for their stealth techniques. This article discusses the new variants released since mid-March 2008. These are particularly interesting due to the number of improvements made to this already complex threat. This article adds to previous discussions of the threat [1], [2] and discusses ways to counter the newly introduced challenges.
In its earlier variants, Mebroot uses advanced infection techniques to modify critical areas in the system. It uses user-mode functions such as CreateFile, WriteFile etc. to access \\.\PhysicalDriveX and write directly into sectors of the disk to infect the MBR, install its own loader code, save a copy of the original MBR and install its kernel-mode driver.
Using the infected MBR, Mebroot gains full control very early during the Windows load process, slips its malicious payload into the kernel memory and hooks the IRP_MJ_READ and IRP_MJ_WRITE function pointers of \Driver\Disk. Using these low-level IRP dispatch table hooks it is able to filter out read/write requests to its malicious disk sectors including the infected MBR. No file or registry is required for the malware to survive reboots once it is installed. These techniques pose a serious challenge for detection and repair.
Despite initially seeming difficult to overcome, anti-malware developers were able to identify weak points in the malware’s defences and come up with successful solutions. However, Mebroot’s author(s) seem to have learned from its earlier shortcomings and have made enhancements to the code in the new variants to reinforce the malware’s defences and escalate the arms race.
The following two sections identify the weaknesses in the original code and the measures taken by the malware’s authors(s) to address them. Thereafter we discuss how these strengthened defences can still be broken.
Many heuristic detection tools search for inconsistencies to raise an alert. Earlier variants of Mebroot hook only two out of 11 valid pointers in the dispatch table of \Driver\Disk, resulting in inconsistent pointer target locations and thus raising suspicion (normally all pointers of \Driver\Disk point to the ClassPNP module).
To avoid suspicion in this scenario the author(s) of Mebroot created a dummy hook table within its code and hooked all other valid IRP_MJ_* functions in addition to IRP_MJ_READ/WRITE, so that they all point within the same module and thus do not raise any suspicion. Since the malware does not really want to intercept calls other than to read/write functions, all the other pointers point directly to one of a series of jumps in the rootkit module referred to as a dummy hook table. As shown in Figure 1, these jumps relay control immediately to the original routines in ClassPNP.
Another way in which an anti-malware tool can detect rootkits in memory is by comparing various kernel structures to find inconsistencies. There are a couple of places in the kernel where the original pointers of the IRP dispatch table of \Driver\Disk are normally saved, which a detection tool can use to find the inconsistency. One is the IRP dispatch table of \Driver\CDRom (which has exactly the same pointers as \Driver\Disk) and the other is the ClassInitialize function in the ClassPNP.sys file, which is an exported function and stores the original IRP pointers for its internal use at a certain offset (see Figure 2).
To bolster its defences against such an attempt at reading the original pointers and restoring them, the new variants of Mebroot hook the IRP dispatch table of \Disk\CDRom and change the pointers to match the location of corresponding hooked dispatch routines of \Driver\Disk. Similarly, Mebroot also patches all the original pointers as listed in the ClassInitialize function of ClassPNP to match its hooks (shown in red in Figure 2).
Finally, the rootkit uses a watcher thread as a fail-safe method to prevent itself from being removed even if an anti-malware program is able to ascertain the original IRP read/write pointers.
As shown in Figure 3, the watcher thread watches continuously for any attempt to restore the original IRP read/write hooks. As soon as these hooks are modified the thread does four things in the following order:
Re-sets the IRP_MJ_READ and IRP_MJ_WRITE pointers to its own filtering routine.
Attempts to rewrite the MBR at sector 0.
Attempts to rewrite the rootkit loader code and original MBR code at sectors 60, 61 and 62.
Attempts to rewrite the rootkit module in the later sectors of the disk.
A more detailed description and annotated code of watcher thread can be found at [3].
From the perspective of detection and repair one of the most interesting elements for analysis is the rootkit’s filtering routine for read/write. The filtering routine maintains a memory image, ‘Fake Sect’, of the first 63 sectors as they would have appeared on the clean machine. Now any read/write requests for the first 63 sectors are redirected to this ‘Fake Sect’ memory buffer instead of actually reading from or writing to the disk. This not only gives a false impression that the MBR is clean, but also makes it seem as if write operations are working (it would raise suspicion if write operations in these sectors didn’t work, but the ‘Fake Sect’ ensures that this illusion persists).
As shown in Figure 3, the IRP read/write pointers are re-infected before the sectors, the result of which is that these sector write requests also have to go through the malware’s own filtering routine. To allow its own requests to actually write to the disk and not to ‘Fake Sect’, the filter function checks whether a magic seed is present at offset 0x40 of IRP [2], as shown in Figure 4. These special IRPs cannot be constructed using a user-mode call, which is why the new variants use the IoBuildSynchronousFsdRequest API to construct an IRP with IRP_MJ_WRITE as the major function, then modify it and write directly into various sectors of the disk by using the device object of the disk in the call to IofCallDriver. Figure 5 shows the rootkit function used to create and send the IRP.
In the variants that we analysed, the watcher thread did not exactly work as intended, and steps 2, 3 and 4 mentioned in the previous section failed; the instruction for mov to 0x40 offset in IRP shown in Figure 5 does not get executed. So, for steps 2, 3 and 4 the thread function is not able to construct an IRP with the magic seed at 0x40. Thus the malware gets caught in its own trap and its own read/write requests are also redirected to the ‘Fake Sect’ and not to the actual disk.
Due to this bug, when an attempt is made to restore the IRP table, the watcher thread ends up infecting the ‘Fake Sect’ that was supposed to present a clean view to tools accessing these sectors. Now, anti-malware tools trying to scan the MBR may start triggering infected MBR detections based on this ‘Fake Sect’, but any repair attempts that seem to work will actually only be reflected in ‘Fake Sect’ and the disk will remain infected. One should use caution while testing solutions with these buggy variants.
In the following discussion we assume that the watcher thread functions properly and writes on the disk instead of ‘Fake Sect’.
Detection of this threat based on MBR scanning once the rootkit is active is challenging, but in-memory detection of the rootkit can easily be achieved. One of the popular methods of cleaning before these new variants arrived was to make use of the original IRP_MJ_READ/WRITE addresses of \Driver\Disk from ClassPNP!ClassInitialize, but as discussed earlier, that is no longer possible. Additionally, cleaning in the new variants involves not only restoring the MBR but also making sure that the MBR is not re-written by the watcher thread. So, to clean this threat we first have to deactivate the watcher thread before cleaning the MBR.
Deactivation of the watcher thread can be achieved simply by suspending it or by patching the watcher thread code to force self-termination or by inserting NOP instructions in the chunks of code where it checks and writes back IRP hooks and where the MBR is modified. Of course one has to be careful when patching code or suspending threads. Once the thread has been deactivated the MBR can be restored using normal user-mode methods to write to the MBR. However, as in the previous variants the IRP needs to be restored as well. Restoring the IRP hooks can still be a challenge even after the watcher thread has been deactivated because the original function pointers are difficult to ascertain, especially due to the CD-ROM hooks and the patched ClassInitialize function. But there are still other ways to restore the IRP hooks after the thread is deactivated.
As another option one could patch the magic seed value to zero, causing the filter function to allow all read/write requests to pass through except for the watcher thread’s own requests. Once this is done, normal MBR detection and repair is sufficient. This approach patches data instead of code, which is safer and does not require thread deactivation or IRP restoration.
Once the detection flag has been raised, the good old manual repair method with booting from an external medium is always a good fall-back solution.
Motivated by profit, the author(s) behind this threat have shown that they have the ability to take offensive technology concepts [4] and convert them into real-world malware. They have also identified the measures being taken to remediate the threat and have come up with a strengthened wave of variants. This new wave of variants with all its changes has presented challenges for a lot of anti-malware developers. On the brighter side, whatever the complexity of these variants, anti-malware products have been able to react quickly in providing successful detection and cleaning.
[1] GMER. Stealth MBR rootkit. http://www2.gmer.net/mbr/.
[2] Florio, E.; Kasslin, L. Your computer is now stoned (...again!). Virus Bulletin, April 2008, pp.4–8. http://www.virusbtn.com/vba/2008/04/vb200804-MBR-rootkit.
[3] Kapoor, A.; Mathur, R. Exploring StealthMBR Defenses. http://www.avertlabs.com/research/blog/index.php/2008/03/23/exploring-stealthmbr-defenses/.
[4] eEye BootRoot. http://research.eeye.com/html/tools/RT20060801-7.html.