The $UsnJrnl records every file system change on an NTFS volume — every create, delete, rename, data extension, and security modification — in a chronological stream that persists even when the files themselves are gone. When an investigator needs to prove that 4,200 files were deleted in a two-minute window at 02:17 AM, the change journal is the artifact that answers the question.
What Is $UsnJrnl?
The Update Sequence Number Journal ($UsnJrnl) is an NTFS change journal that records metadata about every file system operation on a volume. It was introduced in Windows 2000 (NTFS 3.0) and is enabled by default on all modern NTFS volumes. Every time a file or directory is created, deleted, renamed, extended, truncated, or has its security descriptor changed, NTFS writes a USN record to the journal. Each record contains a timestamp, the filename, the parent directory’s MFT reference, and a set of reason flags that describe exactly what changed.
The journal exists as an alternate data stream named $J on the system file $Extend\$UsnJrnl. It operates as a sparse file — the OS maintains a maximum size (typically 32–64 MB), and as the journal grows, the oldest records are marked as sparse (effectively deleted) while new records are appended at the end. This means the journal is a rolling window: on a busy system, it may contain only a few days of history; on a quiet system, it may span weeks or months.
The $UsnJrnl is fundamentally different from the $MFT in what it captures. The $MFT stores the current state of a file (or the last state before entry reuse). The $UsnJrnl stores every change event — the complete sequence of operations. A file that was created, renamed three times, extended twice, and then deleted will produce six or more USN records, each with its own timestamp and reason flags. This event-level granularity makes the $UsnJrnl the primary timeline artifact for file system activity.
The $UsnJrnl records file system events, not file states. A single file deletion generates a USN record even if the MFT entry is immediately reallocated and the $I30 slack is overwritten. The journal is frequently the last artifact that proves a file existed when all other evidence has been destroyed.
Location & Format
File Path & Properties
| Property | Detail |
|---|---|
| Location | C:\$Extend\$UsnJrnl:$J (alternate data stream) |
| Max data stream | C:\$Extend\$UsnJrnl:$Max (contains journal configuration: max size and allocation delta) |
| Format | Binary stream of variable-length USN_RECORD_V2 or V3 structures |
| Typical size | 32–64 MB (default maximum; configurable via fsutil) |
| OS versions | Windows 2000 through Windows 11 (NTFS 3.0+) |
| Access on live system | Locked by NTFS driver; requires raw disk read or fsutil usn readjournal |
USN Record Structure
Each USN record (version 2, the most common) contains the following fields:
| Field | Size | Description | Forensic Value |
|---|---|---|---|
RecordLength | 4 bytes | Total length of this USN record | Used for sequential parsing |
MajorVersion | 2 bytes | USN record version (2 or 3) | Version 3 uses 128-bit file references |
FileReferenceNumber | 8 bytes | MFT entry number + sequence number | Links the event to a specific MFT record |
ParentFileReferenceNumber | 8 bytes | Parent directory MFT reference | Resolves the directory path of the affected file |
Usn | 8 bytes | Byte offset in the $J stream | Monotonically increasing; establishes event ordering |
TimeStamp | 8 bytes | Windows FILETIME (100ns precision) | Exact time of the file system change |
Reason | 4 bytes | Bitmask of reason flags | Describes the type of change (see table below) |
SourceInfo | 4 bytes | Additional source flags | Identifies OS-level operations vs. user-level |
SecurityId | 4 bytes | Security descriptor index | Links to the $Secure file for permission changes |
FileAttributes | 4 bytes | File attribute flags at time of change | Hidden, system, archive, directory flags |
FileNameLength | 2 bytes | Length of the filename in bytes | Used for parsing |
FileNameOffset | 2 bytes | Offset to the filename within the record | Used for parsing |
FileName | Variable | Unicode filename (not full path) | The name of the file at the time of the event |
Key Reason Flags
| Flag | Value | Meaning | Forensic Significance |
|---|---|---|---|
USN_REASON_FILE_CREATE | 0x00000100 | File was created | Proves a file was placed on the volume at a specific time |
USN_REASON_FILE_DELETE | 0x00000200 | File was deleted | Proves deletion occurred; timestamp shows when |
USN_REASON_DATA_EXTEND | 0x00000002 | File data was extended (content added) | Indicates file was written to; size was increasing |
USN_REASON_DATA_OVERWRITE | 0x00000001 | Existing file data was overwritten | Content modification; file was being actively written |
USN_REASON_DATA_TRUNCATION | 0x00000004 | File was truncated | Content was reduced; possible secure-wipe indicator |
USN_REASON_RENAME_OLD_NAME | 0x00001000 | File was renamed (old name) | Captures the filename before the rename |
USN_REASON_RENAME_NEW_NAME | 0x00002000 | File was renamed (new name) | Captures the filename after the rename |
USN_REASON_SECURITY_CHANGE | 0x00000800 | Security descriptor was modified | Permissions were changed; possible privilege escalation indicator |
USN_REASON_CLOSE | 0x80000000 | File handle was closed | Combined with other flags to indicate operation completion |
Reason flags are a bitmask — multiple flags can be set simultaneously. A typical file creation sequence produces records with FILE_CREATE | DATA_EXTEND | CLOSE. A rename produces two records: one with RENAME_OLD_NAME (containing the original filename) and one with RENAME_NEW_NAME (containing the new filename). Both records share the same FileReferenceNumber, linking them to the same MFT entry.
What It Reveals
The $UsnJrnl answers the following investigative questions:
- What files were created, deleted, or renamed on the volume, and when? — Each USN record carries a timestamp and reason flags that describe the exact operation. The filename and parent MFT reference are recorded at the time of the event.
- Were files mass-deleted in a short time window? — Thousands of
FILE_DELETErecords within a narrow timestamp range indicate bulk cleanup or data destruction. This pattern is common in insider threat cases (staging directory cleanup) and ransomware (original file deletion after encryption). - Was a file renamed to disguise its identity? —
RENAME_OLD_NAMEandRENAME_NEW_NAMErecords capture both the original and final filenames. An adversary renamingrclone.exetosvchost.exeis recorded in full: the journal shows the old name, the new name, and the exact timestamp of the rename. - Was data written to a file (staging) before exfiltration? —
DATA_EXTENDrecords for a file in a staging directory prove that data was being aggregated. Combined with $MFT file size data and SRUM network transfer volumes, this builds a complete staging-to-exfiltration timeline. - Did a file exist even though the MFT entry has been reallocated? — If the MFT entry was reused by a new file, the original file’s creation and deletion events may still exist in the $UsnJrnl. The journal provides the only surviving record of the file’s existence.
- What was the chronological sequence of file operations? — The monotonically increasing USN values establish absolute ordering of events. Combined with FILETIME timestamps, investigators can reconstruct second-by-second activity timelines.
- Were security permissions changed on sensitive files? —
SECURITY_CHANGErecords identify when ACLs were modified, which may indicate privilege escalation or data access preparation.
A legitimate user might delete 10–50 files during normal cleanup. An insider threat staging directory cleanup or ransomware file deletion produces thousands of FILE_DELETE records in a 30-second to 2-minute window. This burst pattern is a high-confidence indicator of malicious activity and is trivially detectable by grouping USN records by time bucket and counting deletion events per interval.
Forensic Use Cases
1. Mass Deletion Detection
An insider prepares to leave the company and copies 4,200 proprietary documents to a staging directory. After uploading them via a cloud sync tool, they delete the staging directory. The $UsnJrnl records 4,200 FILE_DELETE entries between 02:17:42 and 02:19:11 — a 89-second burst. The parent MFT reference on all records points to a single directory: C:\Users\jdoe\Documents\backup_temp. The filename field on each record preserves the names of every deleted document. The MFT entries have already been partially reallocated, but the journal still holds the complete file list.
2. File Rename Tracking (Tool Masquerading)
An adversary downloads rclone.exe, renames it to rc.exe, and later renames it again to svchost.exe to blend in. The $UsnJrnl captures both renames as paired records: RENAME_OLD_NAME: rclone.exe / RENAME_NEW_NAME: rc.exe at 22:14:03, then RENAME_OLD_NAME: rc.exe / RENAME_NEW_NAME: svchost.exe at 22:14:17. The complete chain of names is preserved, and the FileReferenceNumber on all four records is identical, proving they refer to the same file.
3. Data Modification Timeline
During a ransomware investigation, the $UsnJrnl reveals the encryption sequence. Each original file generates a DATA_OVERWRITE record (content replaced with ciphertext), followed by a RENAME_NEW_NAME record (extension changed to .locked), followed by FILE_DELETE for the Volume Shadow Copy deletion commands. The timestamps show the encryption proceeded at approximately 1,200 files per minute, starting at 03:41 AM and completing at 04:17 AM.
4. Proving File Existence After MFT Reuse
An attacker’s PowerShell script (invoke-exfil.ps1) was created, executed, and deleted. Heavy system activity caused the MFT entry to be reallocated within hours. The $I30 slack for the parent directory was also overwritten. However, the $UsnJrnl still contains the original FILE_CREATE record (with filename invoke-exfil.ps1, timestamp 2026-03-14 01:22:08) and the subsequent FILE_DELETE record (timestamp 2026-03-14 01:47:33). The journal is the only surviving evidence that this file ever existed on the volume.
5. Anti-Forensics Activity Timing
After completing data theft, a subject runs a cleanup script. The $UsnJrnl captures the sequence: FILE_DELETE for browser history files, FILE_DELETE for Prefetch files (*.pf), FILE_DELETE for Recent Items (*.lnk), and DATA_OVERWRITE for the Recycle Bin index. The timestamps show the cleanup ran between 02:42 and 02:43 — one minute of automated anti-forensics. The journal itself records the attacker’s cleanup activity as evidence.
Acquisition Methods
The $UsnJrnl:$J stream is locked by the NTFS driver. Standard copy operations will fail. Use fsutil usn readjournal for live parsing, KAPE or RawCopy for raw extraction, or extract from a forensic image. The $J stream is a sparse file — its logical size may appear much larger than its actual data content.
Live System — fsutil (Built-in Windows Tool)
:: Query the current journal state fsutil usn queryjournal C: :: Read journal entries (outputs to console; redirect to file) fsutil usn readjournal C: csv > C:\Evidence\usnjrnl_live.csv :: Enumerate specific USN records by file reference fsutil usn readdata C:\path\to\specific\file.txt :: Note: fsutil output is limited on older Windows versions :: Prefer KAPE or MFTECmd for production forensics
Live System — Raw Copy Utilities
:: Using KAPE (Kroll Artifact Parser and Extractor) kape.exe --tsource C: --tdest C:\Evidence\KAPE_Output --target UsnJrnl :: Using RawCopy (bypasses NTFS file locks) RawCopy.exe /FileNamePath:C:\$Extend\$UsnJrnl /OutputPath:C:\Evidence\ :: Using Velociraptor (remote collection via VQL) :: Artifact: Windows.KapeFiles.Targets with target "UsnJrnl" :: Or: SELECT * FROM parse_usn(device="C:")
Forensic Image — Direct Extraction
# Mount the forensic image (read-only) mount -o ro,noexec,nodev,show_sys_files /dev/sdb1 /mnt/evidence # Extract $UsnJrnl using The Sleuth Kit # First, find the inode for $UsnJrnl fls /path/to/image.E01 11 | grep UsnJrnl # Output: r/r 58-128-1: $UsnJrnl # Extract the $J data stream (ADS) icat /path/to/image.E01 58-128-4 > /analysis/usnjrnl/\$J # Note: the stream number for $J may vary; # use istat to enumerate all streams on the inode istat /path/to/image.E01 58
Parsing Tools & Analysis
| Tool | Author | License | Output | Notes |
|---|---|---|---|---|
| MFTECmd | Eric Zimmerman | Free | CSV / JSON | Parses $J stream directly; fast; handles sparse regions; primary recommendation |
| USN-Journal-Parser | PoorBillionaire | Open source (Python) | CSV | Python-based; cross-platform; well-documented; good for scripted analysis |
| NTFS Log Tracker | Junghoon Oh | Free | GUI + CSV | Correlated $UsnJrnl + $LogFile + $MFT analysis in a single interface |
| fsutil | Microsoft | Built-in | Console / CSV | Available on every Windows system; limited filtering capabilities |
| Velociraptor | Rapid7 | Open source | VQL results | parse_usn() plugin for live and offline parsing; powerful filtering via VQL |
| The Sleuth Kit | Brian Carrier | Open source | CLI | usnjls for journal listing (available in newer versions) |
Parsing with MFTECmd
:: Parse $J stream to CSV MFTECmd.exe -f C:\Evidence\$J --csv C:\Analysis\USN_Output --csvf usnjrnl_parsed.csv :: Output columns include: :: EntryNumber, SequenceNumber, ParentEntryNumber, ParentSequenceNumber :: Usn, Timestamp, FileName, Extension, FileAttributes :: UpdateReasons (human-readable reason flags) :: UpdateSourceFlags, SecurityId :: Parse with body file output for timeline integration MFTECmd.exe -f C:\Evidence\$J --body C:\Analysis\USN_Output --bodyf usn_body.txt
Parsing with USN-Journal-Parser
# Install USN-Journal-Parser pip install usn-journal-parser # Parse the $J stream usn_parser /analysis/usnjrnl/\$J -o /analysis/usnjrnl/usn_parsed.csv # Or use the Python API for custom filtering python3 -c " from usn_journal_parser import UsnJournalParser parser = UsnJournalParser('/analysis/usnjrnl/\$J') for record in parser: print(f'{record.timestamp} | {record.filename} | {record.reason_string}') "
Mass Deletion Detection Script
# Detect bulk file deletion events (insider threat / ransomware indicator) import pandas as pd df = pd.read_csv('/analysis/usnjrnl/usnjrnl_parsed.csv') # Filter for deletion events deletes = df[df['UpdateReasons'].str.contains('FileDelete', na=False)].copy() # Parse timestamps and create 1-minute buckets deletes['Timestamp'] = pd.to_datetime(deletes['Timestamp']) deletes['Bucket'] = deletes['Timestamp'].dt.floor('1min') # Count deletions per minute burst = deletes.groupby('Bucket').agg( DeleteCount=('FileName', 'count'), UniqueParents=('ParentEntryNumber', 'nunique'), SampleFiles=('FileName', lambda x: ', '.join(x.head(3))) ).sort_values('DeleteCount', ascending=False) # Flag minutes with more than 100 deletions suspicious = burst[burst['DeleteCount'] > 100] print(f"Suspicious deletion bursts: {len(suspicious)}") print(suspicious.head(10).to_string())
Sample Output
Suspicious deletion bursts: 2 Bucket DeleteCount UniqueParents SampleFiles 2026-03-14 02:17:00 2847 1 Q4_Revenue_Final.xlsx, Board_Deck_2026.pptx, Customer_List.csv 2026-03-14 02:18:00 1353 1 Patent_Filing_Draft.docx, Source_Code_v3.zip, API_Keys.txt
Two consecutive minutes with 2,847 and 1,353 deletions respectively, all from a single parent directory (UniqueParents = 1). The sample filenames include revenue documents, board presentations, customer lists, patent filings, and source code archives. This is a classic insider threat cleanup pattern: the staging directory was purged at 02:17 AM after the exfiltration completed.
Retention & Persistence
| Property | Detail |
|---|---|
| Default maximum size | 32–64 MB (varies by Windows version and volume size) |
| Effective retention | Days to weeks (depends on file system activity volume) |
| Survives reboot | Yes — journal is persistent on disk |
| Survives application uninstall | Yes — uninstall generates FILE_DELETE records that are themselves journaled |
| Rollover behavior | Circular: oldest records are marked sparse (logically deleted) as new records are appended |
| High-activity systems | Build servers, file servers, and developer workstations may retain only 24–72 hours |
| Low-activity systems | Kiosk machines and single-purpose servers may retain weeks or months |
The retention window is a function of the maximum journal size divided by the rate of file system change events. A busy developer workstation generating millions of file operations per day (build artifacts, node_modules, temp files) will roll over the journal in 24–48 hours. A relatively static server with minimal file churn may retain journal entries for 30+ days. Always collect the $UsnJrnl as early as possible in an investigation — every hour of delay risks losing the oldest entries.
Anti-Forensics Resilience
The $UsnJrnl occupies a middle ground in anti-forensics resilience. It is more resistant than Prefetch or browser history (which are trivially cleared) but less resistant than the $MFT (which cannot be directly modified on a live system). The journal can be administratively deleted, but doing so is itself a detectable event.
| Tool / Technique | Clears $UsnJrnl? | Explanation |
|---|---|---|
| CCleaner | No | No USN journal module; does not target NTFS system files |
| Eraser | No | Targets user-specified files; cannot access NTFS metafiles |
| SDelete | No | Operates on user-accessible files; cannot modify journal streams |
| BleachBit | No | No USN journal cleaner module exists |
| Browser cleanup | No (but generates records) | Deleting browser history creates FILE_DELETE records in the journal |
fsutil usn deletejournal /d C: | Yes | Administratively deletes the journal. Requires elevation. Detectable: generates Event ID 1 in the USN journal itself (the deletion is the last record) and may trigger NTFS warnings in System event log. |
fsutil usn deletejournal /n C: | Partial | Notifies the journal for deletion on next reboot; current entries survive until restart |
| Volume formatting | Yes | Full format destroys all NTFS metadata including the journal |
The most widely used anti-forensics tools (CCleaner, BleachBit, Eraser) do not include $UsnJrnl cleanup modules. The only built-in method to clear the journal is fsutil usn deletejournal, which requires administrator privileges and is not included in any known automated cleanup script distributed by commodity malware or insider threat toolkits. Furthermore, the act of deleting files during cleanup generates new USN records — the cleanup tool’s own activity is journaled.
MITRE ATT&CK Detection Mapping
$UsnJrnl analysis provides evidentiary support for detecting the following MITRE ATT&CK techniques:
| Technique | Name | $UsnJrnl Evidence |
|---|---|---|
T1070.004 T1070.004 | File Deletion | FILE_DELETE records with timestamps; mass deletion burst patterns indicating cleanup operations |
T1036 T1036 | Masquerading | RENAME_OLD_NAME / RENAME_NEW_NAME pairs revealing original filenames before masquerading renames |
T1485 T1485 | Data Destruction | Mass DATA_OVERWRITE followed by RENAME_NEW_NAME (extension change) indicates ransomware encryption sequence |
T1074 T1074 | Data Staged | FILE_CREATE and DATA_EXTEND records in staging directories; high-volume file copy patterns |
Related Artifacts & Case Studies
Corroborating Artifacts
| Artifact | Relationship to $UsnJrnl | Cross-Correlation Value |
|---|---|---|
| $MFT | MFT records provide the file state snapshot; $UsnJrnl provides the event history | $UsnJrnl shows what changed; $MFT shows what remains — together they reconstruct the full timeline |
| $I30 Index | Directory index entries with timestamps in slack space | $I30 slack may preserve filenames missing from both $MFT (reused) and $UsnJrnl (rolled over) |
| $LogFile | NTFS transaction log for metadata operations | $LogFile captures low-level metadata changes; $UsnJrnl captures the high-level file operations |
| SRUM.db | Network transfer volumes per application | $UsnJrnl shows file staging and cleanup timing; SRUM shows the network transfer volumes during the same window |
| Prefetch | Execution evidence with timestamps and referenced files | Prefetch proves the tool executed; $UsnJrnl shows the file operations the tool performed |
| Security.evtx | Event ID 4663 (object access) and 4688 (process creation) | Security logs show who accessed files; $UsnJrnl shows what happened to those files afterward |
Case Study
The Ghost in the Index — When MFT entries were reallocated, the $UsnJrnl provided the event log that proved 4,200 files were created in a staging directory, existed for approximately two hours, and were then mass-deleted. Combined with $I30 slack analysis and SRUM network transfer data, the journal completed the evidence chain from staging through exfiltration to cleanup.
References
- Eric Zimmerman, “MFTECmd — $UsnJrnl Parser” — https://ericzimmerman.github.io/
- PoorBillionaire, “USN-Journal-Parser” — https://github.com/PoorBillionaire/USN-Journal-Parser
- Microsoft, “Change Journals (NTFS)” — https://learn.microsoft.com
- SANS Institute, “NTFS Change Journal Forensics” — https://www.sans.org/blog/
- 13Cubed, “$UsnJrnl Analysis for DFIR” — https://www.13cubed.com/blog
- Junghoon Oh, “NTFS Log Tracker” — https://sites.google.com/site/forensaboratory/
- ForensicArtifacts.com, “Windows NTFS Artifact Definitions” — https://github.com/ForensicArtifacts/artifacts
- Microsoft, “fsutil usn” command reference — https://learn.microsoft.com
Mjolnir Security — Digital Forensics & Incident Response
Mjolnir Security provides 24/7 incident response, digital forensics, and expert witness testimony. Our DFIR team specializes in NTFS journal analysis, mass deletion detection, and file system timeline reconstruction for insider threat and ransomware investigations.
mjolnirsecurity.com — 24/7: +1 833 403 5875