This artifact parses the NTFS USN journal and allows filters to assist investigative workflow.
NTFS is a journal filesystem. This means that it maintains a journal file where intended filesystem changes are written first, then the filesystem is changed. This journal is called the USN journal in NTFS.
Velociraptor can parse the USN journal from the filesystem. This provides an indication of recent file changes. Typically the system maintains the journal of around 30mb and depending on system activity this can go back quite some time.
Use this artifact to determine the times when a file was modified/added from the journal. This will be present even if the file was later removed.
Availible filters are Filename, OSPath, MFT/Parent ID and time bounds.
name: Windows.Forensics.Usn
description: |
This artifact parses the NTFS USN journal and allows filters to
assist investigative workflow.
NTFS is a journal filesystem. This means that it maintains a journal
file where intended filesystem changes are written first, then the
filesystem is changed. This journal is called the USN journal in NTFS.
Velociraptor can parse the USN journal from the filesystem. This
provides an indication of recent file changes. Typically the system
maintains the journal of around 30mb and depending on system
activity this can go back quite some time.
Use this artifact to determine the times when a file was
modified/added from the journal. This will be present even if the
file was later removed.
Availible filters are Filename, OSPath, MFT/Parent ID and time bounds.
type: CLIENT
parameters:
- name: Device
description: The NTFS drive to parse
default: "C:\\"
- name: MFTFile
description: Alternatively provide an MFTFile to use for resolving paths.
- name: USNFile
description: Alternatively provide a previously extracted USN file to parse.
- name: Accessor
description: The accessor to use.
- name: AllDrives
description: Dump USN from all drives and VSC
type: bool
- name: FileNameRegex
description: A regex to match the Filename field.
default: .
- name: PathRegex
description: A regex to match the entire path (you can watch a directory or a file type).
default: .
type: regex
- name: MFT_ID_Regex
description: A regex to match the MFTId. e.g ^10225$ or ^(10225|232111)$
default: .
type: regex
- name: Parent_MFT_ID_Regex
description: A regex to match the MFTId. e.g ^10225$ or ^(10225|232111)$
default: .
type: regex
- name: DateAfter
type: timestamp
description: "search for events after this date. YYYY-MM-DDTmm:hh:ssZ"
- name: DateBefore
type: timestamp
description: "search for events before this date. YYYY-MM-DDTmm:hh:ssZ"
- name: FastPaths
type: bool
description: When set use a faster but less accurate path reassembly algorithm.
sources:
- precondition:
SELECT OS From info() where OS =~ 'windows'
query: |
-- firstly set timebounds for performance
LET DateAfterTime <= if(condition=DateAfter,
then=timestamp(epoch=DateAfter), else=timestamp(epoch="1600-01-01"))
LET DateBeforeTime <= if(condition=DateBefore,
then=timestamp(epoch=DateBefore), else=timestamp(epoch="2200-01-01"))
-- If the user specified an MFTFile then ignore the device
LET Device <= if(condition=MFTFile OR USNFile, then="",
else=if(condition=Device,
then=pathspec(parse=Device, path_type="ntfs")))
LET Parse(MFT, USN, Accessor) = SELECT *
FROM parse_usn(accessor=Accessor, fast_paths=FastPaths,
mft_filename=MFT, usn_filename=USN)
WHERE Filename =~ FileNameRegex
AND _FileMFTID =~ MFT_ID_Regex
AND _ParentMFTID =~ Parent_MFT_ID_Regex
AND Timestamp < DateBeforeTime
AND Timestamp > DateAfterTime
AND _Links =~ PathRegex
LET all_drives = SELECT * FROM foreach(
row={
SELECT OSPath[:1] AS Drive
FROM glob(globs="/*/$Extend/$UsnJrnl:$J", accessor="ntfs")
WHERE log(message=format(format="Processing Drive %v", args=Drive))
}, query={
SELECT Timestamp,
Filename,
Drive + OSPath AS OSPath,
_Links,
Reason,
_FileMFTID as MFTId,
_FileMFTSequence as Sequence,
_ParentMFTID as ParentMFTId,
_ParentMFTSequence as ParentSequence,
FileAttributes,
SourceInfo,
Usn
FROM Parse(MFT=Drive + "$MFT",
USN=Drive + "$Extend/$UsnJrnl:$J",
Accessor="ntfs")
})
SELECT *
FROM if(condition=AllDrives, then=all_drives, else={
SELECT * FROM if(condition=Device AND
log(message=format(format="Processing Device %v", args=Device)),
then={
SELECT Timestamp,
Filename,
Device + OSPath AS OSPath,
_Links,
Reason,
_FileMFTID as MFTId,
_FileMFTSequence as Sequence,
_ParentMFTID as ParentMFTId,
_ParentMFTSequence as ParentSequence,
FileAttributes,
SourceInfo,
Usn
FROM Parse(MFT=Device + "$MFT",
USN=Device + "$Extend/$UsnJrnl:$J",
Accessor="ntfs")
}, else={
SELECT Timestamp,
Filename,
OSPath,
_Links,
Reason,
_FileMFTID as MFTId,
_FileMFTSequence as Sequence,
_ParentMFTID as ParentMFTId,
_ParentMFTSequence as ParentSequence,
FileAttributes,
SourceInfo,
Usn
FROM Parse(MFT=MFTFile,
USN=USNFile, Accessor=Accessor)
})
})