Windows Registry Forensics
This blog post will cover how registry keys are stored in memory.
There are many good tools available to extract windows registry information from memory or dump but it's always good to learn how the information is stored in memory and how these tools are extracting it.
Windows Registry (Configuration Manager) in memory is represented using CMHIVE structure.You can view CMHIVE structure here https://www.nirsoft.net/kernel_struct/vista/CMHIVE.html. More about Registry structure can be found here https://binaryforay.blogspot.in/2015/01/registry-hive-basics.html.
We can locate CMHIVE structure in memory by scanning pool tag value CM10. The pool tag is part of POOL_HEADER (https://www.nirsoft.net/kernel_struct/vista/POOL_HEADER.html).The size of POOL_HEADER structure is 8 bytes in 32-bit OS and lies above CMHIVE structure in memory.Below is the result of command !poolfind <tag> <pooltype> in windbg where tag is CM10 and pooltype =1 (paged pool).
Below is the POOL_HEADER structure at virtual address 0x89bae2a0.
As we discussed above structure CMHIVE representing Registry hive lies below POOL_HEADER.
Adding 8 (size of POOL_HEADER struct for 32-bit) byte to POOL_HEADER address structure we get CMHIVE structure as shown below.
But we can use windbg !reg hivelist command to locate registry hives in memory.The command to execute is show below.
As highlighted above is USER hive and is stored in file ntuser.dat on disk.We will see how values of node key HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run stored in memory.
First Member of CMHIVE structure is HHIVE structure. HHIVE structure contains information how registry entries are stored in memory.
The DUAL structure which is member of HHIVE structure as highlighted in above image contains mapping of Registry hive cells to virtual address's in memory.
BlockAddress member of HMAP_ENTRY table points to Registry hive which starts with header hbin as shown in below image.
Node key information in Registry hive starts with header nk as shown in below image.
The node key (nk) is represented using CM_KEY_NODE structure as shown in below image node key CurrentVersion.
SubKeyCounts member of CM_KEY_NODE structure as shown in above image contains number of Sub Keys CurrentVersion node key has under it. SubKeyCounts member is an array of two elements where 0th element contains count (0x15) of non volatile sub keys where as 1st element contains count (0x0) of volatile sub keys.
SubKeyLists member of CM_KEY_NODE contains two elements where 0th element contains cell index (0x67388) of non volatile sub keys and 1st element contains cell index (0xFFFFFFFF) of volatile sub keys.
As discussed above DUAL structure member of HHIVE structure contains information to map cell index to virtual memory.We can convert a cell index to virtual memory as shown below.
cell index bits representation -
Bit 0 - Indicates whether the key is stable or volatile. Stable keys can also be found in the registry file on disk, whereas volatile keys are found only in memory.
Bits 1–10 - An index into the Directory member.
Bits 11–19 - An index into the Table member.
Bits 20–31 - The offset within the BlockAddress of where the key data resides. This is the cell within the registry. The cell contains the length of the data. Therefore, after you find the offset within the BlockAddress, you must add 4 to get to the actual data.
windg command !reg cellindex <HiveAddress> <cellindex> performs above steps to convert cell index to virtual memory. HiveAddress is virtual address of CMHIVE structure.
In above image cell index 0x67388 is converted to virtual address 0x91eb638c.
As highlighted in above image header at address 0x91eb638c is lf.
As per LF Node template Run sub key offset(cell index) is 0x019730. Again converting cell index of Run sub key to virtual address.
In above image cell index 0x019730 is converted to virtual address 0x89be6734 which contains Run node key information as shown in below image.
As discussed above node key is represented using CM_NODE_KEY structure.
ValueList which is a CHILD_LIST structure contains the information about number of value keys under Run node key.
Count - number of value keys.
List - contains cell indexes for value keys.
Address of List is also in form of cell index.Converting cell index to get virtual address of List.
In above image cell index 0x7de78 is converted to virtual address 0x91ecce7c. List is represented by below structure.
Highlighted below is Offset (cell index) of 2 elements of List which is member of CHILD_LIST structure of CM_NODE_KEY structure.
Offset(cell index) 0x70828 is converted to virtual address 0x91ebf82c.
As shown in above image, header value at address 0x91ebf82c is vk and used for Value Key and is represented by structure CM_KEY_VALUE. Name of the Value Key is malware.
Data member of CM_KEY_VALUE points to cell index which contains data of malware Value Key.cell index 0x7b320 is converted to virtual address 0x91eca324.
Data of Value Key malware is stored at virtual address 0x91eca324 as shown below.
Now converting 2nd Offset (cell index) 0x07f810 from List to virtual memory address.
As shown in above image, header at virtual address 0x91ece814 is nk and used for Value Key and is represented by structure CM_KEY_VALUE. Name of the Value Key is IyFxHT.exe.
Data member of CM_KEY_VALUE points to cell index which contains data of IyFxHT.exe Value Key.cell index 0x7f838 is converted to virtual address 0x91ece83c.
Data of Value Key IyFxHT.exe is stored at virtual address 0x91eca324 as shown below.