Windows keeps a cache of prefetch files. When an executable is run, the system records properties about the executable to make it faster to run next time. By parsing this information we are able to determine when binaries are run in the past. On Windows10 we can see the last 8 execution times and creation time (9 potential executions).
This artifact is a timelined output version of the standard Prefetch artifact. There are several parameter’s availible.
name: Windows.Timeline.Prefetch
author: Matt Green - @mgreen27
description: |
Windows keeps a cache of prefetch files. When an executable is run,
the system records properties about the executable to make it faster
to run next time. By parsing this information we are able to
determine when binaries are run in the past. On Windows10 we can see
the last 8 execution times and creation time (9 potential executions).
This artifact is a timelined output version of the standard Prefetch
artifact. There are several parameter's availible.
- dateAfter enables search for prefetch evidence after this date.
- dateBefore enables search for prefetch evidence before this date.
- binaryRegex enables to filter on binary name, e.g evil.exe.
- hashRegex enables to filter on prefetch hash.
reference:
- https://www.forensicswiki.org/wiki/Prefetch
parameters:
- name: prefetchGlobs
default: C:\Windows\Prefetch\*.pf
- name: dateAfter
description: "search for events after this date. YYYY-MM-DDTmm:hh:ssZ"
type: timestamp
- name: dateBefore
description: "search for events before this date. YYYY-MM-DDTmm:hh:ssZ"
type: timestamp
- name: binaryRegex
description: "Regex of executable name."
type: regex
- name: hashRegex
description: "Regex of prefetch hash."
type: regex
precondition: SELECT OS From info() where OS = 'windows'
sources:
- query: |
LET hostname <= SELECT Fqdn FROM info()
SELECT LastRunTimes as event_time,
hostname.Fqdn[0] as hostname,
"Prefetch" as parser,
message,
OSPath as source,
Executable as file_name,
CreationTime as prefetch_ctime,
ModificationTime as prefetch_mtime,
FileSize as prefetch_size,
Hash as prefetch_hash,
Version as prefetch_version,
PrefetchFileName as prefetch_file,
RunCount as prefetch_count
FROM foreach(
row={
SELECT *
FROM Artifact.Windows.Forensics.Prefetch(
prefetchGlobs=prefetchGlobs,
dateAfter=dateAfter,
dateBefore=dateBefore,
binaryRegex=binaryRegex,
hashRegex=hashRegex)
},
query={
SELECT *
FROM chain(a1={
SELECT *
FROM flatten(query={
SELECT Executable,
FileSize,
Hash,
Version,
LastRunTimes,
"Evidence of Execution: " + Executable + format(
format=" Prefetch run count %v", args=RunCount) as message,
RunCount,
OSPath,
PrefetchFileName,
CreationTime,
ModificationTime,
Binary
FROM scope()
})
}, b1={
-- One more row for creation time
SELECT Executable,
FileSize,
Hash,
Version,
CreationTime AS LastRunTimes,
"Evidence of Execution (Btime): " + Executable + format(
format=" Prefetch run count %v", args=RunCount) as message,
RunCount,
OSPath,
PrefetchFileName,
CreationTime,
ModificationTime,
Binary
FROM scope()
})
-- This group by applies on only a single prefetch file to
-- remove duplication with CreationTime
GROUP BY LastRunTimes
})
ORDER BY event_time