Is it possible to create such a registry key that will be visible in Windows as part of an active (connected) registry, but will not be visible to programs that work with an inactive (disabled) registry? It turns out that if you have the opportunity to change only one kernel variable (for example, using a driver), then yes, there is a way.
Why do you need it?
Hiding registry keys from programs that work with an inactive registry, while maintaining the normal operation of these keys with standard Windows operating system tools (as part of the active registry), can be used to achieve two goals:
- Hiding changes made to the registry from forensic investigation (for example, hiding the keys of a particular service that will be correctly read and used by the Windows operating system during the boot process, but will not be visible to third-party programs working with the inactive registry during the drive research);
- hiding registry changes from pre-boot integrity monitoring (for example, making such changes to registry keys that are not visible to trusted boot modules during integrity monitoring, but will be visible to the Windows operating system itself).
How does this happen?
The Windows registry consists of two parts: a volatile part (registry keys and values ​​that will be lost after the hive is disconnected due to the fact that they are not saved to the file; for example, the “SYSTEM” bush Current key), the non-volatile part (synchronized with registry hive file).
Since during the writing of the non-volatile part to the hive file, it is necessary to ensure the integrity of the stored data (for example, in the event of a power failure interrupting data writing operations), the Windows kernel uses registry logging — the recorded data is first stored in the log file (this file is located in the same directory as main file and has the extension “.LOG”, “.LOG1” or “.LOG2”) and only then to the main hive file (if writing to the log file is not completed successfully, the main file will remain intact and intact, and If writing to the main file is not completed successfully, its integrity can be restored using log data that was successfully recorded before the failure).
')
The proposed method of hiding keys (and their values, as well as other elements) is to save the relevant data only in the log, but not in the main registry hive file. Third-party programs that work with an inactive registry, in most cases ignore the log file (s), and therefore registry keys stored in the log, but not in the main file, will be invisible to these programs. The Windows kernel, on the other hand, uses the log to restore the integrity of the hive when it is connected, and therefore the keys discussed will be visible to the kernel and, accordingly, other running programs.
To block writing to the main hive file, you can use the debugging mechanism that appeared in Windows Vista. To understand the essence of this mechanism, you need to consider the logging scheme that appeared in Windows Vista.
Logging to Windows Vista
In Windows XP and earlier versions of Windows, each non-volatile registry hive has one main file and one log file. The exception to this rule is the SYSTEM hive in Windows 2000 and earlier versions of Windows, which mirrors (to a file called “system.alt”), rather than logging, to simplify the bootloader code (which should load the specified hive into memory) and not add it supports recovery from the log (mirroring is the sequential writing of data into two main files, which as a result will have the same logical structure of keys, values ​​and other elements).
Logging is done by compact (without alignment by offsets) saving to the log file the data to be written to the main data file along with the structure — the bit map of the sectors of the main file, which allows determining which offsets need to be written into the main file data blocks from the log file. If upon connecting a hub it is determined that the data has not been completed in its main file, then the blocks from the log file will be read, the offsets of these blocks in the main file will be determined (using a bitmap), and then these blocks will be written to the main file, thus completing the previously interrupted recording due to failure.
Such a scheme has a significant drawback - if an I / O error occurs during writing to the main file (for example, because of an attempt to write to the bad sector), then further operations of synchronizing the hive with the main file will not be possible until the computer is restarted (even if if the bad sector is neutralized by reassigning sectors at the file system or storage driver level). This is due to the fact that logging each time clears the log file from old data, which means that writing to the main file will violate the integrity of this file, and a new attempt to synchronize the hive will require erasing data from the log, which remains the only way to restore the already broken integrity of the main file.
Therefore, if such an erasure of a log is allowed, a situation may arise when the integrity of a single log file is compromised due to a new failure, while the integrity of the main file was broken by a previous failure.
Logging from Windows Vista (to Windows 8.1)
To solve the problem of synchronization of the hive with the main file in conditions of repeated failures, a double journaling scheme was implemented. In this scheme, there are two log files for each main file (with the extensions “.LOG1” and “.LOG2”). The default is the first log file (".LOG1").
If an error occurred while writing to the main file, then the log file changes (from “.LOG1” to “.LOG2” and vice versa). This approach ensures that there is always a valid log file containing data from a previous synchronization attempt. As a result, a failure while writing to the log file (after a failure while writing to the main file) will not lead to an unrecoverable violation of the registry hive integrity (by the way, if this situation does occur, the Windows kernel has self-healing mechanisms that correct obvious errors in the logical bush structure).
But such a logging scheme needs to be debugged, and therefore a variable was introduced into the Windows kernel that allows you to simulate repeated write errors in the main files of all registry hives, CmpFailPrimarySave. For unknown reasons, this variable is also found in regular kernel versions (and not only in debug versions). If a non-zero value is written to this variable, the function of writing data to the main file will simulate an error at different stages of such a record.
It should be noted that in the process of connecting the registry hive, the kernel must choose which of the two log files to use for recovery, for which a relatively complex algorithm is implemented, which determines which of the log files has preserved integrity, which of them contains the later version of the data being written, and so on. Before Windows 8, this algorithm contained a serious error, as a result of which in almost all cases, regardless of specific details, the first log file was selected (“.LOG1”). In particular, for Windows 7, the corresponding algorithm fixes were released only in March 2016 (therefore, all this time, double logging in Windows 7 provided integrity protection no better than Windows XP). To overcome the described error, it is necessary not only to block writing to the main hive file, but also to block the transition to the second log file (".LOG2") in case of failure (so that the first log file always contains the latest data, even if to the detriment of integrity in the event of failure; otherwise, during the next boot, the system registry hives may be restored to a state unexpectedly earlier than when the computer is completely shut down). Fortunately, the next value of the variable under discussion allows to achieve the desired effect without changing the log file - 3.
The same variable will also work in newer versions of Windows (8.1 and 10), where a different way of logging is used (outside the scope of this article).
Experiment
As an experiment, create an invisible key and its value in the Windows 7 operating system (Service Pack 1). To do this, change the value of the CmpFailPrimarySave kernel variable from 0 to 3 in the running operating system, and then create the registry key "HKEY_LOCAL_MACHINE \ SYSTEM \ invisible_key" with the value "invisible_value" containing the string "123456". Then turn off the operating system in a regular way and export the SYSTEM hive files.
After re-enabling the operating system, launch the registry editor and note that the desired key and value are visible in it (Fig. 1).
Fig. 1: Windows Registry EditorAt the same time, third-party programs (for example, Windows Registry Recovery and Registry Explorer) do not display the required key and value in exported registry files (Fig. 2 and 3).
Fig. 2: Windows Registry Recovery
Fig. 3: Registry ExplorerConclusion
Do not overly rely on programs that work with an inactive registry while investigating an information security incident, as well as during integrity monitoring. This article has demonstrated one of the many ways to hide a registry key, its values ​​and other elements from similar programs.