The Windows Registry, a fundamental component of the Windows Operating System, empowers users to fine-tune system policies and manipulate low-level configuration settings. However, this registry's capabilities have also made it a target for exploitation by malicious actors and adversaries, who exploit this enigmatic database to carry out their malicious activities.
As indicated by the title, we will delve into how I discovered a method to leverage the functionalities of 'reg save' and 'reg restore' to establish persistence while adeptly evading detection measures.
In this blog post I will cover the following subjects:
- How it started? A Brief Overview
- Sysmon Registry Event Evasion
- Proof of Concept (POC) Development
- "reg save" and "reg restore" mechanism
- parsing the registry backup file
- RegF Header
- HiveBin and Cell Record
- References
How it started? A Brief Overview
While conducting research on registry persistence, I reached a point where I opted to generate a registry backup for my test registry. This approached help me to avoid the need for repetitive input. I accomplished this by employing the 'reg save' command, which allowed me to save the registry hive. However, upon looking to the contents of the registry backup file, an intriguing realization dawned upon me. Within the file, I discovered an inclusion of registry keys, their corresponding names, and the associated data values relevant to the registry I was actively working on. It dawned on me that by making modifications and then restoring this backup, I could effectively manipulate the registry, capitalizing on the capabilities of these two features within the 'reg.exe' tool..
Figure 1 illustrates the modification I did to the saved registry hive and the consequences of this alteration in Figure 2 after the restoration process.
|
Figure 1 - registry saved hive modification |
|
Figure 2 : after reg restore |
Challenge
In this test, we can conclude that we have successfully identified a method to establish persistence through the utilization of 'reg save' and 'reg store.' However, a crucial next step involves finding an automated process to modify the saved registry hive. This is essential in order to create a persistence entry within the registry run key. Hence, the challenge at hand is to determine the methodology for effectively parsing the registry backup file.
Sysmon Registry Event Evasion
Before addressing the challenge presented in the initial sub-heading, I conducted an examination of the Sysmon registry events that are generated when saving and restoring a registry backup file. Surprisingly, no events were captured during these processes. This situation prompted me to investigate how Sysmon monitors registry events.
Sysmon (System Monitor) is actually a windows device driver installed as service that monitor and log system activity to the windows event log.
The device driver component of Sysmon is located within the .RSRC section of its file. Consequently, I extracted this component and loaded it into IDAPRO for analysis. During this examination, it became evident that the Sysmon driver utilizes the 'CmRegisterCallback()' callback function to effectively monitor registry events.
|
figure 3 : Registry callback function |
Examining the recently renamed function "func_ExCallbackFunction()", we can gain insight into how Sysmon utilizes it to scrutinize registry operations of the REG_NOTIFY_CLASS type. In the most up-to-date iteration of this tool, the Sysmon driver effectively filters and monitors the following REG_NOTIFY_CLASS instances:
- RegNtDeleteKey
- RegNtRenameKey
- RegNtPostCreateKey
- RegNtPostDeleteKey
- RegNtPostSetValueKey
|
figure 4 : REG_NOTIFY_CLASS filtering |
In this particular scenario, we can deduce the reason behind Sysmon's inability to capture registry operations like "reg save" and "reg restore." This stems from the fact that the Sysmon driver is not actively monitoring and processing the REG_NOTIFY_CLASS associated with registry restoration and saving.
Now Let's develop our POC... :)
Proof of Concept (POC) Development
Prior to delving into the use case of my proof of concept (POC), I took the initiative to gain a comprehensive understanding of the inner workings behind two essential components
"reg save" and "reg restore" Mechanism: My primary focus was to grasp the underlying mechanisms of both "reg save" and "reg restore." This approach allowed me to emulate their functionalities within my code autonomously, eliminating the need for external invocations.
Upon inspecting the code of reg.exe, a notable revelation emerged: the initial step involves the adjustment of the process token's privilege. Initially, the "SeBackupPrivilege" is granted, enabling the preservation of the registry hive through the utilization of the RegSaveKeyExW() API. Subsequently, the focus shifts to the "SeRestorePrivilege" which is activated to facilitate the restoration of the registry backup file, accomplished by invoking the RegRestoreKeyW() API.
Parsing the Registry Backup File: Equally important was the task of developing a method to effectively parse the registry backup file. By knowing its structure, I could ensure seamless extraction and utilization of critical information contained within the file.
In terms of parsing the registry backup file, I didn't find any full documentation from Microsoft to help me parse this file type. However, fortune favored me as numerous research efforts dedicated to deciphering this file type have been diligently conducted. These valuable insights have been compiled and are readily accessible within the reference sub-heading of this blog.
While an exhaustive exploration of each header within the registry backup structure isn't within the scope of my discussion, I'm inclined to shed light on the pivotal segments that I leveraged for parsing and subsequently modifying. These particular insights hold significance, as they played a crucial role in enabling both persistence and defense evasion strategies within the context of the registry backup.
RegF FileHeader
Also known to be the base block. this file header is 4096 bytes in length and contains information such as signature header "regf", Major/Minor version, file type, file format, root cell offset and structure in little endian form.
|
figure 5 : regf file header |
HiveBin and Cell
the hive bin starts with "hbin" header and consist of cells. A hive bin header is 32 bytes in length.
after hive bin is the Cell. It is a variable in size depending on the cell data record type listed below:
|
figure 6: cell record type |
for my POC I focus on the Registry key Node "nk" that contains structure field to check the existence of registry named key, total number of registry value count and if the registry sub key entry is already deleted.
Furthermore, I harnessed the Registry Key Value "vk" header to extract and interpret individual registry value data. This approach allowed me to precisely correlate each piece of registry value data with the specific registry key under examination, enhancing the accuracy and integrity of the parsing process.
Below is the code snippet of my POC "RegREeper.exe" in enumerating all Registry value data in the registry hive file.
|
figure 7: registry value data enumeration |
now we are all set and we're ready to prepare our POC use case with the following approach:
- Adjust Token Privilege
SeBackupPrivilege
to be able to save HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
registry hive. - saved the registry hive to "save_reg.hive"
- Parse registry hive structure (
save_reg.hive
) to look for registry value key data string to be modify. - compute the length of the registry value key data string during parsing, then used that length to generate random file name.
- dropped a copy of itself in
c:\users\public\{random_filename}.exe
- create a copy of
save_reg.hive
-> mod_save_reg.hive
- modify the current registry value key data string of
HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run
with the file path of its file copy. - Adjust Token Privilege to
SeRestorePrivilege
- trigger RegRestore via
RegRestoreKeyW()
API.
and viola! we have a working POC that gain persistence by modifying registry entry in Registry Run keys that can outsmart Sysmon Registry Event Monitoring.
The POC code:
short demo:
References: