[Book] Rootkit And Bootkit
Last Update:
Word Count:
Read Time:
Introduction
This article serves as my study notes while reading Rootkit And Bootkit.
As I continue learning about rootkits and bootkits, I will document important concepts, techniques, and case studies from the book, along with my own understanding.
⚠️ This is a work-in-progress note.
The content will be continuously updated as I progress through the book.
El Libro
Chapter 1 - What’s In a Rootkit: The TDL3 Case Study
History of TDL3 Distribution in the Wild
It was first discovered in 2010.
Controlling the Flow of Data
To fulfill their mission of stealth, kernel rootkits must modify the control flow or the data flow (or both) of the kernel’s system calls.
To do so, rootkits typically inject their code somewhere on the execution path of the system call implementation.
The Hidden Filesystem
TDL3 was the first malware system to store its configuration files and payload in a hidden encrypted storage area on the target system, instead of relying on the filesystem service provided by the operating system. Today, TDL3’s approach has been adopted by other complex threats (e.g., Rovnix Bootkit, ZeroAccess, Avatar and Gapz).
TDL3 allocates its image of the hidden filesystem on the hard disk. The image is divided into blocks of 1024 bytes each. The first block contains a file table whose entries describe files contained within the filesystem and include the following information:
- A filename limited to 16 characters, including the terminating null
- The size of the file
- The actual file offset, which is calculated by subtracting the starting offset of a file, multiplied by 1024, from the offset of the beginning of the filesystem
- The time the filesystem was created
The contents of the filesystem are encrypted with a custom encryption algorithm on a per-block basis (e.g., RC4 or XOR operation with a fixed key).
From user mode, the payload accesses the hidden storage by opening a handle for a device object named \Device\XXXXXXXX\YYYYYYYY where XXXXXXXX and YYYYYYYY are randomly generated hexadecimal numbers.
Note that the codepath to access this storage relies on many standard Windows components.
The name of the device object is generated each time the system boots and then passed as a parameter to the payload modules.
The rootkit is responsible for maintaining and handling I/O requests to this filesystem. For example, when a payload module performs an I/O operation with a file stored in the hidden storage area, the OS transfers this request to the rootkit and executes its entry point functions to handle the request.
TDL3 shows the general trend followed by rootkits. Rather than providing brand-new code for all of its operations, burdening the third-party malware developers with learning the peculiarities of that code, a rootkit piggybacks on the existing and familiar Windows functionality.
Note: This design is particularly interesting because it avoids relying on the operating system’s filesystem, making traditional file-based detection much less effective.
Chapter 2 - Festi Rootkit: The Most Advanced Spam and DDoS Bot
Compared to TDL3, Festi adopts a more modular design by introducing a plug-in architecture, allowing its functionality to be extended dynamically.
Dissecting the Rootkit Driver
The Festi rootkit is distributed mainly through a PPI scheme similar to the TDL3 rootkit. The dropper’s rather simple functionality installs into the system a kernel-mode driver that implements the main logic of the malware.
A dropper is a special type of infector. Droppers carry payload to the victim system within itself. The payload is frequently compressed and encrypted or obfuscated. Once executed, a dropper extracts the payload from its image and installs it on a victim system.
Plug-in Management
Plug-ins downloaded from the C7C server and loaded and executed by the malware. Festi maintains an array of pointers to a specially defined PLUGIN_INTERFACE structure.
1 | |
AntiDebugging Techniques
Festi also checks for the presence of a kernel debugger in the system by examining the KdDebuggerEnabled variable exported from the operating system kernel image. If a system debugger is attached to the operating system, the variable contains the value TRUE; otherwise, it contains FALSE.
Festi actively counteracts the system debugger by periodically zeroing the debugging registers dr0 through dr3. These registers are used to store addresses for breakpoints, and removing the hardware breakpoints hinders the debugging process.
1 | |
The Method for Hiding the Malicious Driver on Disk
To protect and conceal the image of the malicious kernel-mode driver stored on the hard drive, Festi hooks the filesystem driver so that it can intercept and modify all requests sent to the filesystem driver to exclude evidence of its presence.
A simplified version of the routine for installing the hook is shown below:
1 | |
The malware first tries to obtain a handle to the special system file SystemRoot, which corresponds to the Windows installation directory. Then, by executing the ObReferenceObjectByHandle system routine, Festi obtains a pointer to the FILE_OBJECT that corresponds to the handle for SystemRoot.
The FILE_OBJECT is a special data structure used by the operating system to manage access to device objects and so contains a pointer to the related device object.
The Method for Protecting the Festi Registry Key
Festi also hides a registry key corresponding to the registered kernel-mode driver using a similar method. Located in HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services, the registry key contains Festi’s driver type and the path to the driver’s image on the filesystem. This makes it vulnerable to detection by security software, so Festi must hide the key.
To do so, Festi first hooks the ZwEnumerateKey, a system service that queries information on a specified registry key and returns all of its subkeys, by modifying the System Service Descriptor Table (SSDT), a special data structure in the operating system kernel that contains addresses of the system service handlers.