System administrators use osquery for endpoint telemetry and daily monitoring. Security threat hunters use it to find indicators of compromise on their systems. Now another audience is discovering osquery: forensic analysts. While osquery core is great for querying various system-level data remotely, forensics extensions will give it the ability to inspect to deeper-level data structures and metadata not even available to a user at a local system. We continued our collaboration with Crypsis, a security consulting company, to show some immediate scenarios where osquery comes in handy for forensic analysts.
Previously, we announced and briefly introduced the features of the new NTFS forensics extension that we added to our osquery-extensions repository. Today, we’ll demonstrate some familiar real-world use-cases for forensic analysts interested in leveraging osquery in their incident response efforts.
Identifying “Timestomping” Attacks
Every interaction with a filesystem leaves a trace. Attackers who want to remain undetected for as long as possible need to clean up these traces. File timestamps, if left unmodified, provide a great deal of information about the attacker’s timeline and behavior. They’re a common focus for both the attacker and the forensic analyst. “Timestomping” is the common name for the anti-forensics tactic of destroying filesystem timestamp evidence of the attacker’s file modifications.
When it comes to covering up evidence in timestamps, NTFS is a little more complicated than other filesystems. To explain, we’ll have to explore some of NTFS’s structure.
The core element of NTFS is the Master File Table (MFT), which stores an entry for every single file on the system. Every entry in the MFT contains a number of attributes that store metadata describing the file. One attribute – $STANDARD_INFORMATION ($SI) – stores a collection of timestamps. Standard files also have a $FILE_NAME ($FN) attribute that contains its own set of timestamps. The timestamps in the $SI attribute roughly correlate to interactions with the contents of the file. The timestamps in the $FN attribute roughly correlate to interactions with the location and name of the file. Finally, directory entries in the MFT have an index attribute that stores a copy of the $FN attribute (including timestamps) for all files in that directory.
Example 1: Timestamp Inconsistency
The simplest example of a timestamp attack is to change the file-creation date to a time prior to incursion. Done poorly, the $FN creation timestamp and $SI creation timestamp won’t match. The discrepancy stands out. To use osquery to find files in a directory whose timestamps don’t match, for example, I’d run the following:
SELECT path,fn_btime,btime from ntfs_file_data where device=”\\.\PhysicalDrive0” and partition=3 and directory=”/Users/mmyers/Desktop/test_dir” and fn_btime != btime;
We can also look for other forms of timestamp inconsistency. Perhaps the file-creation times are left alone, and thus match, but the last modified time was set to some earlier time to avoid detection. Would you trust a file whose MFT entry’s modified time predates its creation time? Me neither:
SELECT filename, path from ntfs_file_data where device=”\\.\PhysicalDrive0” and partition=2 and path=”/Users/Garret/Downloads” and fn_btime > ctime OR btime > ctime;
Example 2: Timestamp Missing Full Precision
Attackers can be lazy sometimes and timestomp a file with a built-in system utility. These utilities have a lower precision for time values than the operating system would naturally use. An analyst can spot this kind of forgery by checking the nanosecond portion of the timestamp — it’s unlikely to be all zeros, unless it has been tampered with.
We saw above that NTFS timestamps are 64-bit values. For example, consider the NTFS timestamp 131683876627452045. If you have a Windows command prompt handy, that’s Monday, April 16, 2018 9:27:43 PM — to be specific, it’s 9:27:42 PM and 0.7452045 minutes, but it was rounded up. Pretty specific! This is what a natural file timestamp looks like.
However, a file timestamp that has been set by a system utility will only have seconds-level precision, and that’s as much detail as most user-interfaces show. 131683876620000000 is also Monday, April 16, 2018 9:27:42 PM, but it sticks out like a sore thumb in integer representation. This timestamp was forged.
At first use, it might seem odd for osquery to output the NTFS timestamps in integer representation, but it serves to make this type of forgery easy to spot for an experienced forensic analyst.
Locating Evidence of Deleted Files
A user clicks a bad link or opens a bad email attachment. The malware goes to work. It downloads a couple of payloads, deploys them, collects some data on the system into a file, sends that data upstream, then deletes itself and all downloaded files from the filesystem. All neat and tidy, right?
Well, maybe not. The contents of those files might not be available any longer, but NTFS is lazy about cleaning up metadata for files, especially in the context of directory indices. A complete explanation of NTFS and directory index management is beyond the scope of this post, but we can provide a high-level overview (readers who are inclined to learn more might wish to read NTFS.com or the documentation by Russon and Fledel of the Linux-NTFS project).
Like any file on NTFS, every directory has an entry in the MFT. These entries have various attributes. The relevant attribute here is the index attribute, which in turn contains copies of the $FN attributes of the directory’s child files, arranged in a tree structure. As files are added and removed from the directory, the contents of the index attribute are updated. Entries in the index are not deleted, though—they’re simply marked as inactive, and may be overwritten later as new entries are added. Even though a file was deleted, a copy of its $FN attribute may still remain in its parent directory’s index for some time afterwards.
The NTFS forensic extension makes finding these entries relatively simple.
Example 3: A Directory’s Unused Filename Entries
Let’s delete all of the files from the last example, and empty the Recycle Bin. Then, let’s look at the unused entries in that folder’s directory index by running the following query:
SELECT parent_path,filename,slack from ntfs_indx_data WHERE parent_path=”/Users/mmyers/Desktop/test_dir” and slack!=0;
There’s more information available than just filenames. Since the entire $FN attribute is stored, there are time stamps available as well. We can reconstruct a partial timeline of file activity in a directory just from the index entries. Some extra work is required, though: since directory indices are filename-based, renaming a file will in effect cause the old entry to be marked as inactive, and create a new entry in the index. Differentiating a renamed file from a deleted one will require additional analysis.
Also note that there were three files deleted, but only two files left artifacts in slack. When looking at unused data structures, we are often only seeing a partial record of what used to be there.
This extension offers a fast and convenient way to perform filesystem forensics on Windows endpoints as a part of an incident response. Go get it – and our other osquery extensions – from our repository. We’re committed to maintaining and extending our collection of extensions. Take a look, and see what else we have available. Visit the osquery community on Slack if you need help.
Helping incident responders with remote forensics is an area of increasing capability for osquery. Besides our NTFS forensics extension, osquery already supports file carving, system activity queries, and audit-based monitoring. There is undoubtedly still more that could be added to osquery: remote memory carving, USB device history retrieval, or filesystem forensic metadata for other filesystems.
Join us on June 20th-21st for QueryCon!
Trail of Bits is hosting the QueryCon osquery conference in New York City, June 20th and 21st, 2019. As we have demonstrated in this article with the NTFS forensics extension, there are many potential use-cases for osquery extensions, and some of the talks at QueryCon 2019 will explore some of those specifically. Victor Vrantchan will give a lesson on how to use extensions and logger plugins to integrate osquery with your existing logging infrastructure; Atul Kabra will speak about enriching osquery with ‘event-driven’ extensions.
As of the time of this writing, tickets for QueryCon are still available! Purchase yours today, and meet with the others from the osquery user and developer community. Bring your ideas for extensions, and participate in the workshop. We look forward to seeing you there!