Being able to track the activity of malicious software on a particular host is critically important to understanding the potential impact and consequences that will arise from its execution. As such, designers of malware will attempt to utilize a variety of anti-forensics mechanisms in order to evade detection or obfuscate the actions taken in order to make it more difficult for security investigators to assemble action time-lines. This can be achieved through a variety of methods but today I am discussing simple time-line alteration techniques that may often be seen as side modules existing within larger packages of malware.
In particular, altering the modification, access and creation (MAC) times of files can greatly hinder investigative attempts to understand when and how different actions on a system were taken. This is more easily done through direct struct manipulation in C but I am utilizing Python 3+ in order to modify MAC times. Python can easily handle changing Access and Modification times but modifying the creation time requires a more in-depth examination of C-Structs and as such I will be using the imports ‘win32file’ and ‘pywintypes’ and ‘win32api’ to achieve easier handling and manipulation of Windows APIs and file-structure data.
The first step I take in achieving a realistic time-line is to generate a random date-time sequence which will be used when later modifying file MAC times. In order to do this, I first pull the ‘start date’ from the local device’s System Event Log by opening up the event log and getting the date from the earliest record present, as shown below.
The above code opens up a handle using the pre-defined variables and then uses a basic loop to get the ‘TimeGenerated’ data from the earliest record in the log. If the log isn’t regularly wiped, this will typically be from when the OS was installed, giving us some boundaries which can be utilized for date-time generation if we wish to remain ‘in-bounds’ in regards to accurate time-setting, although this isn’t completely necessary. The next step taken is to create function which, when utilized, will generate a random date-time within the boundary given above as well as the system’s current date-time. This function is shown below.
The above code can be written in a variety of ways and is very simplistic, ignoring many fringe cases and achieving a very naive mechanism to generate random date-times. These are utilized in the next stage of the process to alter MAC times for a given file. The overall script is able to take a directory as input and, when given, will iterate through the entire directory and any sub-directories and will pass any detected file through the ‘randomizeFileTime’ function given below.
The above function uses ‘os.utime’, a Python native function under the ‘os’ import to modify both Modification and Access time of files but it cannot natively alter the Creation time. To do that, I prepare a time in the necessary C-struct format under the variable ‘ct’ and then use the ‘CreateFile’, ‘Time’ and ‘SetFileTime’ functions included within ‘win32file’ and ‘pywintypes’ to modify the Creation time. This results in files having a completely randomized MAC time similar to utilizing the ‘Timestomper’ software released many years ago.
Unfortunately, this type of work can be easily reversed by a skilled investigator through System Event log examination and a basic script which ‘un-does’ the actions performed within this obfuscation attack. One way to make this more difficult is to simultaneously modify the System Time in order to effectively ‘scramble’ the System Event log, making reconstruction much more tedious and time-consuming. This is done in a simple ‘while’ loop for demonstration purposes but could just as easily be performed via threading to achieve concurrent execution. The above random-date-time generator is utilized to create variables which are input to the basic line of code shown below.
This will change the system time using the previously mentioned imports in a very simple ‘one-liner’. This is achievable through pure python means but is much more tedious to perform. One other action that may be taken to increase the difficulty of ‘un-scrambling’ the event log would be to alter the current time-zone previous to modification of each file-time. This may also be done through Win32API interaction and the method used is shown below.
The ‘tz’ variable includes a long-list of all potential Time Zones present in the Windows 10 OS while ‘tzpath’ gives the expected path in the Registry for time-zone value manipulation, shown in the below image.
The code snippet above demonstrates how, for each file, previous to having the file-time randomized a random time-zone is selected from ‘tz’ and the registry value for current Time-Zone is modified, further obfuscating system event logs and increasing the tediousness of investigations. Further-more, after script completion, an attempt to wipe all existing event logs is made via the code snippet given below.
This code attempts to iterate through all existing logs and uses native Windows functions to attempt clearing logs. If allowed, this can make it very difficult for forensic investigators to determine specific time-lines if no external reporting or auditing systems are in place. There is one final technique utilized in this script to attempt time-line obfuscation, but which does not quite work as expected, although I will include mention of it here. I noticed in my testing that there exists a ‘System Uptime’ event in the Event Logs which seems to ‘tick’ every second since the system has last started. It seems through research that this event is dependent upon the ‘LastBootUpTime’ property of the Window’s CIM_OperatingSystem information class and altering this cannot be done very easily. I have attempted to write a new ‘Managed Object Format’ class which will over-write the existing class and attempt to define a new value for ‘LastBootUpTime’ property. The initial function for this is shown below.
The above function, when called, will attempt to write a ‘.mof’ file containing the above code with a randomized date-time inserted into the code. This alone is not enough, as this function would simply leave the file on the system but that would do nothing on its own.
The code snippet attempts to call the writing-MOF function as well as utilize ‘subprocess.call’ in an attempt to force an update to the existing class via the command-line. Additionally PowerShell is utilized throughout in order to learn what the original ‘LastBootUpTime’ is as well as to verify that it is modified after MOF compilation.
Overall, the above code, when combined, attempts to obfuscate malicious software actions and would be part of a larger package. This ‘larger package’ may attempt some form of data exfiltration or persistence achievements and this type of obfuscation will try to hide the greater intent of the package and make it very difficult for security investigators to understand what happened or construct accurate time-lines.
Some screenshots of this script in action are shown below.