File tunnelling: weird creation timestamps

File tunnelling is a little known Windows capability that stems back from MSDOS days. In MSDOS, a ‘safe save’ was done by saving a copy of the modified data to a temp file, deleting the original and then renaming the temp file to the original name whilst also retaining the original files metadata. Windows NT also does this on FAT and NTFS to ensure that 16-bit applications can do a safe save, and this is called file tunnelling. This effects all Windows OSes including XP and Windows7.

Unfortunately this ‘feature’ means that creations times for files are often not quite correct. Take figure 1. This is what you would expect to happen when you have a file A, and replace it with file B. File A has been deleted and file B renamed to file A. The new file A has the creation timestamp of File B, as it was this file in the first place.

Expected results when replacing a deleted file.

However, if the delete/replace happens in less than 15 seconds, then File A will retain its original creation date! This can be shown in Figure 2, where file B has again replaced file A, but instead of having file B’s creation timestamp, it now has file A’s creation timestamp.

Actual results when replacing a deleted file within 15 seconds of deletion.

According to the Windows support page, the following 4 actions can cause this effect:

  • delete(name)/create(name)
  • delete(name)/rename(source, name)
  • rename(name, newname)/create(name)
  • rename(name, newname)/rename(source, name)

The Windows support page also has useful information like how to change the default 15 seconds and to remove this feature completely – both require registry edits.

To test out file tunnelling I wrote a simple python script that will either rename FileA as a temp file, or delete FileA. In either case, FileB is then renamed to FileA. In all cases under 15 seconds, FileA’s creation time was kept, but over 15 seconds, FileB’s creation time was kept. As you can see from the command line output, with a 14.9 second delay the overwritten file got the original file’s creation date, but at 15 seconds, it got the new file’s creation date.

Command line output of Python script

Realistically, programs which automatically overwrite or replace files in this way will not take more than 15 seconds to do so and even slow humans take less time than this to rename a file. Therefore, it is likely that the original creation date will be maintained even if the file is overwritten regularly, and careful consideration of this must be taken when evaluating creation date timestamps for forensic investigations.

import time
import os

file1 = "file1"
file2 = "file2"
file_tmp = "file0"
wait_period = 20 # seconds between creating 1st and 2nd files

def run_test(rename_delay, rename=True):
    """ Parameters:
    rename_delay - the amount of seconds delay between deleting/renaming 
    1st file and renaming 2nd file as the 1st file. 
    rename - True if you want to rename 1st file as a temp file, or False if 
    you want to delete the first file."""
    # remove old files
    if os.path.exists(file1):
    if os.path.exists(file_tmp):
    print "\nRunning test\n============"

    # create the original file
    with open(file1, 'w') as file_1:
        file_1.write('First file')
    print "File '{}' created at {}".format(file1, os.path.getctime(file1))
    # wait
    print "Waiting {} seconds".format(wait_period)

    # create second file
    with open(file2, 'w') as file_2:
        file_2.write('Second file')
    print "File '{}' created at {}".format(file2, os.path.getctime(file2))
    if rename:
        # rename first file to tmp file
        os.rename(file1, file_tmp)
        print "File '{}' renamed to '{}'".format(file1, file_tmp)
        # or delete the 1st file
        print "File '{}' deleted".format(file1)
    # wait
    print "Waiting {} seconds".format(rename_delay)
    # rename second file as first file 
    os.rename(file2, file1)
    print "File '{}' renamed to '{}'".format(file2, file1)

    if rename:
        print "File '{}' created at {}".format(file_tmp, os.path.getctime(file_tmp))
    print "File '{}' created at {}".format(file1, os.path.getctime(file1))
run_test(0, True)
run_test(14, True)
run_test(14.9, False)
run_test(15, False)

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s