Every MFT record stores four timestamps in two separate attributes. That is eight numbers per record. They are not always in sync. The relationship between them, and where they break down, is the foundation of NTFS time analysis. If you only learn one detail of MFT forensics, learn this one.
The four moments NTFS records
Both $STANDARD_INFORMATION (SI, attribute type 0x10) and $FILE_NAME (FN, attribute type 0x30) carry timestamps for the same four events:
- Created: when the file was first written to the volume.
- Modified: when the file's contents last changed.
- Accessed: when the file was last read.
- MFT-modified: when the record itself was last updated (any attribute change, not just data).
The timestamps are stored as 64-bit values in Windows FILETIME format (100-nanosecond ticks since 1601-01-01 UTC). 100-nanosecond granularity. Plenty of bits for natural events to leave noise in the bottom digits.
Why two sets exist
$STANDARD_INFORMATION is the timestamp set userland sees. The Win32 API SetFileTime writes here. Every routine file operation that touches a timestamp updates SI: write, read (depending on the access-time setting), rename, attribute change.
$FILE_NAME was added for POSIX subsystem compatibility in early NT and persists for historical reasons. It is updated only when the name changes: creation (when the name is first set), rename (when the name changes), or move between directories (which renames in the NTFS sense). After that, FN sits unchanged for as long as the file keeps that name.
In practice this means SI timestamps tick constantly while FN timestamps remain stable. The asymmetry is what makes timestomping detectable.
What timestomping does
Tools that alter timestamps usually call SetFileTime. That writes to SI. It does not touch FN. After timestomping:
- SI shows whatever the attacker chose. Often backdated by years (to make a recently dropped tool look like a system file) or pushed forward (to obscure the actual activity time).
- FN still reflects the real creation time, possibly by a wide margin.
This is what produces the canonical timestomping signature: a file with SI created in 2018 and FN created six minutes ago.
Two patterns to watch for during triage:
- SI created older than FN created. This is impossible naturally. Files cannot exist before they are named. Any record where SI created predates FN created has been touched.
- SI modified far from FN modified on a file that has clearly not been renamed. FN modified moves only on renames; if SI says 2017 and FN says yesterday with no rename in between, something is wrong.
The double rename trick
Operators who know SI/FN divergence is detectable use a workaround: rename the file (which forces NTFS to update FN), then call SetFileTime on both SI and FN, then rename back. Now both attributes show the backdated values.
This defeats SI/FN comparison. It does not defeat:
- The USN journal. Every rename writes a
RENAME_OLD_NAME/RENAME_NEW_NAMEpair. The two renames needed for the trick are visible in the journal. Their timestamps in the journal are the actual times, not the spoofed FN values. $LogFile. Transaction records around the rename sit in the log.- VSS snapshots. Older snapshots have the pre-stomp FN values. Diff the current MFT against the snapshot's MFT for the same record.
The double rename is harder to do quietly. It is still common in mature red team toolkits.
Sub-second granularity, the lazy-tool tell
NTFS stores timestamps in 100-nanosecond ticks. Native Windows operations leave noise in the bottom digits. The OS does not zero out the sub-second component when it writes a timestamp; whatever the kernel clock returned is what gets recorded.
Most timestomping tools round to the nearest second before writing. The result is a timestamp ending in .0000000 UTC. One such timestamp is unremarkable (occasional natural events do round). A column of .0000000 suffixes lined up across many files is a fingerprint.
This is easy to check. Take the created, modified, accessed, and MFT-modified columns from your MFT parse. Filter for any record where all four SI timestamps end in .0000000. Compare against a baseline of natural Windows activity. The contrast is immediate.
What Windows itself does to timestamps
To use the SI/FN comparison you need to know what Windows does on its own to the four fields. The cheat sheet:
- SI created: written on creation. Updated by some installers when they "create" a file by extracting it.
- SI modified: written on every data write. Updated by
SetFileTime. Not updated by metadata-only changes. - SI accessed: by default disabled on Windows 7+ (set
fsutil behavior set disablelastaccess 0to enable). If disabled, this field still gets updated occasionally by certain operations (backup software, EDR scans), but it is unreliable as a "last read" signal in either direction. - SI MFT-modified: written on any attribute change, including renames, ACL changes, ADS creation, and data writes.
- FN created: written when the name is first set (creation, hard link creation, rename).
- FN modified, FN accessed, FN MFT-modified: written when the name is set, then largely stable.
On a clean install, FN's four timestamps typically equal each other (they were all set at the same instant when the name was assigned). When you see FN with all four timestamps identical and the SI four diverging, that is normal.
Windows Update and patched binaries
Windows Update touches the SI timestamps of patched binaries. After a cumulative update, half of \Windows\System32\ has SI modified within minutes of each other and FN that has been stable since the last service pack. This is normal. Treat it as a baseline pattern, not as anomalous activity.
Cross-reference with CBS.log and setupapi.dev.log for the patching window. If SI says svchost.exe was modified at 03:14 and the CBS log shows a component install at 03:14, that is Windows Update, not an attacker.
How I screen for timestomping
The screen I run on a fresh MFT extract:
- Pull every record where SI created < FN created. Manually review each.
- Pull every record where SI modified is more than 30 days before FN modified and the file is in a user-writable directory. Manually review.
- Pull every record where all four SI timestamps end in
.0000000and the file is not a Windows system binary. Manually review. - Diff the current MFT against the most recent VSS snapshot. Highlight records whose SI timestamps moved backward. Manually review.
That sequence catches the majority of timestomping in the wild. Sophisticated operators using the double-rename trick or VSS deletion need the journal and event log layers to detect, but the four checks above will surface them anyway through other artifacts (the rename in the USN journal, the VSS delete in the event log).
Further reading
- David Cowen, Forensic Lunch coverage of timestomping. Years of practitioner case studies.
- SANS, Windows Time Rules cheatsheet. Quick reference for what each Windows operation does to each timestamp.
- The linux-ntfs project's
$STANDARD_INFORMATIONand$FILE_NAMEnotes. Field-level layout reference.