I am currently working on a PowerShell module that will provide a remote forensic capability for forensicators and incident responders alike. I know many tools that parse file based forensic artifacts (Ex: Prefetch), but none of these tools parse remote artifacts. Remote parsing provides defenders with many advantages, including a capability called Least Frequency of Occurrence (LFO). If a defender can aggregate data from every prefetch file on every host in a large network, they can use LFO to spot anomalies, which may in turn point out malicious activity.
While creating a cmdlet, to parse Windows Prefetch files, I realized that there were many inconsistencies between the format of prefetch files on Windows XP and Windows 7. I also realized that little research had been done regarding the structure of Windows 8 prefetch files, and assumed there would be small inconsistencies with this version as well. I am writing a blog series to describe the methodology I used to learn Windows 8 prefetch file format, and to document some of the interesting finds along the way.
What is Prefetch?
Simply put, application prefetching is used to store information about frequently used applications to help Windows load them more quickly in the future. This information is stored in "prefetch" files found in the %systemroot%\Prefetch\ directory. At any given time the system can keep up to 128 (Windows XP/2003/Vista/7/2008) or 1024 (Windows 8/8.1/2012) individual prefetch files (Each one correlates to a single application). These files contain information about the application like how many times it was run, when was it last run, what path it was run from, what external files it loaded in its first 10 seconds of execution, etc.
Understanding the Prefetch File Format (Windows 8)
This series of examples is using a cmd.exe prefetch file from Windows 8
File Signature (Offset: 0x00 8-bytes)
The first value found in the data structure is the File Signature at Offset 0x00. The signature is a 8-byte value containing (0x1A,0x00,0x00,0x00,0x53,0x43,0x43,0x41), the first of which represents the OS (0x11 = XP, 0x17 = 7, 0x1A = 8). The ASCII representation of the final 4 bytes is SCCA, which is commonly recognized as the Prefetch File Signature.
Application Name (Offset: 0x10 60-bytes)
Next, at Offset 0x10, we see a Unicode Formatted String that says "CMD.EXE". This value represents the name of the application for which this prefetch record has been created. This name can/should be compared to the name of the prefetch file itself to ensure the file name has not been tampered with. One important detail is that this value is represented in 60 bytes, to allow for variable lengths of application names. The standard is for the application name to be terminated by Unicode NULL (0x0000).
File Path Hash (Offset: 0x4C 4-bytes)
Have you ever wondered about those 8 random hex values in name of prefetch files? Interestingly enough the value is a hash of the application's file path. Remember earlier I said that one prefetch file is created for each application run? Well...that is not entirely truthful. A more precise explanation is that one prefetch file is created per application from a specific file path. When cmd.exe is run from C:\Windows\system32 one prefetch record is created. However, if I copy cmd.exe to C:\Windows and execute it, a second prefetch file will be created.
From a detection/investigation perspective this hash can be useful in finding malware hiding in plain sight. Often times attackers will name their malware as common Windows applications, putting their version in a different directory than the real thing (Ex: Placing svchost in C:\Windows instead of C:\Windows\system32). If they are careless and execute the malware without cleaning up their tracks, there will be a conspicuous second prefetch record for svchost that will provide investigators with some attack details.
Similarly to the application name, the file path hash is stored inside the prefetch file. This can again be used to check for simple manipulation of the prefetch file name.
NOTE: The majority of non-unicode values are stored in Little Endian, so when parsing/reading the values make sure you flip the bytes.
Application Run Count (Offset: 0x0D 4-bytes)
One of the more useful pieces of information found in the prefetch file is the run count, found at Offset 0xD0). The run count tells a forensicator how many times the application has been executed. Remember this value is stored in Little Endian, so this example shows the run count to be one.
Last Access Timestamp (Offset: 0x80 8-bytes)
The last really useful piece of information found in the main section of the prefetch file is the last accessed timestamp. This value is of extreme importance during an investigation because it tells the investigator when the program was last executed. This value is stored as a "FILETIME" object, which is describe by Microsoft as being "the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC)". There are plenty of way to turn the hex value into an actual time (Ex: the hex editor I'm using automatically converts hex timestamps to the actual time, or you can use PowerShell to convert the value with .NET).
Christmas coming early...Thanks Microsoft!
Some of you may be familiar with the file structure of a prefetch file in previous versions of Windows. If you are you are probably asking why the run count (Offset 0xD0 isn't directly following the timestamp (Offset 0x80) like it always has. Well my friends, this is because Microsoft has decided to throw us a bone for whatever reason. Prefetch files in Windows 8 contain not one timestamp, not two timestamps, but 8 Last File Accessed Timestamps! Below I show a quick demonstration of how the Windows 8 prefetch files store the 8 timestamps.
Above is a screen shot of the same CMD.EXE prefetch file, except I ran the application an extra time to increase the run count (0xD0) to two times. The important thing to notice is that the original timestamp has been shifted over to Offset 0x88, and the most recent timestamp has moved in to the 0x80 position. Well this is interesting, but what about the other 64 bytes between the 2nd timestamp and the run count value?
After some trial and error testing I was able to determine that the Windows 8 prefetch files will store the 8 most recent last accessed timestamps. Notice in the screenshot that the original time is still there, but it has been moved all the way down to the basement (Offset: 0xB8). It is interesting to note that there is still 16 bytes of 0's. What ever comes of that space?
What happens after 8?!?
Well that is a good question. I have noticed that those 0's are changed after the timestamp slots a filled, but I have yet to determine what the value represents (If anyone knows or figures it out please let me know). I am assuming it has something to do with the timestamps because the values seem to only appear after the 8 timestamp values have been created.
Well this concludes the first portion of my foray into the Windows 8 Prefetch File Structure. My next post will discuss the different sections contained within prefetch files, and what information can be found in each section.