Let’s say you are given an encryption key and asked this question — “This key can be found somewhere in the Kernel memory. You will be given a memory dump and all the tools you need. Your job is to find where and how this key is stored in the Kernel”. How do you go about solving this problem?
I have broken this down into 5 steps:
- Get the key (FEK) that you need to search for.
- Locate the regions of memory that contain the FEK.
- Identify the type of Kernel memory that contains the FEK.
- Identify the Kernel object that holds the FEK.
- $$ Profit
Step 1— Get the key (FEK) that you need to search for
Ok, first you will need a key to search. I have a bunch of Python scripts that you can run on a Windows host that will create an EFS encrypted file and dump the key for you. There is too much to explain about how this is done. If you are interested please refer to this video. Back to the focus of this article, you can see from the below image that we got an encryption key as an output of the script.
Step 2 — Locate the regions of memory that contain the Key
To search the live memory, let’s use the REkall tool. I am launching Rekal with
rekal --live Memory option to do a live search.
How do we search for a FEK byte string in memory? We can use the yarascan plugin. The syntax for the plugin is: yarascan(binary_string=”FEK as a hex string”)
A snip of the Rekal yarascan results is shown in Figure 2.2. We can see the FEK is found in the kernel on a page with a physical offset of 0x14f48000. Since the FEK here is a fully random 32-byte string in memory, false positives are unlikely.
Step 3 — Identify the type of Kernel memory that contains the FEK.
We now know for a fact that the FEK is available in the Kernel memory at physical offset 0x14f48000. What is the Kernel using this memory for? We can find it out using the RamMap tool from SysInternals.
In the “Physical Pages” section of the RamMap tool, we can see the address 0x14f48000 is allocated to the Nonpaged Pool in memory. So till now, we have identified that, after EFS encryption, a copy of the FEK is found in the non-paged pool section of the kernel memory.
Step 4 — Identify which Kernel Object holds the FEK.
Kernel memory is a collection of pool objects. Identifying the type of pool object holding the FEK can be done in two steps.
- Run the yarascan plugin to scan only the non-paged pool. This will give the exact virtual offset of the FEK (and not just the virtual page offset).
- Run the analyze_struct plugin on the virtual offsets. In this case there are two virtual offsets: 0xcd0471c63b6c and 0xcd0471c63b90. Figure D5 shows the results of running analyze_struct 0xcd0471c63b6c.
Step 5 — $$ Profit
At this stage, you could probably write a Volatility plugin/script that will scan for ‘Efsm’ pool tags and print out the EFS encryption keys. It has been on my mind for a while but I haven’t gotten around to doing this. So that’s all for now!