In this section

$STANDARD_INFORMATION and $FILE_NAME Attributes

14 hours · Module 1 · Free
What you already know
Section 1.1 showed $STANDARD_INFORMATION as type 0x10 and $FILE_NAME as type 0x30 in the attribute chain. This section goes inside both attributes: the timestamps at their byte offsets, the fields that make each attribute forensically significant, and the comparison between them that detects timestamp manipulation.

Scenario

You find 47 executable files in a temporary directory. All have identical $SI Created timestamps: 2025-08-15T09:00:00.0000000. The $SI Entry Modified timestamps range across March 18, 2026. The fractional seconds on Created are all zeros. Naturally created files have non-zero fractional seconds. Identical timestamps to the nanosecond across dozens of files means a script set them to the same value. The real creation time is in the $FN timestamps and USN Journal.

The FILETIME format

Every timestamp in the MFT uses Windows FILETIME: a 64-bit unsigned integer representing the number of 100-nanosecond intervals since January 1, 1601 00:00:00 UTC. This epoch predates the Unix epoch (January 1, 1970) by 369 years, and the 100-nanosecond resolution provides precision that is forensically significant for both event sequencing and timestomping detection.

To convert a FILETIME to a readable date: read the 8-byte little-endian integer, subtract the epoch offset (116444736000000000 — the number of 100-nanosecond intervals between 1601 and 1970), divide by 10,000,000 to get Unix seconds, then convert to your preferred date format. MFTECmd performs this automatically and outputs ISO 8601 with seven decimal places — the full 100-nanosecond resolution. In Python: struct.unpack(' gives the integer, and datetime(1601,1,1) + timedelta(microseconds=value//10) gives the datetime.

This precision matters for timestomping detection. When an attacker uses SetFileTime() or a timestomping tool to modify $SI timestamps, the tool typically sets timestamps with lower precision than NTFS natively provides. A file created naturally has a timestamp like 2026-03-15T14:23:07.1234567. A file timestomped via PowerShell's Set-ItemProperty typically produces 2026-03-15T14:23:07.0000000 — the fractional seconds are all zeros because the API call specified the timestamp to second precision. This is not definitive proof (some legitimate operations produce zero-fractional timestamps), but it is an indicator that warrants further investigation when other files in the same directory have full nanosecond precision.

A FILETIME value of 0 (all eight bytes 0x00) indicates the timestamp was never set. This is different from the epoch time (January 1, 1601). MFTECmd displays zero FILETIMEs as blank or a placeholder. In raw hex, eight consecutive zero bytes in a timestamp field mean the timestamp is undefined.

The four $SI timestamps

The timestamps are stored in Created, Modified, Entry Modified, Accessed order (CMEA) at offsets 0x00, 0x08, 0x10, 0x18 relative to the attribute content start.

$SI Attribute Content — Hex Dump
── $SI content starts at attribute_start + content_offset (typically 0x50 in the record) ──
Offset   Hex                               Decoded
+0x00    80 1A C3 5F 82 A9 D8 01   Created:      2026-03-18 02:13:02.3456789  ◄ 8-byte FILETIME
+0x08    00 3C D1 5F 82 A9 D8 01   Modified:     2026-03-18 02:13:04.1234567
+0x10    40 5E DF 5F 82 A9 D8 01   Entry Mod:    2026-03-18 02:13:06.7890123
+0x18    80 1A C3 5F 82 A9 D8 01   Accessed:     2026-03-18 02:13:02.3456789  ◄ Same as Created (lazy update)
+0x20    20 00 00 00                        Flags:        0x20 = Archive                ◄ Permission flags
+0x24-43 ...                               MaxVer, VerNum, ClassID, OwnerID, SecurityID, Quota
+0x44    A7 C3 0B 00 00 00 00 00   USN:          0x0BC3A7                     ◄ Links to USN Journal entry

Created (offset +0x00) records when the file was originally created on this volume. On a file that has never been copied or moved, this reflects the moment Windows allocated the MFT entry. On a copied file, it reflects the copy time, not the original creation time. On a same-volume move, Created is unchanged because the MFT entry is the same (only the parent directory reference changes). On a cross-volume move, the behavior is copy-then-delete, so Created reflects the move time.

Modified (+0x08) records the last time the file's $DATA attribute content was written. Opening a file, reading it, and closing it without changes does not update Modified. Renaming a file does not update it (the filename is in $FN, not $DATA). Changing permissions does not update it. Only actual data writes trigger a Modified update. This specificity makes Modified valuable for identifying when file content last changed, but it requires corroboration to determine what application performed the write.

Entry Modified (+0x10) records the last time any attribute in the MFT record was changed. This is broader than Modified: it captures data changes (which also update Modified) and metadata changes — renaming (changes $FN), changing permissions (changes $SI itself), moving to a different directory (changes the parent reference in $FN), and changing security descriptors. Entry Modified is the most frequently updated timestamp because any MFT record modification triggers it.

Accessed (+0x18) records the last time the file was read. On Windows XP and earlier, this updated on every access. Starting with Vista, NtfsDisableLastAccessUpdate reduces disk writes by only updating Accessed when it is more than one hour older than the current time. This setting is enabled by default on Windows 10/11, giving Accessed hour-level granularity at best. Treat Accessed as approximately accurate on modern evidence, not precise.

The forensic implications of the lazy access update: if a file was accessed at 14:30 and the Accessed timestamp shows 13:45, the file was genuinely accessed between 13:45 and the current time. If the Accessed timestamp shows a date from weeks ago, the file has not been accessed since that date (within the one-hour window). You can determine the NtfsDisableLastAccessUpdate setting from the registry hive (HKLM\SYSTEM\CurrentControlSet\Control\FileSystem) to know which behavior was in effect on the evidence system. A value of 1 means updates are disabled (hour granularity). A value of 0 means updates are enabled (full precision). The default changed to 1 starting with Windows 10 1803.

Anti-Pattern

Citing the Modified timestamp as proof a specific user edited the file

The $SI Modified timestamp proves the $DATA attribute was written at that time. Antivirus quarantine-and-restore, backup software, file synchronization (OneDrive, Dropbox), and Windows updates all write to $DATA and update Modified. Proving user-initiated modification requires correlating Modified with user session data (logon events), process execution (Prefetch), and application artifacts (Office recent documents, Jump Lists).

Permission flags and file attributes

At content offset +0x20, four bytes encode the file's DOS-compatible attribute flags. These are the same flags visible in the attrib command and the file properties dialog. The forensically relevant flags:

Hidden (0x0002): The file is hidden from default directory listings. Malware frequently sets this flag to avoid visual detection. A hidden file in a non-standard location warrants investigation.

System (0x0004): The file is marked as an operating system file. Combined with Hidden, this creates "super hidden" files invisible even when "Show hidden files" is enabled in Explorer — the user must also uncheck "Hide protected operating system files." Malware that sets both Hidden and System is deliberately hiding from the default file browser view.

Compressed (0x0800): The file is NTFS-compressed. The actual data on disk is smaller than the logical file size in the MFT. Recovering compressed files requires decompression after cluster extraction. Section 1.12 covers compression in detail.

Encrypted (0x4000): The file is encrypted with EFS (Encrypting File System). The $DATA attribute contains encrypted content that cannot be read without the user's decryption key. For forensic analysis, either the key must be recovered from the certificate store or backup, or the file must be examined on a live system where the user is logged in.

Archive (0x0020): Set by the filesystem when the file is modified. Backup software clears it after a successful backup. Forensically, an Archive flag that is set means the file has been modified since the last backup. An Archive flag that is cleared means a backup tool has processed the file. This is a low-confidence indicator but can corroborate other evidence of file activity.

Not Content Indexed (0x2000): The file is excluded from Windows Search indexing. Attackers occasionally set this flag on tools and staging directories to avoid appearing in Windows Search results. Like the Hidden/System combination, this flag is an indicator of deliberate concealment when found on files in unexpected locations.

The Update Sequence Number (USN)

At content offset +0x44 (NTFS 3.0+, all Windows 2000+ systems), an 8-byte field contains the Update Sequence Number. This is not the USN Journal entry itself — it is a reference that links the MFT record to the corresponding USN Journal entry. Every time NTFS modifies an MFT record, it writes an entry to the USN Journal ($UsnJrnl) and stores the USN offset in this field.

This creates an asymmetry that attackers rarely account for. When SetFileTime() modifies $SI timestamps, NTFS records the modification as a "data change" in the USN Journal — because the $SI attribute was modified. The USN Journal entry records the real time of the modification, the filename, and the reason code. The attacker has changed $SI to show fake values, but the USN Journal records that $SI was modified at the real time. Unless the attacker also truncates the USN Journal (a separate, more destructive anti-forensic action that itself leaves traces), the timestomping is detectable through USN correlation.

The relationship between $SI timestamps and the USN field creates a multi-artifact check. The $SI timestamp alone is modifiable. The USN field alone is a number without context. But the USN field combined with the corresponding USN Journal entry produces a complete picture: "the file's $SI timestamps were modified at [real time] and now show [fake time]." This is why the multi-artifact correlation approach matters. Single-artifact analysis is vulnerable to manipulation. Multi-artifact correlation is resilient because the attacker must manipulate multiple independent data sources consistently — and each additional source they manipulate creates additional forensic artifacts documenting the manipulation.

Reading $SI from raw hex

To locate $SI, navigate to the first attribute offset (from the record header at 0x14). Confirm the type is 10 00 00 00. The attribute header for a resident attribute contains the content size and content offset. The content offset (typically 0x18 from the attribute start) tells you where the timestamp fields begin.

For a standard record with $SI at offset 0x38, the content starts at 0x38 + 0x18 = 0x50. Created is at bytes 0x50-0x57, Modified at 0x58-0x5F, Entry Modified at 0x60-0x67, Accessed at 0x68-0x6F. Each is an 8-byte little-endian integer.

The manual verification workflow: read 8 bytes at the timestamp offset, convert little-endian to integer in Python (int.from_bytes(bytes.fromhex('HEX'), 'little')), convert to datetime (datetime(1601,1,1) + timedelta(microseconds=value//10)), compare to MFTECmd's output. If they match, the parser is correct. If they differ, you have found a discrepancy worth investigating. Apply this workflow to every file that forms a core finding in a legal or regulatory investigation. Document the raw-verified values in your methodology section.

$SI attribute size and NTFS version

The $SI attribute exists in two sizes depending on the NTFS version. NTFS 1.x (Windows NT 3.x and 4.0) has a 48-byte $SI content containing only the four timestamps (32 bytes), the permission flags (4 bytes), and reserved fields. NTFS 3.0 and later (Windows 2000 through Windows 11) has a 72-byte $SI content that adds the version fields, owner ID, security ID, quota charged, and the USN field.

On all evidence you encounter in current investigations, the $SI attribute will be the 72-byte version — NTFS 1.x systems have been out of production for over 20 years. However, if you encounter evidence from a forensic archive or legacy system, check the $SI content size before attempting to read fields beyond offset +0x20. Reading the USN field (+0x44) from a 48-byte $SI produces garbage data from whatever follows the $SI content in the MFT record. MFTECmd handles both versions automatically, but when reading raw hex, always verify the content size in the attribute header.

The content size is in the attribute header at attribute_start + 0x10 (4 bytes, little-endian). A value of 0x48 (72 decimal) confirms the extended NTFS 3.0+ format. A value of 0x30 (48 decimal) indicates the legacy format.

Investigation Principle

The $SI timestamp alone is not trustworthy. The $SI USN field alone is not self-explanatory. But the USN field combined with the corresponding USN Journal entry produces a complete picture: "the file's $SI timestamps were modified at [real time] and now show [fake time]." Multi-artifact correlation turns individual data points into defensible evidence.

Reading $SI from raw hex

To locate $SI, navigate to the first attribute offset (from the record header at 0x14). Confirm the type is 10 00 00 00. The content offset is in the attribute header at attribute_start + 0x14 (2 bytes), typically 0x18. So if $SI starts at record offset 0x38, the content begins at 0x38 + 0x18 = 0x50. Created is at 0x50-0x57, Modified at 0x58-0x5F, Entry Modified at 0x60-0x67, Accessed at 0x68-0x6F.

The manual verification workflow: read 8 bytes, convert little-endian to integer in Python (int.from_bytes(bytes.fromhex('HEX'), 'little')), convert to datetime (datetime(1601,1,1) + timedelta(microseconds=value//10)), compare to MFTECmd output. If they match, the parser is correct. If they differ, you've found either a parser issue or a conversion error worth investigating.

$STANDARD_INFORMATION Field Reference

+0x00 (8B): Created — FILETIME, modifiable via SetFileTime(). Primary timestomping target.

+0x08 (8B): Modified — FILETIME, updates on $DATA writes only.

+0x10 (8B): Entry Modified — FILETIME, updates on any MFT record attribute change.

+0x18 (8B): Accessed — FILETIME, unreliable on Vista+ (lazy update, hour granularity).

+0x20 (4B): Flags — Hidden (0x02), System (0x04), Compressed (0x0800), Encrypted (0x4000).

+0x44 (8B): USN — links to USN Journal entry documenting the most recent modification.

Scenario

A suspected ransomware executable has $SI Created of 2025-06-01 (nine months before the incident) and $FN Created of 2026-03-18 02:14:33 (during the intrusion window). This temporal inversion is physically impossible under normal NTFS operation because both timestamps are set from the same clock at the same moment during file creation. The attacker created the file in March 2026 and backdated $SI to blend with older files. The $FN timestamp reveals the real creation time.

Why $FN timestamps matter

$SI timestamps are updated by the Windows I/O manager through the file system filter stack. Any application that calls SetFileTime(), SetFileInformationByHandle(), or equivalent APIs can modify $SI timestamps. This is by design — applications legitimately set timestamps when extracting archives (to preserve the original file's timestamps), when synchronizing files (to match the source's timestamps), and when performing backup-restore operations. The same API that enables these legitimate uses is what timestomping tools exploit.

$FN timestamps are set by the NTFS driver at the kernel level. When NTFS creates a new file and allocates the MFT record, the driver copies the current system time into both $SI and $FN timestamps. From that point forward, $FN timestamps update only under specific NTFS-internal conditions: file rename (updates $FN Modified and Entry Modified), file move to a different directory (updates $FN Modified), and certain MFT record restructuring operations. Data writes to the file do not update $FN timestamps. The $FN Created timestamp is set once at file creation and almost never changes.

This creates the forensic asymmetry that makes timestomping detectable. When an attacker creates a malicious file at 02:14 on March 18, 2026, and then uses a timestomping tool to set $SI Created to August 2025, the $SI attribute shows August but the $FN attribute still shows March 18. The discrepancy between $SI Created and $FN Created — particularly when $FN Created is later than $SI Created, which cannot happen naturally — is strong evidence of timestamp manipulation.

$FILE_NAME Attribute Content — Hex Dump
── $FN content starts at attribute_start + content_offset ──
Offset   Hex                               Decoded
+0x00    05 00 00 00 00 00 03 00   Parent MFT ref: entry=5 seq=3       ◄ Root directory (C:\)
+0x08    80 1A C3 5F 82 A9 D8 01   $FN Created:  2026-03-18 02:13:02   ◄ Set by NTFS driver, not API
+0x10    80 1A C3 5F 82 A9 D8 01   $FN Modified: 2026-03-18 02:13:02
+0x18    80 1A C3 5F 82 A9 D8 01   $FN EntryMod: 2026-03-18 02:13:02
+0x20    80 1A C3 5F 82 A9 D8 01   $FN Accessed: 2026-03-18 02:13:02
+0x28-3F ...                               Alloc size, real size, flags
+0x40    08                             Filename length: 8 characters        ◄ x2 for UTF-16LE bytes
+0x41    03                             Namespace: 0x03 = Win32+DOS          ◄ Short name, single $FN
+0x42    74 00 65 00 73 00 74 00 2E 00 74 00 78 00 74 00  Filename: "test.txt"

The parent directory reference at +0x00 contains a 6-byte MFT entry number (5 = root directory) and a 2-byte sequence number (3). To reconstruct the full path, follow the parent chain: read the parent's MFT entry, read its $FN attribute for the directory name and its parent reference, continue until you reach MFT entry 5 (root). MFTECmd does this automatically in the "ParentPath" column. When it fails (because a parent directory's MFT entry was reallocated), it outputs an incomplete path.

Anti-Pattern

Claiming $FN timestamps are immutable

$FN timestamps cannot be modified through user-mode Windows APIs. But an attacker with kernel-level access (a kernel driver or direct disk write tool) can modify them. Tools like SetMACE have proof-of-concept modes for $FN modification via raw disk writes. In court testimony, state "$FN timestamps cannot be modified through standard Windows APIs and require kernel-level or direct disk access to alter." This is accurate and defensible. "Cannot be modified" is technically incorrect and can be challenged.

Filename and namespace

At +0x40, one byte contains the filename length in characters (multiply by 2 for UTF-16LE bytes). At +0x41, one byte indicates the namespace: 0x00 POSIX (rare), 0x01 Win32 (long name), 0x02 DOS (8.3 short name), 0x03 Win32+DOS (short enough for both). The filename at +0x42 is UTF-16LE encoded. ASCII characters appear as the character byte followed by 0x00.

Most files have either one $FN attribute (namespace 0x03, when the filename is short enough for DOS compatibility) or two $FN attributes (namespace 0x01 for the Win32 long name and namespace 0x02 for the DOS 8.3 short name). When two $FN attributes exist, each has its own set of four timestamps. In practice, the timestamps in both are typically identical because NTFS sets them at the same time during file creation. However, certain operations can cause them to diverge — this is an edge case worth checking when precision matters.

Hard links create additional $FN attributes. Each hard link adds a $FN attribute with a different parent directory reference and potentially a different filename. The timestamps in each $FN attribute reflect when that hard link was created. The oldest $FN Created timestamp corresponds to the original filename, and newer $FN Created timestamps correspond to hard links added later. The hard link count at record header offset 0x12 tells you how many $FN attributes to expect. If the count is 1, expect one or two $FN attributes (Win32 + optional DOS). If the count is 2 or higher, expect additional $FN attributes for each hard link.

$FN timestamp update behavior

$FN Created: Set once when the file is created. Never updated by normal file operations. Editing the file, changing permissions, moving the file within the same volume, renaming the file — none of these update $FN Created. The only operations that set $FN Created are file creation (new file or copy) and tunnel-cache operations (described below). This makes $FN Created the most stable and reliable timestamp in NTFS. On a file that has not been subject to timestomping or tunnel-cache effects, $FN Created reflects the actual time the file was created on this volume.

$FN Modified: Updated when the file's data is modified AND the parent directory's $INDEX entry is updated to reflect the new size. In practice, this means $FN Modified tracks data changes that change the file's displayed size in the directory listing. Small edits that don't change the allocated size may not trigger a $FN Modified update. Large writes that extend or truncate the file do trigger it. $FN Modified is less frequently updated than $SI Modified because not every data write triggers a directory index update.

$FN Entry Modified: Updated when the MFT record is modified in a way that affects the directory index. This is less frequently updated than $SI Entry Modified — internal MFT changes that don't affect the directory listing don't trigger a $FN Entry Modified update.

$FN Accessed: Follows the same lazy-update rules as $SI Accessed. Disabled by default on Windows 10/11, giving hour-level granularity at best.

The NTFS tunnel cache

One legitimate mechanism can cause unexpected $FN timestamps: the NTFS tunnel cache. When a file is deleted and a new file is created with the same name in the same directory within 15 seconds (the default tunnel cache timeout), NTFS copies the deleted file's $FN timestamps to the new file. This preserves timestamp continuity during save operations where applications delete the original file and write a new one with the same name (a common save pattern in older applications).

The tunnel cache can cause forensic confusion: a file appears to have a $FN Created timestamp from a previous file that occupied the same name. The effect is time-limited (15 seconds) and name-specific (the new file must have the same name as the deleted file in the same directory). It does not affect files created with new names, files created more than 15 seconds after a deletion, or files created in different directories.

For the forensic examiner, the tunnel cache means $FN timestamps are highly reliable but not absolute. When a $FN Created timestamp seems inconsistent with other evidence (particularly when it is older than expected), consider whether the file's name was previously used by another file in the same directory. USN Journal analysis (covered in later modules) can confirm or rule out this scenario by showing the deletion of the previous file and the creation of the new one within the tunnel cache window. The tunnel cache timeout is configurable via the registry key HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\MaximumTunnelEntryAgeInSeconds, though modifying it is extremely rare in production environments.

Investigation Principle

For every file central to your investigation, compare $SI Created against $FN Created. Three indicators flag timestomping: temporal inversion ($SI earlier than $FN), precision anomaly ($SI zero fractional, $FN full nanosecond), and temporal gap (more than a few seconds difference with no USN Journal entry explaining it). This comparison should be documented in your methodology section as timestamp integrity verification.

$FILE_NAME Attribute Field Reference

+0x00 (8B): Parent directory MFT reference — 6B entry number + 2B sequence number.

+0x08-0x27 (32B): Four MACE timestamps — same FILETIME format as $SI but NTFS-driver controlled.

+0x40 (1B): Filename length in characters (x2 for byte count in UTF-16LE).

+0x41 (1B): Namespace — 0x00 POSIX, 0x01 Win32, 0x02 DOS, 0x03 Win32+DOS.

+0x42 (var): Filename — UTF-16LE encoded. ASCII chars = byte + 0x00.

Next
Section 1.3 examines the $DATA and $INDEX attributes: how file content is stored (resident vs non-resident), data run encoding, Alternate Data Streams, and the directory B-tree structure that provides deleted filename evidence through $I30 slack.
Unlock the Full Course See Full Course Agenda