High-Resolution Dynamic Analysis of Windows Kernel Rootkits

High-Resolution Dynamic Analysis of Windows Kernel Rootkits

Many recently-discovered sophisticated attacks against Windows users have been found to use at least one component executing in the kernel of the operating system. Examples for such APT attacks are Equation, Regin, Dark Hotel, or Turla/Uroburos, and they have received a lot of scrutiny from the security and research community.

These threats are particularly pernicious because their kernel components are running with the highest level of permissions available on a computer system. As such, it is very difficult for traditional antivirus systems to detect (or protect) a computer system from these attacks, because the attacker is running with the same (or higher!) permissions as the AV solution.

At the same time, it is far from trivial to analyze such kernel-based APTs inside a traditional sandboxing system, as kernel behavior often lies outside the scope of what can be monitored using traditional hooking mechanisms.

In this post, we will show how the latest release of the Lastline Breach Detection Platform using a full-system emulation approach defeats even the latest version of kernel-based attacks. In a series of follow-up posts, we will focus on individual APT families and techniques, and detail how our sandbox can be used to analyze and detect these threats.

Analysis of Malicious Code in the Kernel

Most traditional sandboxes available today are based on intercepting API function invocations by placing hooks into the user-mode libraries loaded by a program under analysis. The idea is to intercept – and sometimes even tamper with – any parameters passed to functions that can be used to perform security-relevant behavior on a system.

Some slightly more advanced sandboxes are also able to intercept system calls invoked by the analyzed program, to address the case in which evasive malware bypasses user-mode functions and interacts with the operating system kernel directly. In both systems, the core idea is to interrupt the execution of malicious code at certain points of interest in order to extract and log the functions (and their arguments) that represent the actions performed by the program under analysis.

When malware manages to load one of its components into the kernel (for example via an exploit, as we will cover in a follow-up post), this malicious component is loaded indistinguishably from trusted, operating-system code. At this point, it is no longer feasible to monitor actions triggered by malware code using traditional hooking mechanisms, as the malware behaviors do not rely on invocations of user-mode APIs or system calls any longer.
With the rise and prevalence of kernel-mode APTs, it is crucial to overcome this problem in order to defend against these recent attacks.

Lastline’s high-resolution sandbox uses a full-system emulation approach, which allows the sandbox to see every instruction executed inside the analysis environment. This allows our engine to interrupt the execution of an interesting piece of code at any time (and not only when an API function or system call is invoked) to extract behavior, regardless of whether the malicious code is running in the context of a user-application or the operating system’s kernel. At the same time, our approach allows us to track which code has been loaded or modified from the context of untrusted operations (such as newly-loaded drivers) and thus track which code belongs to the original, trusted kernel, and what code is part of the malware threat and, therefore, requires special attention.

Anatomy of Traditional Kernel-Rootkits

To start off, let us take a brief look at how kernel-based attacks have worked in the past. While some of the attacks described below are rather well-understood, they nevertheless highlight a few key concepts a next-generation analysis sandbox has to fulfill to allow for the analysis of kernel-based malicious code.

Most traditional rootkits have the ability to hide the user-mode components of a malicious program. This is typically used to hide these components from AV software or analysts looking for signs of an infection. This can be achieved by hooking or modifying critical system tables, such as SSDT or IDT, or by modifying other kernel memory regions, such as code or data sections of system modules.

For such rootkits, the infection typically works as follows: First, an attacker exploits a user system (for example, the attacker tricks the user to visit a URL serving a drive-by download exploit attacking the user’s browser), loading a piece of malicious code into the kernel. This code then intercepts any system call invoked by user-mode applications, and filters any data returned to a program that would reveal the infection. For example, if a security product is looking for newly-generated files in a directory, this filter function would simply remove any malicious files before returning a directory listing to the requesting program. In a similar way, these hooks can filter and hide the presence of registry modifications, running processes, or any other event generated by the attacker.

Anatomy of Traditional Kernel Rootkits Malware
(View Full-size)

As one might have guessed, the presence of such filtering code loaded into the kernel is very indicative of malicious activity. Therefore, the Lastline analysis engine is able to analyze any code that is newly loaded into the kernel of the operating system under analysis.

Additionally, whenever a critical function or memory location is hooked or modified, the analysis system uses this information to classify the origin of this code as malicious. At the same time, the analysis report exposes all this information with details on the type of function that was hooked or modified, providing analysts with highly-valuable information about the attack:

Malware analysis report showing kernel modification
Analysis report showing kernel modification (View Full-size)

Malware analysis showing SSDT hooks modification
Analysis report showing SSDT hooks modification (View Full-size)

Analysis showing critical kernel memory region modification
Analysis report showing critical kernel memory region modification (View Full-size)

Anatomy of Kernel-Based APTs

Recent waves of APT-attacks, such as Regin, Dark Hotel, or Turla/Uroburos, have shown that malware authors are using these rootkit techniques not only to hide the presence of other user-mode components, but also to leverage the privileges of kernel-code and integrate much more sophisticated behavior directly into the kernel-components. Examples of such added functionality are the ability to inject arbitrary code into running processes, or code to download and install further code, directly from the context of the kernel.

At the same time, these APTs have also become more evasive against traditional, signature-based detection systems. Very often, they use encryption and loading in multiple stages to hinder analysis. Often they use hidden and encrypted files in unpartitioned sections of the file-system to hide their presence, even when the system is booted using a trusted, uncompromised kernel to analyze an infected host.

Anatomy of kernel-based APTs
(View Full-size)

With full visibility into any malicious code running in user or kernel context, the Lastline sandbox is able to perform comprehensive analysis of any such components. Whenever the engine sees that untrusted code tampers with or injects code into another user-mode process, the system includes any behavior exhibited by the modified user-process in the analysis.

This way, our analysis results reflect the full chain of infection, from the initial exploit modifying the kernel, all the way to kernel code spreading to other user-mode processes.

Kernel memory hooking and user-mode injections
Analysis report showing kernel-memory hooking and user-mode injections (View Full-size)

Understanding Kernel Modifications: Necrus

As we have described in a previous post on process snapshotting, the Lastline analysis engine allows a security analyst to expose memory dumps from various stages of the malware execution in addition to the detailed description of the behavior observed during analysis.

This is no different for kernel-based malicious code, so let us use a variant of the Necrus Rootkit to take a deeper look at how this malware behaves as part of the kernel.

As any analyst who has worked on Necrus (or really any kernel rootkit) knows, it is very tedious to analyze and understand the various decryption loops obfuscating the interesting payload of a kernel driver.

The following snippet of code shows just one such decryption loop present in Necrus:

Understanding kernel modifications — Necrus
(View Full-size)

In addition to using various obfuscation/decryption loops, Necrus also contains fake entries in the import table that are not related to any payload functionality:

Necrus fake entries import table
Function Exports in IDA (View Full-size)

Luckily for this analysis, we can skip the description of how to set up a kernel debugger to intercept execution when the kernel component has decrypted itself. The Lastline analysis engine does all of this automatically and provides us with a decrypted, de-obfuscated, repackaged executable snapshot that can be loaded via IDA Pro.

Once opened in IDA, the snapshot reveals all information about the decrypted payload. For example, the Rebuilt APIs section contains information about imports pointing to decrypted payload functionality:

Deobfuscated function pointers extracted analysis engine
Deobfuscated Function Pointers Extracted by Analysis Engine (View Full-size)

Starting from this table, it is trivial to find a particular hook the analyst is interested in. For example, we can follow KeServiceDescriptorTable, which reveals that the sample patches the SSDT, and sets hooks at NtOpenProcess and NtOpenThread to the code seen below:

Malware sample patches the SSDT
(View Full-size)

The routine first maps the Service Descriptor Table in memory to find the function addresses of NtOpenProcess and NtOpenThread. These pointers are then overwritten with addresses of the corresponding hook functions. Subsequently, calls to NtOpenProcess or NtOpenThread from any user-mode application execute the hijacked functions of the rootkit.

Summary

Kernel-based malicious code has become part of the most advanced and sophisticated attacks seen in recent months. As a result, security solutions and analysis sandboxes need to adapt and provide the ability for analyzing and understanding kernel code to protect users from these threats.

Lastline’s high-resolution sandbox uses a full-system emulation approach and is able to perform effective analysis of code running in both kernel and user spaces. This allows us to obtain a complete picture of the malicious behavior to detect and mitigate these advanced threats.

To learn more about Lastline’s rootkit analysis capabilities, read the announcement that we made today in a press release.

Clemens Kolbitsch

Clemens Kolbitsch

Clemens is a Security Researcher and engine developer at Lastline. As a lead-developer of Anubis, he has gained profound expertise in analyzing current, malicious code found in the wild. He has observed various trends in the malware community and successfully published peer-reviewed research papers. In the past, he also investigated offensive technologies presenting results at conferences such as BlackHat.
Clemens Kolbitsch