In the previous post we dealt with one of the most popular anti-forensic techniques - timestomping. So we changed the timestamps of the files to confuse the analysts and make the files appear unrelated to malicious activity. This time we will try to transfer timestomping to another source of evidence - the Windows registry. The register is by far one of the most important sources of evidence. There we will find information about both the operating system and computer configuration, as well as user activity. Its content is also not easy for attackers to hide. Just as simply deleting a file does not physically erase it from disk, deleted keys and values will often be recoverable.
Let's start with the basics - the structure of the registry and why attackers would be interested in changing timestamps at all. The registry is stored in hive files that contain key configuration information about the system and user activity. The registry consists of four main keys:
In the file system, most of the registry is located in the Windows\system32\config directory:
Specifically, we will be interested in DEFAULT, SAM, SECURITY, SOFTWARE and SYSTEM files. In the registry, these files will contain keys under HKEY_LOCAL_MACHINE and store information about machine configuration, services, devices, user accounts, password policies and applications. In addition to computer-related data, each user has his own section of the registry stored in the NTUSER.DAT and UsrClass.DAT files. The keys contained therein are extremely useful for DFIR analysts as they allow to obtain a lot of information about the user's behavior, such as recently searched files, addresses entered in the web browser, open files or folders. In the course of post-hack analysis, they allow you to track the activity of attackers in the system.
In the attached pictures, we can see the "Last write timestamp" parameter, which allows you to determine the time of the last key change. From an incident analysis perspective, this signature, combined with what information stored in the keys, helps analysts reconstruct the course of events. Recalling the example of information about recently searched files, we can even determine whether files related to specific, confidential projects were searched during malicious activity. Registry timestomping by attackers can therefore cause the activity time determined on the basis of the keys to be inconsistent with the information obtained from other artifacts, significantly disrupting the course of the investigation.
So let's create an artifact that could simulate attackers trying to gain permanent access to the environment. One of the most interesting places is the keys created in connection with the automatic running programs or commands at startup, which can be used to maintain access to the environment. So let's put such an example entry in the key
The favorite tool of all attackers - the calculator - is therefore in place. Now let's look at the timestamp of the last key entry:
It is February 2, 22:37. To change this value we will use a tool written by Joachim Schicht "SetRegTime". It takes advantage of the NtSetInformationKey function available in the API Windows. As we read in the documentation, it allows you to modify the parameters contained in the structure KEY_SET_INFORMATION_CLASS where we will find KEY_WRITE_TIME_INFORMATION storing information about the time of the last write to the key. In addition, the author used functions NtFlushKey to force the changes to be written to disk immediately after the change. The program has two functionalities, the first one allows you to read the value for a specific key:
The displayed time agrees with what we saw in the Registry Explorer window. The second is to change the attribute. We will move the time of the last save a few days back. It is worth noting that, as with file timestamps, the accuracy extends beyond seconds. For registry keys, these are 100 nanosecond intervals:
And again we look into RegistryExplorer to verify the operation:
As expected, the timestamp is as we selected the value. It is worth noting here that we make changes at the key level. In our example, the Run key contains three values, so we won't specify which signature it applies to - it's just a matter of knowing what should be in the system. In addition, it should be noted that the tool will only modify the specific key that we provide as a parameter. This may seem obvious, but it is not entirely consistent with how the operating system behaves. For keys that contain subkeys, the last modified value will coincide with the last modified time of the subkey. As we can see in the example:
In this respect, the tool is therefore too precise, and the attacker will also have to modify the value of the parent key to cover his tracks. What's more, he will have to watch out for all the timestamps within the key so as not to lead to a situation where one of the keys will still contain a date later than the modification time of the master key.
So what are our detection capabilities? We can approach the matter from three sides:
- Registry value modification detection.
- Detecting the effects of registry modifications.
- Detection of the operation of the tool itself.
As for the first option, the log is responsible for monitoring changes in the registry 4657 in the Security log – the registry value has been modified. Unfortunately, in our case, it will not be helpful. It includes value changes, and the time of the last write to the register is not a register value, so the record will not be created.
Therefore, in terms of registry-based detections, we are left with observation of anomalies in the compliance of key and subkey values. This involves the need to modify the entire set of keys to maintain the timestamp compatibility:
Approaching the topic a bit around, we can try to match the registry values with artifacts related to the effects of modifications. So if we encounter an artifact indicating that the application was added to the autostart, the analysis of when the program actually started running with the system startup will help to determine whether the value is true. So we can search for it logs 4688 – the process has been created to verify the launches of the application stored in the key value.
After all, perhaps the most effective solution is to monitor processes and API calls, in the attached image, in the process monitor we can clearly see the function called by SetRegTime to modify the time:
We also see how immediately after modifying the data thanks to NtFlushKey, the program forces the changes to be written to disk.
In order to apply this method effectively, monitoring must be carried out in real time. When it comes to analyzing the memory image, a memory dump would have to be made at the time of modifying the register to intercept the function call. Process monitoring tools will also detect tool launches with the following parameter:
However, the function might as well be implemented within another executable file and not leave such an obvious trace. On the other hand, if malware samples were obtained, exploitation was detected NtSetInformationKey during the analysis, it can put us on the right track in terms of searching for irregularities in the registry.
In conclusion, registry timestomping is not easy to detect. The most reliable method is to monitor processes, which will allow you to create detection based on calls of functions responsible for changing the entry, and possibly also using the NtFlushKey function to quickly introduce changes to the system. Let us remember, however, that timestomping in this form has limited usefulness. If we change the time of the last key modification, the values already stored in it - such as the user's last login time - will not be changed. Ultimately, therefore, the most important thing will be to collate the evidence from various sources and determine where the attackers could have modified the artifacts and what their intentions were.