Strike me down, and I shall become more powerful!

2008-06-01

Aditya Kapoor

McAfee Avert Labs, USA

Rachit Mathur

McAfee Avert Labs, USA
Editor: Helen Martin

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.


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.

Know your weakness

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.

Reinforce those defences

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.

Dummy code hook table.

Figure 1. Dummy code hook table.

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).

The ClassInitialize function of ClassPNP.sys.

Figure 2. The ClassInitialize function of ClassPNP.sys.

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.

Watcher thread self-preservation logic.

Figure 3. Watcher thread self-preservation logic.

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:

  1. Re-sets the IRP_MJ_READ and IRP_MJ_WRITE pointers to its own filtering routine.

  2. Attempts to rewrite the MBR at sector 0.

  3. Attempts to rewrite the rootkit loader code and original MBR code at sectors 60, 61 and 62.

  4. 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].

Taking a closer look

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.

Code snippet from filter function.

Figure 4. Code snippet from filter function.

Code snippet to construct and send IRP.

Figure 5. Code snippet to construct and send 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’.

But defences are meant to be broken

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.

Conclusion

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.

Bibliography

[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.

twitter.png
fb.png
linkedin.png
hackernews.png
reddit.png

 

Latest articles:

Nexus Android banking botnet – compromising C&C panels and dissecting mobile AppInjects

Aditya Sood & Rohit Bansal provide details of a security vulnerability in the Nexus Android botnet C&C panel that was exploited to compromise the C&C panel in order to gather threat intelligence, and present a model of mobile AppInjects.

Cryptojacking on the fly: TeamTNT using NVIDIA drivers to mine cryptocurrency

TeamTNT is known for attacking insecure and vulnerable Kubernetes deployments in order to infiltrate organizations’ dedicated environments and transform them into attack launchpads. In this article Aditya Sood presents a new module introduced by…

Collector-stealer: a Russian origin credential and information extractor

Collector-stealer, a piece of malware of Russian origin, is heavily used on the Internet to exfiltrate sensitive data from end-user systems and store it in its C&C panels. In this article, researchers Aditya K Sood and Rohit Chaturvedi present a 360…

Fighting Fire with Fire

In 1989, Joe Wells encountered his first virus: Jerusalem. He disassembled the virus, and from that moment onward, was intrigued by the properties of these small pieces of self-replicating code. Joe Wells was an expert on computer viruses, was partly…

Run your malicious VBA macros anywhere!

Kurt Natvig wanted to understand whether it’s possible to recompile VBA macros to another language, which could then easily be ‘run’ on any gateway, thus revealing a sample’s true nature in a safe manner. In this article he explains how he recompiled…


Bulletin Archive

We have placed cookies on your device in order to improve the functionality of this site, as outlined in our cookies policy. However, you may delete and block all cookies from this site and your use of the site will be unaffected. By continuing to browse this site, you are agreeing to Virus Bulletin's use of data as outlined in our privacy policy.