Timestomping Programmatically

Timestomping is a favourite topic of red teamers and forensic analysts. They often speak about the tools and powershell commands that can be used to do timestomping. How do these tools work? In the course of developing nTimetools, I read up on the various APIs and the extent of modification/access these APIs allow. A brief overview before I dive into the specifics.

API function Type Timestamp Access
SetFileTime Win32 API Creation, Last Access, Last Write Time
SetFileInformationByHandle Win32 API Creation, Last Access, Last Write, Change Time (1)
NtSetInformationFile undocumented NT API Creation, Last Access, Last Write, Change Time
CreateFile(.\PhysicalDrive0) Win32 API-ish All above $STD_INFO and others (e.g. $FILE_NAME) (2)

  1. Metadata change time can be progammatically set, however it will be overwritten to current time as this operation is considered changing file metadata.
  2. As of Windows Vista and Server 2008, Microsoft has blocked direct disk write to mounted volumes. Hence, this will not work on the SYSTEM drive.

SetFileTime API

This is the highest level API. It is rather uninteresting, as it does not allow us to modify the metadata change time. It will only be able to fool someone who uses right click -> Properties to view the file timestamp information. Any further probing will reveal that the timestomping has been performed.


SetFileInformationByHandle allows us to update the _FILE_BASIC_INFORMATION structure. Internally, I believe what happens is that this function calls the NtSetInformationFile function, after it has returned, it will update the ChangeTime timestamp to the current time. This behaviour is not good since we are trying to do timestomping, hence we have to go deeper.

    typedef struct _FILE_BASIC_INFORMATION {
      LARGE_INTEGER CreationTime;
      LARGE_INTEGER LastAccessTime;
      LARGE_INTEGER LastWriteTime;
      LARGE_INTEGER ChangeTime;
      ULONG         FileAttributes;


NtSetInformationFile is an undocumented NT API. We cannot just import the library and call the function. In order to access the function, we will need to get the handle to ntdll.dll during runtime and get the process address for NtSetInformationFile. Once done, we can update the _FILE_BASIC_INFORMATION structure. nTimetools uses this API. Based on my testing, we can modify the ChangeTime timestamp to any timestamp of our liking.



This is the lowest level possible. We are opening a handle to the raw device. With this level of access, we can read or write individual bytes on the hard disk itself. The challenge with this method is the lack of any data structures. You will need to define your own MFT entry structure, MFT structure and start parsing the blob of data you have just read. While the $MFT is rather well researched, others such as $I30, $LogFile are largely unknown. That said, with this level of access, the sky is the limit. You could selectively overwrite event log entries or even system drivers. However, it is also extremely dangerous, improper writes may leave your filesystem in an inconsistent state or corrupt it entirely.

As of Windows Vista and Server 2008, Microsoft has blocked direct disk write to mounted volumes. It is still possible to do direct disk read on mounted volumes. The Invoke-Ninjacopy library does just that.