Forensic analysis of disclosed uninitialized kernel memory

Memory images, page files, hibernation files, crash dumps are standard targets for memory forensics. But there are unusual ones: for example, chunks of disclosed (leaked) uninitialized kernel memory found on a drive.

Objects containing chunks of disclosed (leaked) uninitialized kernel memory are quite uncommon on a drive. Typically, disclosing these chunks of memory to a user-readable location is a vulnerability (such chunks may contain sensitive data like encryption keys and memory addresses used to defeat the address space layout randomization).

However, disclosing such data to a location readable by privileged user-mode processes only isn’t always considered as a vulnerability, so there is no issue with page files, which were designed to hold memory pages. Frankly speaking, an unencrypted page file is a serious issue for a virtual machine with its memory protected from a host machine using hardware encryption, so the page file encryption feature should be enabled for such configurations (thus, in these configurations, any leak of unencrypted memory to a virtual drive should be considered as a vulnerability).

And here are some historical examples of what I’m talking about:

So, how do these memory leaks happen?

A kernel, or a driver, or another kernel component allocates a buffer, writes something to this buffer, then writes this buffer to a drive (or sends this buffer to an application, if we talk in general). During the allocation process, the buffer isn’t initialized with null bytes, so it can contain remnant data chunks (which were marked as free memory before; this is very similar to deleted files, but in memory). If the buffer wasn’t entirely overwritten by a kernel component in question, this results in the uninitialized kernel memory disclosure: remnant data chunks are made available outside of the kernel space (on a drive or within an application).

Here is an example of a memory chunk found in the slack space of an NTFS-compressed file (the same bug as described above):

ntfs-slack.png
A layout of the last cluster of an NTFS-compressed file

In this example, the NTFS driver allocated a buffer to store compressed data, wrote a smaller chunk of compressed data (it’s marked as Compressed data), left remnant data intact (it’s marked as RAM slack and File slack), then wrote this buffer to a cluster on a drive (the last one of that file, previous clusters are filled with compressed data entirely).

As a side note. Developers of drivers are expected to sanitize each allocated buffer if it’s going to be sent to the outside world. Also, Microsoft introduced the ZeroPool shim to the kernel (in the Insider Preview versions of “19H1”), so drivers that don’t follow this rule can be fixed (this shim initializes every buffer allocated using the ExAllocatePoolWithTag() routine with null bytes).

What artifacts can be found in such memory leaks?

Basically, any artifact. There is no way to predict which data is going to be disclosed to a drive. Registry data (key nodes, key values, data cells), NTFS file records, file system paths (as ASCII and/or Unicode strings), network structures (like packets) are expected candidates.

In general, HEX editors, tools like strings and bulk_extractor can be used during the initial analysis stage. Note that random memory chunks may not provide enough context to identify data structures and their relationships (smaller leaks give less context, a small leak may give you no chance to identify which data it contains).

Is this really useful?

It depends. As I said, this source of artifacts is quite uncommon on drives, two issues mentioned above were fixed by Microsoft.

However, another source is still here. It’s the “klobjdb.dat” file (located in the “\System Volume Information” directory of a system volume) created by Kaspersky products (like Kaspersky Total Security and Kaspersky Anti-Virus).

This file is used to keep some data which is internally used by Kaspersky products. The data is stored in pages of 8192 bytes, many pages are used partially and contain remnant data at the end:

kts2019_kmd.png
A layout of a page in the “klobjdb.dat” file: “used” data is shown as selected, remnant data is shown as not selected, the first 4 bytes of a registry key node are highlighted, you can also see some registry key values starting with the “vk” signature

(A larger version of this image.)

As a side note. I reported this issue to Kaspersky and they confirmed it (but they didn’t consider this as a vulnerability). My report was sent 90 days ago.

In general, the “klobjdb.dat” file is one of the largest unintentional sources of uninitialized kernel memory.

kl-file.png
An NTFS file record found in the “klobjdb.dat” file (the signature is shown as highlighted)

Given that uninitialized kernel memory is constantly leaking to this file, it becomes a perfect place to try during the forensic analysis.

For this reason, I added the “deep scan” mode to the yarp-memcarver tool. In this mode, the tool locates and extracts standalone key nodes and key values (without trying to extract hive bins or other continuous blocks of registry data).

The output is like this:

Offset: 339832
Type: key
Name: {084F01FA-E634-4D77-83EE-074817C03581}
Last written timestamp (UTC): 2018-11-02 22:52:40.075114
Access bits: 2
Number of subkeys: 0
Number of values: 1

Offset: 339952
Type: value
Value name: oem0.inf
Value type: REG_BINARY
Data size: 4
Data (hexdump):
00000000 01 FF 00 00 ....

Offset: 339992
Type: key
Name: {0F4130DD-19C7-7ab6-99A1-980F03B2EE4E}
Last written timestamp (UTC): 2018-11-02 22:52:48.895138
Access bits: 2
Number of subkeys: 0
Number of values: 1

Offset: 340112
Type: value
Value name: oem1.inf
Value type: REG_BINARY
Data size: 4
Data (hexdump):
00000000 01 FF 00 00 ....

Finally, the tool can be used against regular memory dumps, because they are expected to contain partially overwritten pages (it’s okay if such pages are kept within the kernel space).

One thought on “Forensic analysis of disclosed uninitialized kernel memory

Leave a comment