The Velociraptor SQLiteHunter Site #
This repository maintains the source for the
Generic.Forensic.SQLiteHunter VQL artifact. This artifact is
designed to be an efficient and mostly automated artifact to analyze
and collect SQLite based artifacts from various applications on the
endpoint.
The produced artifact is self contained and can be loaded into Velociraptor (https://docs.velociraptor.app) to hunt quickly and efficiently across a large number of endpoints.
You can download the latest artifact pack as a zip file, or as a YAML file and add it manually to Velociraptor.
Parameters #
RuleFilter: If you dont want to run all the rules, you can filter the ones you need using this regular expression.
Rules: Alteratively, the rules may be specified one at the time using a multi-choice selector.
MatchFilename: Rules generally look for SQLite files using known filenames. If this option is unset, we relay on automatic detection to identify the filenames (For example, enumerate the tables in the SQLite file). This makes scanning much slower so by default this setting is enabled.
CustomGlob: Rules default to search for SQLites using known globs. However, if you have a bunch of SQLite files in a different location, you may specify the custom glob to search for files.
DateAfter and DateBefore: These setting allow you to time box the returned rows to only return items that occurred between the specified dates.
FilterRegex: A filter that applies on the entire row (encoded as JSON). This is very useful to find all relevant rows relating to a specific item. For example, if you want to know any rows accessing www.example.com you can specify this filter which will return records like
Visited links,bookmarks,faviconsetc.SQLITE_ALWAYS_MAKE_TEMPFILE: By default Velociraptor will make a temporary copy of the SQLite file before parsing it. This ensure the file is not locked and can be freely accessed. If this setting is set to off parsing might be a lot slower as Velociraptor will have to contend with application locks. There is probably no reason to disable this.
AlsoUpload: This option also uploads the raw SQLite files.
Artifact #
name: Generic.Forensic.SQLiteHunter
description: |
Hunt for SQLite files.
SQLite has become the de-facto standard for storing application data,
in many types of applications:
- Web Browsers
- Operating Systems
- Various applications, such as iMessage, TCC etc
This artifact can hunt for these artifacts in a mostly automated way.
More info at https://github.com/Velocidex/SQLiteHunter
NOTE: If you want to use this artifact on just a bunch of files already
collected (for example the files collected using the
Windows.KapeFiles.Targets artifact) you can use the CustomGlob parameter
(for example set it to "/tmp/unpacked/**" to consider all files in the
unpacked directory).
column_types:
- name: Image
type: preview_upload
- name: Payload
type: preview_upload
export: |
LET SPEC <= "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"
LET Specs <= parse_json(data=gunzip(string=base64decode(string=SPEC)))
LET CheckHeader(OSPath) = read_file(filename=OSPath, length=12) = "SQLite forma"
LET Bool(Value) = if(condition=Value, then="Yes", else="No")
-- In fast mode we check the filename, then the header then run the sqlite precondition
LET matchFilename(SourceName, OSPath) = OSPath =~ get(item=Specs.sources, field=SourceName).filename
AND CheckHeader(OSPath=OSPath)
AND Identify(SourceName= SourceName, OSPath= OSPath)
AND log(message=format(format="%v matched by filename %v",
args=[OSPath, get(item=Specs.sources, field=SourceName).filename]))
-- If the user wanted to also upload the file, do so now
LET MaybeUpload(OSPath) = if(condition=AlsoUpload, then=upload(file=OSPath)) OR TRUE
LET Identify(SourceName, OSPath) = SELECT if(
condition=CheckHeader(OSPath=OSPath),
then={
SELECT *
FROM sqlite(file=OSPath, query=get(item=Specs.sources, field=SourceName).id_query)
}) AS Hits
FROM scope()
WHERE if(condition=Hits[0].Check = get(item=Specs.sources, field=SourceName).id_value,
then= log(message="%v was identified as %v",
args=[OSPath, get(item=Specs.sources, field=SourceName).Name]),
else=log(message="%v was not identified as %v (got %v, wanted %v)",
args=[OSPath, get(item=Specs.sources, field=SourceName).Name, str(str=Hits),
get(item=Specs.sources, field=SourceName).id_value]) AND FALSE)
LET ApplyFile(SourceName) = SELECT * FROM foreach(row={
SELECT OSPath FROM AllFiles
WHERE if(condition=MatchFilename, then=matchFilename(SourceName=SourceName, OSPath=OSPath),
else=Identify(SourceName= SourceName, OSPath= OSPath))
}, query={
SELECT *, OSPath FROM sqlite(
file=OSPath, query=get(item=Specs.sources, field=SourceName).SQL)
})
-- Filter for matching files without sqlite checks.
LET FilterFile(SourceName) =
SELECT OSPath FROM AllFiles
WHERE if(condition=MatchFilename,
then=OSPath =~ get(item=Specs.sources, field=SourceName).filename)
-- Build a regex for all enabled categories.
LET all_categories = SELECT if(condition=_value = "All", then=".", else=_value) AS _value
FROM foreach(row=["All","MacOS","Browser","Chrome","Edge","Firefox","Google","Cloud","SyncClient","InternetExplorer","Windows"])
WHERE get(field=_value)
parameters:
- name: RuleFilter
type: regex
description: Only collect rules matching this regex filter.
default: "."
- name: Rules
type: multichoice
description: Only collect these rules
default: '[]'
choices:
- "Chromium_Browser_Autofill"
- "Chromium_Browser_Bookmarks"
- "Chromium_Browser_Cookies"
- "Chromium_Browser_Extensions"
- "Chromium_Browser_Favicons"
- "Chromium_Browser_History"
- "Chromium_Browser_Media"
- "Chromium_Browser_Network"
- "Chromium_Browser_Notifications"
- "Chromium_Browser_Shortcuts"
- "Chromium_Browser_Top_Sites"
- "Chromium_Sessions"
- "Edge_Browser_Autofill"
- "Edge_Browser_Collections"
- "Edge_Browser_History_Screenshots"
- "Edge_Browser_Navigation_History"
- "Firefox_Cookies"
- "Firefox_Downloads"
- "Firefox_Favicons"
- "Firefox_Form_History"
- "Firefox_Places"
- "Firefox_Places_History"
- "Firefox_Places_History_Legacy"
- "Google_Drive_Metadata"
- "Google_Drive_Mirrored_Files"
- "Google_Drive_Mirrored_Metadata_Files"
- "Google_Drive_Sync_Roots"
- "IE_or_Edge_WebCacheV01"
- "IntelligencePlatform"
- "MacOS_Applications_Cache"
- "MacOS_NetworkUsage"
- "MacOS_Notes"
- "MacOS_XProtect_Detections"
- "Safari_Browser_History"
- "Windows_Activities_Cache"
- "Windows_Search_Service"
- "Windows_WPNDatabase___Notifications"
- "iMessage"
- name: MatchFilename
description: |
If set we use the filename to detect the type of sqlite file.
When unset we use heuristics (slower)
type: bool
default: Y
- name: CustomGlob
description: Specify this glob to select other files
- name: DateAfter
description: Timebox output to rows after this time.
type: timestamp
default: "1970-01-01T00:00:00Z"
- name: DateBefore
description: Timebox output to rows after this time.
type: timestamp
default: "2100-01-01T00:00:00Z"
- name: FilterRegex
description: Filter critical rows by this regex
type: regex
default: .
- name: All
description: Select all targets
type: bool
default: Y
- name: MacOS
description: Select targets with category MacOS
type: bool
default: N
- name: Browser
description: Select targets with category Browser
type: bool
default: N
- name: Chrome
description: Select targets with category Chrome
type: bool
default: N
- name: Edge
description: Select targets with category Edge
type: bool
default: N
- name: Firefox
description: Select targets with category Firefox
type: bool
default: N
- name: Google
description: Select targets with category Google
type: bool
default: N
- name: Cloud
description: Select targets with category Cloud
type: bool
default: N
- name: SyncClient
description: Select targets with category SyncClient
type: bool
default: N
- name: InternetExplorer
description: Select targets with category InternetExplorer
type: bool
default: N
- name: Windows
description: Select targets with category Windows
type: bool
default: N
- name: SQLITE_ALWAYS_MAKE_TEMPFILE
type: bool
default: Y
- name: AlsoUpload
description: If specified we also upload the identified file.
type: bool
sources:
- name: AllFiles
notebook:
- type: vql
template: |
// This cell generates other cells to preview the collected
// data. DO NOT recalculate this cell - each time new cells
// will be added. Instead delete the notebook and allow
// Velociraptor to recreate the entire notebook.
LET ArtifactsWithResults <=
SELECT pathspec(accessor="fs", parse=Data.VFSPath)[4] AS Artifact ,
pathspec(accessor="fs", parse=Data.VFSPath)[-1][:-5] AS Source ,
stat(accessor="fs", filename=Data.VFSPath + ".index").Size / 8 AS Records
FROM enumerate_flow(client_id=ClientId, flow_id=FlowId)
WHERE Type =~ "Result" AND Records > 0
LET _ <= SELECT notebook_update_cell(notebook_id=NotebookId, type="vql",
input=format(format='''
/*
# Results From %v
*/
SELECT * FROM source(source=%q, artifact=%q)
''', args=[Source, Source, split(string=ArtifactName, sep='/')[0]]),
output=format(format='''
<i>Recalculate</i> to show Results from <b>%v</b> with <b>%v</b> rows
''', args=[Source, Records])) AS NotebookModification
FROM ArtifactsWithResults
/*
# Results Overview
*/
SELECT Source, Records FROM ArtifactsWithResults ORDER BY Source
query: |
LET category_regex <= join(sep="|", array=all_categories._value)
LET RuleFilter <= if(condition=Rules,
then=join(array=Rules, sep="|"),
else=RuleFilter)
LET _ <= log(level="DEBUG", message="Rule Filter is %v", args=RuleFilter)
LET AllGlobs <= filter(list=Specs.globs,
condition="x=> x.tags =~ category_regex AND x.rule =~ RuleFilter")
LET _ <= log(message="Globs for category %v is %v",
args=[category_regex, CustomGlob || AllGlobs.glob])
LET AllFiles <= SELECT OSPath FROM glob(globs=CustomGlob || AllGlobs.glob)
WHERE NOT IsDir AND MaybeUpload(OSPath=OSPath)
SELECT * FROM AllFiles
- name: IntelligencePlatform_Wifi
notebook:
- type: none
output: "IntelligencePlatform_Wifi - Recalculate to view results"
template: |
/*
# IntelligencePlatform_Wifi
*/
SELECT * FROM source(source="IntelligencePlatform_Wifi")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="IntelligencePlatform_Wifi")
// linter: symbol_mask_warn:timestamp
LET Output = SELECT timestamp(cocoatime=timestamp) AS Timestamp,
behaviorType,
split(string=behaviorIdentifier, sep=':')[0] AS event,
split(string=behaviorIdentifier, sep=':')[1] AS network,
OSPath[1] AS User
FROM Rows
SELECT * FROM
if(condition="IntelligencePlatform_Wifi" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Safari_Browser_History_Visits
notebook:
- type: none
output: "Safari_Browser_History_Visits - Recalculate to view results"
template: |
/*
# Safari_Browser_History_Visits
*/
SELECT * FROM source(source="Safari_Browser_History_Visits")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Safari_Browser_History_Visits")
LET Output = SELECT ID,
timestamp(epoch=visit_time + 978307200) AS VisitTime,
URL, Title, VisitCount, DomainExpansion,
if(condition=Origin = 0,
then="Local",
else="iCloud Sync") AS Origin,
Bool(Value=LoadSuccessful) AS LoadSuccessful,
Bool(Value=HttpNonGet) AS HttpNonGet,
RedirectSource, RedirectDestination, OSPath
FROM Rows
WHERE VisitTime > DateAfter AND VisitTime < DateBefore
AND (URL, Title, RedirectSource, RedirectDestination) =~ FilterRegex
SELECT * FROM
if(condition="Safari_Browser_History_Visits" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: iMessage_Profiles
notebook:
- type: none
output: "iMessage_Profiles - Recalculate to view results"
template: |
/*
# iMessage_Profiles
*/
SELECT * FROM source(source="iMessage_Profiles")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="iMessage_Profiles")
LET Output = SELECT timestamp(epoch=date / 1000000000 + 978307200) AS Timestamp, *
FROM Rows
WHERE Timestamp > DateAfter AND Timestamp < DateBefore
AND (MessageText, RoomName) =~ FilterRegex
SELECT * FROM
if(condition="iMessage_Profiles" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Autofill_Profiles
notebook:
- type: none
output: "Chromium_Browser_Autofill_Profiles - Recalculate to view results"
template: |
/*
# Chromium_Browser_Autofill_Profiles
*/
SELECT * FROM source(source="Chromium_Browser_Autofill_Profiles")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Autofill_Profiles")
LET Output = SELECT GUID,
timestamp(epoch= date_modified) AS DateModified,
timestamp(epoch= use_date) AS UseDate,
FirstName, MiddleName, LastName, EmailAddress,
PhoneNumber, CompanyName, StreetAddress,
City, State, ZipCode, UseCount, OSPath
FROM Rows
WHERE UseDate > DateAfter AND UseDate < DateBefore
AND (FirstName, MiddleName, LastName, EmailAddress, CompanyName, StreetAddress) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Autofill_Profiles" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Autofill_Masked_Credit_Cards
notebook:
- type: none
output: "Chromium_Browser_Autofill_Masked Credit Cards - Recalculate to view results"
template: |
/*
# Chromium_Browser_Autofill_Masked Credit Cards
*/
SELECT * FROM source(source="Chromium_Browser_Autofill_Masked Credit Cards")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Autofill_Masked Credit Cards")
LET Output = SELECT * FROM Rows
SELECT * FROM
if(condition="Chromium_Browser_Autofill_Masked Credit Cards" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Bookmarks
notebook:
- type: none
output: "Chromium_Browser_Bookmarks - Recalculate to view results"
template: |
/*
# Chromium_Browser_Bookmarks
*/
SELECT * FROM source(source="Chromium_Browser_Bookmarks")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Chromium_Browser_Bookmarks")
-- Recursive function to report the details of a folder
LET ReportFolder(Data, BaseName) = SELECT * FROM chain(a={
-- First row emit the data about the actual folder
SELECT BaseName + " | " + Data.name AS Name,
timestamp(winfiletime=int(int=Data.date_added) * 10) AS DateAdded,
timestamp(winfiletime=int(int=Data.date_last_used) * 10) AS DateLastUsed,
Data.type AS Type,
Data.url || "" AS URL
FROM scope()
},
b={
-- If this folder has children recurse into it
SELECT * FROM foreach(row={
SELECT _value FROM items(item=Data.children)
}, query={
SELECT * FROM ReportFolder(Data=_value, BaseName=BaseName + " | " + Data.name)
})
})
LET MatchingFiles = SELECT OSPath, parse_json(data=read_file(filename=OSPath)) AS Data
FROM Rows
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT * FROM chain(
a={
SELECT OSPath, *, "bookmark_bar" AS Type
FROM ReportFolder(Data=Data.roots.bookmark_bar, BaseName="")
},
b={
SELECT OSPath, *, "other" AS Type
FROM ReportFolder(Data=Data.roots.other, BaseName="")
},
c={
SELECT OSPath, *, "synced" AS Type
FROM ReportFolder(Data=Data.roots.synced, BaseName="")
})
})
SELECT * FROM
if(condition="Chromium_Browser_Bookmarks" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Cookies_Cookies
notebook:
- type: none
output: "Chromium_Browser_Cookies_Cookies - Recalculate to view results"
template: |
/*
# Chromium_Browser_Cookies_Cookies
*/
SELECT * FROM source(source="Chromium_Browser_Cookies_Cookies")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Cookies_Cookies")
LET Output = SELECT timestamp(winfiletime=(creation_utc * 10) || 0) AS CreationUTC,
timestamp(winfiletime=(expires_utc * 10) || 0) AS ExpiresUTC,
timestamp(winfiletime=(last_access_utc * 10) || 0) AS LastAccessUTC,
timestamp(winfiletime=(last_update_utc * 10) || 0) AS LastUpdateUTC,
HostKey, Name, Path,
Bool(Value=is_secure) AS IsSecure,
Bool(Value=is_httponly) AS IsHttpOnly,
Bool(Value=has_expires) AS HasExpiration,
Bool(Value=is_persistent) AS IsPersistent,
Priority, SourcePort, OSPath
FROM Rows
WHERE LastAccessUTC > DateAfter AND LastAccessUTC < DateBefore
AND (Name, Path) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Cookies_Cookies" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Extensions
notebook:
- type: none
output: "Chromium_Browser_Extensions - Recalculate to view results"
template: |
/*
# Chromium_Browser_Extensions
*/
SELECT * FROM source(source="Chromium_Browser_Extensions")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Chromium_Browser_Extensions")
-- Resolve the message string against the Locale dict
LET ResolveName(Message, Locale) = get(item=Locale,
field=lowcase(string=parse_string_with_regex(regex="^__MSG_(.+)__$", string=Message).g1),
default=Message).message || Message
-- Read the manifest files
LET ManifestData = SELECT OSPath, parse_json(data=read_file(filename=OSPath)) AS Manifest
FROM Rows
-- Message names are case insensitive so lower case the keys to
-- match ResolveName()
LET LowerKeys(Item) = to_dict(item={
SELECT lowcase(string=_key) AS _key, _value FROM items(item=Item)
})
-- Find the Locale file to help with.
LET LocaleData = SELECT *, if(condition=Manifest.default_locale, else=dict(),
then=LowerKeys(Item=parse_json(data=read_file(
filename=OSPath.Dirname + "_locales" + Manifest.default_locale + "messages.json")))) AS Locale
FROM ManifestData
LET GetIcon(Manifest) = Manifest.icons.`128` || Manifest.icons.`64` || Manifest.icons.`32` || Manifest.icons.`16`
-- Flatten the matches of all content scripts into one list of unique sites.
LET ContentScriptMatches(Manifest) = SELECT * FROM foreach(
row=Manifest.content_scripts,
query={ SELECT _value FROM foreach(row=matches) })
GROUP BY _value
LET Output = SELECT OSPath,
-- Manifests are stored in Extensions/<ID>/<Version>/
OSPath.Components[-3] AS ID,
OSPath.Components[-2] AS Version,
Manifest.author.email AS Email,
ResolveName(Message = Manifest.name, Locale=Locale) AS name,
ResolveName(Message = Manifest.description, Locale=Locale) AS description,
Manifest.manifest_version AS ManifestVersion,
Manifest.oauth2.scopes as Scopes,
Manifest.permissions as Permissions,
Manifest.host_permissions AS HostPermissions,
ContentScriptMatches(Manifest=Manifest)._value AS ContentScriptMatches,
Manifest.key as Key, if(condition=GetIcon(Manifest=Manifest),
then=upload(file=OSPath.Dirname + GetIcon(Manifest=Manifest))) AS Image,
Manifest AS _Manifest
FROM LocaleData
WHERE (name, description) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Extensions" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Favicons
notebook:
- type: none
output: "Chromium_Browser_Favicons - Recalculate to view results"
template: |
/*
# Chromium_Browser_Favicons
*/
SELECT * FROM source(source="Chromium_Browser_Favicons")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Favicons")
LET Output = SELECT ID, IconID,
timestamp(winfiletime= (LastUpdated * 10) || 0) AS LastUpdated,
PageURL, FaviconURL,
upload(accessor="data",
file=_image,
name=format(format="Image%v.png", args=ID)) AS Image,
OSPath as _OSPath
FROM Rows
WHERE LastUpdated > DateAfter AND LastUpdated < DateBefore
SELECT * FROM
if(condition="Chromium_Browser_Favicons" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_History_Visits
notebook:
- type: none
output: "Chromium_Browser_History_Visits - Recalculate to view results"
template: |
/*
# Chromium_Browser_History_Visits
*/
SELECT * FROM source(source="Chromium_Browser_History_Visits")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_History_Visits")
LET Output = SELECT ID,
timestamp(winfiletime=(visit_time * 10) || 0) AS VisitTime,
timestamp(winfiletime=(last_visit_time * 10) || 0) AS LastVisitedTime,
URLTitle, URL, VisitCount, TypedCount,
if(condition=hidden =~ '1', then="Yes", else="No") AS Hidden,
VisitID, FromVisitID,
visit_duration / 1000000 AS VisitDurationInSeconds,
OSPath
FROM Rows
WHERE VisitTime > DateAfter
AND VisitTime < DateBefore
AND (URLTitle, URL) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_History_Visits" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_History_Downloads
notebook:
- type: none
output: "Chromium_Browser_History_Downloads - Recalculate to view results"
template: |
/*
# Chromium_Browser_History_Downloads
*/
SELECT * FROM source(source="Chromium_Browser_History_Downloads")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_History_Downloads")
LET StateLookup <= dict(`0`='In Progress', `1`='Complete', `2`="Cancelled", `3`="Interrupted", `4`="Interrupted")
LET DangerType <= dict(`0`='Not Dangerous', `1`="Dangerous", `2`='Dangerous URL', `3`='Dangerous Content',
`4`='Content May Be Malicious', `5`='Uncommon Content', `6`='Dangerous But User Validated',
`7`='Dangerous Host', `8`='Potentially Unwanted', `9`='Whitelisted by Policy',
`10`='Download Pending Detailed Verdict', `11`='Blocked By Policy Password Protected', `12`='Blocked By Policy Download Too Large',
`13`='Sensitive Content Warning', `14`='Sensitive Content Blocked', `15`='Deep Scanned Safe',
`16`='Deep Scanned Dangerous But Opened By User', `17`='Prompt For Deep Scanning', `18`='Blocked Unsupported Filetype',
`19`='Dangerous Associated With Account Compromise', `20`='Deep Scan Failed', `21`='Encrypted Archive Prompt for Local Password Scanning',
`22`='Encrypted Archive Prompt for Local Password Scanning Pending Detailed Verdict', `23`='Blocked by Policy Scan Failed')
LET InterruptReason <= dict(`0`= 'No Interrupt', `1`= 'File Error', `2`='Access Denied', `3`='Disk Full',
`5`='Path Too Long',`6`='File Too Large', `7`='Virus', `10`='Temporary Problem', `11`='Blocked',
`12`='Security Check Failed', `13`='Resume Error File Too Short', `14`='File Hash Mismatch', `15`='File Same As Source',
`20`='Network Error', `21`='Operation Timed Out', `22`='Connection Lost', `23`='Server Down',
`24`='Network Request Invalid', `30`='Server Error', `31`='Range Request Error',
`32`='Server Precondition Error', `33`='Unable to get file', `34`='Server Unauthorized',
`35`='Server Certificate Problem', `36`='Server Access Forbidden', `37`='Server Unreachable',
`38`='Content Length Mismatch', `39`='Cross Origin Redirect', `40`='Cancelled', `41`='Browser Shutdown',
`50`='Browser Crashed')
LET Output = SELECT ID, GUID, CurrentPath, TargetPath, OriginalMIMEType, ReceivedBytes, TotalBytes,
timestamp(winfiletime=(start_time * 10) || 0) AS StartTime,
timestamp(winfiletime=(end_time * 10) || 0) AS EndTime,
timestamp(winfiletime=(opened * 10) || 0) AS Opened,
timestamp(winfiletime=(last_access_time * 10) || 0) AS LastAccessTime,
timestamp(epoch=last_modified) AS LastModified,
get(item=StateLookup, field=str(str=state), default="Unknown") AS State,
get(item=DangerType, field=str(str=danger_type), default="Unknown") AS DangerType,
get(item=InterruptReason, field=str(str=interrupt_reason), default="Unknown") AS InterruptReason,
ReferrerURL, SiteURL, TabURL, TabReferrerURL, DownloadURL, OSPath
FROM Rows
WHERE LastAccessTime > DateAfter AND LastAccessTime < DateBefore
AND (SiteURL, DownloadURL, TabURL, TabReferrerURL, ReferrerURL, DownloadURL) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_History_Downloads" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_History_Keywords
notebook:
- type: none
output: "Chromium_Browser_History_Keywords - Recalculate to view results"
template: |
/*
# Chromium_Browser_History_Keywords
*/
SELECT * FROM source(source="Chromium_Browser_History_Keywords")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_History_Keywords")
LET Output = SELECT KeywordID, URLID,
timestamp(winfiletime=(last_visit_time * 10) || 0) AS LastVisitedTime,
KeywordSearchTerm, Title, URL, OSPath
FROM Rows
WHERE LastVisitedTime > DateAfter AND LastVisitedTime < DateBefore
AND (Title, KeywordSearchTerm, URL) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_History_Keywords" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Media_History
notebook:
- type: none
output: "Chromium_Browser_Media_History - Recalculate to view results"
template: |
/*
# Chromium_Browser_Media_History
*/
SELECT * FROM source(source="Chromium_Browser_Media_History")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Media_History")
LET Output = SELECT ID, URL, WatchTimeSeconds,
Bool(Value=has_video) AS HasVideo,
Bool(Value=has_audio) AS HasAudio,
timestamp(winfiletime=last_updated_time_s || 0) AS LastUpdated,
OriginID, OSPath
FROM Rows
WHERE LastUpdated > DateAfter AND LastUpdated < DateBefore
AND URL =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Media_History" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Media_Playback_Session
notebook:
- type: none
output: "Chromium_Browser_Media_Playback Session - Recalculate to view results"
template: |
/*
# Chromium_Browser_Media_Playback Session
*/
SELECT * FROM source(source="Chromium_Browser_Media_Playback Session")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Media_Playback Session")
LET Output = SELECT ID,
timestamp(winfiletime=last_updated_time_s || 0) AS LastUpdated, URL,
duration_ms / 1000 AS DurationInSeconds,
position_ms / 1000 AS PositionInSeconds,
Title, Artist, Album, SourceTitle, OriginID, OSPath
FROM Rows
WHERE LastUpdated > DateAfter AND LastUpdated < DateBefore
AND URL =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Media_Playback Session" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Network_Predictor
notebook:
- type: none
output: "Chromium_Browser_Network_Predictor - Recalculate to view results"
template: |
/*
# Chromium_Browser_Network_Predictor
*/
SELECT * FROM source(source="Chromium_Browser_Network_Predictor")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Network_Predictor")
LET Output = SELECT * FROM Rows
WHERE UserText =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Network_Predictor" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Notifications_Site_Engagements
notebook:
- type: none
output: "Chromium_Browser_Notifications_Site Engagements - Recalculate to view results"
template: |
/*
# Chromium_Browser_Notifications_Site Engagements
*/
SELECT * FROM source(source="Chromium_Browser_Notifications_Site Engagements")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Chromium_Browser_Notifications_Site Engagements")
LET JSON = SELECT parse_json(data=read_file(filename=OSPath)) AS Data, OSPath FROM Rows
LET Output = SELECT * FROM foreach(row={
SELECT OSPath, Data.profile.content_settings.exceptions AS exceptions FROM JSON
}, query={
SELECT _key AS Site,
timestamp(winfiletime=int(int=_value.last_modified) * 10 || 0) AS LastModified,
timestamp(winfiletime=int(int=_value.setting.lastEngagementTime) * 10 || 0) AS LastEngagementTime,
OSPath
FROM items(item=exceptions.site_engagement)
})
SELECT * FROM
if(condition="Chromium_Browser_Notifications_Site Engagements" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Notifications_App_Banners
notebook:
- type: none
output: "Chromium_Browser_Notifications_App Banners - Recalculate to view results"
template: |
/*
# Chromium_Browser_Notifications_App Banners
*/
SELECT * FROM source(source="Chromium_Browser_Notifications_App Banners")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Chromium_Browser_Notifications_App Banners")
LET JSON = SELECT parse_json(data=read_file(filename=OSPath)) AS Data, OSPath FROM Rows
LET Output = SELECT * FROM foreach(row={
SELECT OSPath, Data.profile.content_settings.exceptions AS exceptions FROM JSON
}, query={
SELECT _key AS Site,
timestamp(winfiletime=int(int=_value.last_modified) * 10 || 0) AS LastModified,
{
SELECT _key AS Site,
timestamp(winfiletime=int(int=_value.couldShowBannerEvents) * 10 || 0) AS CouldShowBannerEvents,
timestamp(winfiletime=int(int=_value.next_install_text_animation.last_shown) * 10 || 0) AS LastShown
FROM items(item=_value.setting)
} AS Setting,
OSPath
FROM items(item=exceptions.app_banner)
})
SELECT * FROM
if(condition="Chromium_Browser_Notifications_App Banners" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Notifications_Notification_Preferences
notebook:
- type: none
output: "Chromium_Browser_Notifications_Notification Preferences - Recalculate to view results"
template: |
/*
# Chromium_Browser_Notifications_Notification Preferences
*/
SELECT * FROM source(source="Chromium_Browser_Notifications_Notification Preferences")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Chromium_Browser_Notifications_Notification Preferences")
LET ContentSettings <= array(`0`="Default",`1`="Allow",`2`="Block",`3`="Ask",`4`="Session Only",`5`="Detect Important Content")
LET JSON = SELECT parse_json(data=read_file(filename=OSPath)) AS Data, OSPath FROM Rows
LET Output = SELECT * FROM foreach(row={
SELECT OSPath, Data.profile.content_settings.exceptions AS exceptions FROM JSON
}, query={
SELECT _key AS Site,
timestamp(winfiletime=int(int=_value.last_modified) * 10 || 0) AS LastModified,
ContentSettings[_value.setting] AS Setting,
OSPath
FROM items(item=exceptions.notifications)
})
SELECT * FROM
if(condition="Chromium_Browser_Notifications_Notification Preferences" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Notifications_Notification_Interactions
notebook:
- type: none
output: "Chromium_Browser_Notifications_Notification Interactions - Recalculate to view results"
template: |
/*
# Chromium_Browser_Notifications_Notification Interactions
*/
SELECT * FROM source(source="Chromium_Browser_Notifications_Notification Interactions")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Chromium_Browser_Notifications_Notification Interactions")
LET JSON = SELECT parse_json(data=read_file(filename=OSPath)) AS Data, OSPath FROM Rows
LET S = scope()
LET Output = SELECT * FROM foreach(row={
SELECT OSPath, Data.profile.content_settings.exceptions AS exceptions FROM JSON
}, query={
SELECT _key AS URL,
timestamp(winfiletime=int(int=_value.last_modified) * 10 || 0) AS LastModified,
_value.display_count as DisplayCount,
_value.click_count as ClickCount,
OSPath
FROM items(item=S.notification_interactions || dict())
})
SELECT * FROM
if(condition="Chromium_Browser_Notifications_Notification Interactions" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Shortcuts
notebook:
- type: none
output: "Chromium_Browser_Shortcuts - Recalculate to view results"
template: |
/*
# Chromium_Browser_Shortcuts
*/
SELECT * FROM source(source="Chromium_Browser_Shortcuts")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Shortcuts")
LET Output = SELECT ID,
timestamp(winfiletime= (last_access_time * 10) || 0) AS LastAccessTime,
TextTyped, FillIntoEdit, URL, Contents,
Description, Type, Keyword, TimesSelectedByUser, OSPath
FROM Rows
WHERE LastAccessTime > DateAfter AND LastAccessTime < DateBefore
AND (Contents, Description) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Browser_Shortcuts" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Sessions_Sessions
notebook:
- type: none
output: "Chromium_Sessions_Sessions - Recalculate to view results"
template: |
/*
# Chromium_Sessions_Sessions
*/
SELECT * FROM source(source="Chromium_Sessions_Sessions")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Sessions_Sessions")
LET Output = SELECT timestamp(winfiletime=(creation_utc * 10) || 0) AS CreationUTC,
timestamp(winfiletime=(expires_utc * 10) || 0) AS ExpiresUTC,
timestamp(winfiletime=(last_access_utc * 10) || 0) AS LastAccessUTC,
HostKey, Name, Path,
Bool(Value=is_secure) AS IsSecure,
Bool(Value=is_httponly) AS IsHttpOnly,
Bool(Value=has_expires) AS HasExpiration,
Bool(Value=is_persistent) AS IsPersistent,
Priority, SourcePort, OSPath
FROM Rows
WHERE LastAccessUTC > DateAfter AND LastAccessUTC < DateBefore
AND (Name, Path) =~ FilterRegex
SELECT * FROM
if(condition="Chromium_Sessions_Sessions" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Chromium_Browser_Top_Sites
notebook:
- type: none
output: "Chromium_Browser_Top_Sites - Recalculate to view results"
template: |
/*
# Chromium_Browser_Top_Sites
*/
SELECT * FROM source(source="Chromium_Browser_Top_Sites")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium_Browser_Top_Sites")
LET Output = SELECT * FROM Rows
WHERE ( URL =~ FilterRegex OR Title =~ FilterRegex )
SELECT * FROM
if(condition="Chromium_Browser_Top_Sites" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Edge_Browser_Autofill_CombinedAutofill
notebook:
- type: none
output: "Edge_Browser_Autofill_CombinedAutofill - Recalculate to view results"
template: |
/*
# Edge_Browser_Autofill_CombinedAutofill
*/
SELECT * FROM source(source="Edge_Browser_Autofill_CombinedAutofill")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Edge_Browser_Autofill_CombinedAutofill")
LET Output = SELECT timestamp(epoch=date_last_used) AS DateLastUsed, *
FROM Rows
WHERE DateLastUsed > DateAfter AND DateLastUsed < DateBefore
SELECT * FROM
if(condition="Edge_Browser_Autofill_CombinedAutofill" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Edge_Browser_Collections_Collections__Items__and_Comments
notebook:
- type: none
output: "Edge_Browser_Collections_Collections, Items, and Comments - Recalculate to view results"
template: |
/*
# Edge_Browser_Collections_Collections, Items, and Comments
*/
SELECT * FROM source(source="Edge_Browser_Collections_Collections, Items, and Comments")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Edge_Browser_Collections_Collections, Items, and Comments")
LET ExtractImage(Data) = base64decode(
string=split(string=parse_json(data=Data).image, sep=",")[1])
LET Output = SELECT *,
timestamp(epoch=Collection_CreationUTC) AS Collection_CreationUTC,
timestamp(epoch=Collection_ModifiedUTC) AS Collection_ModifiedUTC,
timestamp(epoch=ColletionSync_DateLastSynced) AS ColletionSync_DateLastSynced,
timestamp(epoch=Item_CreationUTC) AS Item_CreationUTC,
timestamp(epoch=Item_ModifiedUTC) AS Item_ModifiedUTC,
parse_json(data= Item_Source) AS Item_Source,
upload(accessor="data",
file=ExtractImage(Data=Image),
name=format(format="Screenshot_%v.png", args=item_id)) AS Image,
timestamp(epoch=ItemSync_DaeLastSynced) AS ItemSync_DaeLastSynced
FROM Rows
SELECT * FROM
if(condition="Edge_Browser_Collections_Collections, Items, and Comments" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Edge_Browser_Navigation_History_Navigation_History
notebook:
- type: none
output: "Edge_Browser_Navigation_History_Navigation History - Recalculate to view results"
template: |
/*
# Edge_Browser_Navigation_History_Navigation History
*/
SELECT * FROM source(source="Edge_Browser_Navigation_History_Navigation History")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Edge_Browser_Navigation_History_Navigation History")
LET Output = SELECT ID,
timestamp(epoch=`Last Visited Time`) AS `Last Visited Time`,
Title, URL, VisitCount, OSPath
FROM Rows
WHERE `Last Visited Time` > DateAfter
AND `Last Visited Time` < DateBefore
AND (Title, URL) =~ FilterRegex
SELECT * FROM
if(condition="Edge_Browser_Navigation_History_Navigation History" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Edge_Browser_History_Screenshots_Screenshots
notebook:
- type: none
output: "Edge_Browser_History_Screenshots_Screenshots - Recalculate to view results"
template: |
/*
# Edge_Browser_History_Screenshots_Screenshots
*/
SELECT * FROM source(source="Edge_Browser_History_Screenshots_Screenshots")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Edge_Browser_History_Screenshots_Screenshots")
LET Output = SELECT *,
timestamp(winfiletime=VisitTime * 10) AS VisitTime,
VisitTime AS VisitTimeInt,
upload(accessor="data",
file=Image,
name=format(format="Screenshot_%v.png", args=VisitID)) AS Image
FROM Rows
SELECT * FROM
if(condition="Edge_Browser_History_Screenshots_Screenshots" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Places_Bookmarks
notebook:
- type: none
output: "Firefox_Places_Bookmarks - Recalculate to view results"
template: |
/*
# Firefox_Places_Bookmarks
*/
SELECT * FROM source(source="Firefox_Places_Bookmarks")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Places_Bookmarks")
LET BookmarkTypes <= dict(`1`='URL', `2`='Folder', `3`='Separator')
LET Output = SELECT ID, ParentID,
get(item= BookmarkTypes, field=str(str=type), default="Unknown") AS Type,
timestamp(epoch=dateAdded) AS DateAdded,
timestamp(epoch=lastModified) AS LastModified,
Position, Title, URL, ForeignKey, OSPath
FROM Rows
WHERE LastModified > DateAfter AND LastModified < DateBefore
AND (Title, URL) =~ FilterRegex
SELECT * FROM
if(condition="Firefox_Places_Bookmarks" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Places_Downloads
notebook:
- type: none
output: "Firefox_Places_Downloads - Recalculate to view results"
template: |
/*
# Firefox_Places_Downloads
*/
SELECT * FROM source(source="Firefox_Places_Downloads")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Places_Downloads")
LET DownloadTypes <= dict(`downloads/destinationFileURI`='FileURI', `downloads/destinationFileName`='Filename', `downloads/metaData`='Metadata')
LET Output = SELECT PlaceID, URL, Content,
get(item= DownloadTypes, field=str(str=name), default="Unknown") AS Type,
timestamp(epoch=dateAdded) AS DateAdded,
timestamp(epoch=lastModified) AS LastModified,
OSPath
FROM Rows
WHERE LastModified > DateAfter AND LastModified < DateBefore
AND (URL, Content) =~ FilterRegex
SELECT * FROM
if(condition="Firefox_Places_Downloads" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Cookies
notebook:
- type: none
output: "Firefox_Cookies - Recalculate to view results"
template: |
/*
# Firefox_Cookies
*/
SELECT * FROM source(source="Firefox_Cookies")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Cookies")
LET Output = SELECT ID, Host, Name, Value,
timestamp(epoch= creationTime) AS CreationTime,
timestamp(epoch= lastAccessed) AS LastAccessedTime,
timestamp(epoch= expiry) AS Expiration,
Bool(Value= isSecure) AS IsSecure,
Bool(Value= isHttpOnly) AS IsHTTPOnly, OSPath
FROM Rows
WHERE LastAccessedTime > DateAfter
AND LastAccessedTime < DateBefore
AND ( Name =~ FilterRegex OR Value =~ FilterRegex )
SELECT * FROM
if(condition="Firefox_Cookies" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Downloads
notebook:
- type: none
output: "Firefox_Downloads - Recalculate to view results"
template: |
/*
# Firefox_Downloads
*/
SELECT * FROM source(source="Firefox_Downloads")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Downloads")
LET Output = SELECT ID, Name, MIMEType, Source, Target,
timestamp(epoch= startTime) AS StartTime,
timestamp(epoch= endTime) AS EndTime,
timestamp(epoch= expiry) AS Expiration,
CurrentBytes, MaxBytes, OSPath
FROM Rows
WHERE StartTime > DateAfter
AND StartTime < DateBefore
AND Name =~ FilterRegex
SELECT * FROM
if(condition="Firefox_Downloads" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Favicons
notebook:
- type: none
output: "Firefox_Favicons - Recalculate to view results"
template: |
/*
# Firefox_Favicons
*/
SELECT * FROM source(source="Firefox_Favicons")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Favicons")
LET Output = SELECT ID, PageURL, FaviconURL,
timestamp(epoch= expire_ms) AS Expiration,
OSPath
FROM Rows
SELECT * FROM
if(condition="Firefox_Favicons" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Form_History
notebook:
- type: none
output: "Firefox_Form_History - Recalculate to view results"
template: |
/*
# Firefox_Form_History
*/
SELECT * FROM source(source="Firefox_Form_History")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Form_History")
LET Output = SELECT ID, FieldName, Value, TimesUsed,
timestamp(epoch= firstUsed) AS FirstUsed,
timestamp(epoch= lastUsed) AS LastUsed,
GUID, OSPath
FROM Rows
WHERE LastUsed > DateAfter AND LastUsed < DateBefore
AND ( FieldName =~ FilterRegex OR Value =~ FilterRegex )
SELECT * FROM
if(condition="Firefox_Form_History" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Places_History
notebook:
- type: none
output: "Firefox_Places_History - Recalculate to view results"
template: |
/*
# Firefox_Places_History
*/
SELECT * FROM source(source="Firefox_Places_History")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Places_History")
LET VisitType <= dict(`1`='TRANSITION_LINK', `2`='TRANSITION_TYPED', `3`='TRANSITION_BOOKMARK',
`4`='TRANSITION_EMBED', `5`= 'TRANSITION_REDIRECT_PERMANENT', `6`='TRANSITION_REDIRECT_TEMPORARY',
`7`='TRANSITION_DOWNLOAD', `8`='TRANSITION_FRAMED_LINK', `9`='TRANSITION_RELOAD')
LET Output = SELECT VisitID, FromVisitID, PlaceID,
timestamp(epoch= visit_date) AS VisitDate,
timestamp(epoch= last_visit_date) AS LastVisitDate,
VisitCount, URL, Title, Description,
get(item= VisitType, field=str(str=visit_type), default="Unknown") AS VisitType,
Bool(Value=hidden) AS Hidden,
Bool(Value=typed) AS Typed,
Frecency, PreviewImageURL, OSPath
FROM Rows
WHERE VisitDate > DateAfter AND VisitDate < DateBefore
AND (Title, URL, Description) =~ FilterRegex
SELECT * FROM
if(condition="Firefox_Places_History" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Firefox_Places_History_Legacy
notebook:
- type: none
output: "Firefox_Places_History_Legacy - Recalculate to view results"
template: |
/*
# Firefox_Places_History_Legacy
*/
SELECT * FROM source(source="Firefox_Places_History_Legacy")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox_Places_History_Legacy")
LET VisitType <= dict(`1`='TRANSITION_LINK', `2`='TRANSITION_TYPED', `3`='TRANSITION_BOOKMARK',
`4`='TRANSITION_EMBED', `5`= 'TRANSITION_REDIRECT_PERMANENT', `6`='TRANSITION_REDIRECT_TEMPORARY',
`7`='TRANSITION_DOWNLOAD', `8`='TRANSITION_FRAMED_LINK', `9`='TRANSITION_RELOAD')
LET Output = SELECT VisitID, FromVisitID, PlaceID,
timestamp(epoch= visit_date) AS VisitDate,
timestamp(epoch= last_visit_date) AS LastVisitDate,
VisitCount, URL, Title,
get(item= VisitType, field=str(str=visit_type), default="Unknown") AS VisitType,
Bool(Value=hidden) AS Hidden,
Bool(Value=typed) AS Typed,
Frecency, OSPath
FROM Rows
WHERE VisitDate > DateAfter AND VisitDate < DateBefore
AND (Title, URL) =~ FilterRegex
SELECT * FROM
if(condition="Firefox_Places_History_Legacy" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Google_Drive_Metadata_File_Metadata
notebook:
- type: none
output: "Google_Drive_Metadata_File Metadata - Recalculate to view results"
template: |
/*
# Google_Drive_Metadata_File Metadata
*/
SELECT * FROM source(source="Google_Drive_Metadata_File Metadata")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Google_Drive_Metadata_File Metadata")
LET Output = SELECT timestamp(epoch=modified_date ) AS Timestamp, *
FROM Rows
WHERE
if(condition=DateAfter, then=Timestamp > DateAfter, else=TRUE) AND
if(condition=DateBefore, then=Timestamp < DateBefore, else=TRUE) AND
(local_title, mime_type) =~ FilterRegex
SELECT * FROM
if(condition="Google_Drive_Metadata_File Metadata" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Google_Drive_Metadata_Deleted_Items
notebook:
- type: none
output: "Google_Drive_Metadata_Deleted Items - Recalculate to view results"
template: |
/*
# Google_Drive_Metadata_Deleted Items
*/
SELECT * FROM source(source="Google_Drive_Metadata_Deleted Items")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Google_Drive_Metadata_Deleted Items")
LET Output = SELECT * FROM Rows
SELECT * FROM
if(condition="Google_Drive_Metadata_Deleted Items" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Google_Drive_Mirrored_Files_Mirrored_Items
notebook:
- type: none
output: "Google_Drive_Mirrored_Files_Mirrored Items - Recalculate to view results"
template: |
/*
# Google_Drive_Mirrored_Files_Mirrored Items
*/
SELECT * FROM source(source="Google_Drive_Mirrored_Files_Mirrored Items")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Google_Drive_Mirrored_Files_Mirrored Items")
LET Output = SELECT timestamp(epoch=local_mtime_ms ) AS Timestamp, *
FROM Rows
WHERE
if(condition=DateAfter, then=Timestamp > DateAfter, else=TRUE) AND
if(condition=DateBefore, then=Timestamp < DateBefore, else=TRUE) AND
(local_filename, cloud_filename, volume) =~ FilterRegex
SELECT * FROM
if(condition="Google_Drive_Mirrored_Files_Mirrored Items" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Google_Drive_Mirrored_Metadata_Files_Mirrored_Metadata_Items
notebook:
- type: none
output: "Google_Drive_Mirrored_Metadata_Files_Mirrored Metadata Items - Recalculate to view results"
template: |
/*
# Google_Drive_Mirrored_Metadata_Files_Mirrored Metadata Items
*/
SELECT * FROM source(source="Google_Drive_Mirrored_Metadata_Files_Mirrored Metadata Items")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Google_Drive_Mirrored_Metadata_Files_Mirrored Metadata Items")
LET Output = SELECT timestamp(epoch=modified_date ) AS Timestamp, *
FROM Rows
WHERE
if(condition=DateAfter, then=Timestamp > DateAfter, else=TRUE) AND
if(condition=DateBefore, then=Timestamp < DateBefore, else=TRUE) AND
(local_title, mime_type) =~ FilterRegex
SELECT * FROM
if(condition="Google_Drive_Mirrored_Metadata_Files_Mirrored Metadata Items" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Google_Drive_Sync_Roots_Sync_Folders
notebook:
- type: none
output: "Google_Drive_Sync_Roots_Sync Folders - Recalculate to view results"
template: |
/*
# Google_Drive_Sync_Roots_Sync Folders
*/
SELECT * FROM source(source="Google_Drive_Sync_Roots_Sync Folders")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Google_Drive_Sync_Roots_Sync Folders")
LET Output = SELECT *
FROM Rows
WHERE (root_path, title, media_id) =~ FilterRegex
SELECT * FROM
if(condition="Google_Drive_Sync_Roots_Sync Folders" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: IE_or_Edge_WebCacheV01_All_Data
notebook:
- type: none
output: "IE_or_Edge_WebCacheV01_All Data - Recalculate to view results"
template: |
/*
# IE_or_Edge_WebCacheV01_All Data
*/
SELECT * FROM source(source="IE_or_Edge_WebCacheV01_All Data")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="IE_or_Edge_WebCacheV01_All Data")
LET MatchingFiles = SELECT OSPath FROM Rows
LET S = scope()
LET Containers(OSPath) = SELECT Table
FROM parse_ese_catalog(file=OSPath)
WHERE Table =~ "Container_"
GROUP BY Table
LET AllHits(OSPath) = SELECT * FROM foreach(row={
SELECT * FROM Containers(OSPath=OSPath)
}, query={
SELECT timestamp(winfiletime=ExpiryTime) AS ExpiryTime,
timestamp(winfiletime=ModifiedTime) AS ModifiedTime,
timestamp(winfiletime=AccessedTime) AS AccessedTime,
S.Url AS Url, *
FROM parse_ese(file=OSPath, table=Table)
})
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT * FROM AllHits(OSPath=OSPath)
})
WHERE AccessedTime > DateAfter AND AccessedTime < DateBefore
AND Url =~ FilterRegex
SELECT * FROM
if(condition="IE_or_Edge_WebCacheV01_All Data" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: IE_or_Edge_WebCacheV01_Highlights
notebook:
- type: none
output: "IE_or_Edge_WebCacheV01_Highlights - Recalculate to view results"
template: |
/*
# IE_or_Edge_WebCacheV01_Highlights
*/
SELECT * FROM source(source="IE_or_Edge_WebCacheV01_Highlights")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="IE_or_Edge_WebCacheV01_Highlights")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT AccessedTime, ModifiedTime, ExpiryTime, Url
FROM AllHits(OSPath=OSPath)
})
WHERE AccessedTime > DateAfter AND AccessedTime < DateBefore
AND Url =~ FilterRegex
SELECT * FROM
if(condition="IE_or_Edge_WebCacheV01_Highlights" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: MacOS_Applications_Cache
notebook:
- type: none
output: "MacOS_Applications_Cache - Recalculate to view results"
template: |
/*
# MacOS_Applications_Cache
*/
SELECT * FROM source(source="MacOS_Applications_Cache")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS_Applications_Cache")
// linter: symbol_mask_warn:version
LET Output = SELECT
time_stamp AS Timestamp,
OSPath.Base AS Application,
entry_ID AS EntryID,
version AS Version,
hash_value AS Hash,
storage_policy AS StoragePolicy,
request_key AS URL,
plist(file=request_object, accessor="data") AS Request,
plist(file=response_object, accessor="data") AS Response,
partition AS Partition,
OSPath
FROM Rows
WHERE Timestamp > DateAfter AND Timestamp < DateBefore
AND Application =~ FilterRegex
SELECT * FROM
if(condition="MacOS_Applications_Cache" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: MacOS_NetworkUsage
notebook:
- type: none
output: "MacOS_NetworkUsage - Recalculate to view results"
template: |
/*
# MacOS_NetworkUsage
*/
SELECT * FROM source(source="MacOS_NetworkUsage")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS_NetworkUsage")
LET Output = SELECT timestamp(epoch= ZTIMESTAMP + 978307200) AS Timestamp,
timestamp(epoch= ZFIRSTTIMESTAMP + 978307200) AS FirstTimestamp,
timestamp(epoch= LIVE_USAGE_TIMESTAMP + 978307200) AS LiveUsageTimestamp,
ZBUNDLENAME AS BundleID,
ZPROCNAME AS ProcessName,
ZWIFIIN AS WifiIn,
ZWIFIOUT AS WifiOut,
ZWWANIN AS WanIn,
ZWWANOUT AS WandOut,
ZWIREDIN AS WiredIn,
ZWIREDOUT AS WiredOut,
ZXIN AS _XIn,
ZXOUT AS _XOut,
Z_PK AS LiveUsageTableID
FROM Rows
SELECT * FROM
if(condition="MacOS_NetworkUsage" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: MacOS_Notes
notebook:
- type: none
output: "MacOS_Notes - Recalculate to view results"
template: |
/*
# MacOS_Notes
*/
SELECT * FROM source(source="MacOS_Notes")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS_Notes")
LET Output = SELECT Key AS _Key,
OSPath[1] AS User,
Note,
Title,
Snippet,
NoteID AS _NoteID,
timestamp(cocoatime=CreatedTS) AS CreatedTime,
timestamp(cocoatime=LastOpenedDate) AS LastOpenedTime,
timestamp(cocoatime=DirModificationDate) AS LastDirModifcation,
Account AS _Account,
Directory,
DirectoryID,
AttachmentName,
AttachmentSize,
AttachmentUUID,
if(condition=AttachmentUUID,
then=OSPath[:2] + '/Library/Group Containers/group.com.apple.notes/Accounts/LocalAccount/Media/' + AttachmentUUID + '/' + AttachmentName) AS AttachmentLocation,
AccountName AS _AccountName,
AccountID AS _AccountID,
AccountType AS _AccountType,
gunzip(string=Data) AS Data,
OSPath
FROM Rows
WHERE LastOpenedTime > DateAfter AND LastOpenedTime < DateBefore
AND ( Title =~ FilterRegex OR Data =~ FilterRegex )
SELECT * FROM
if(condition="MacOS_Notes" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: MacOS_XProtect_Detections
notebook:
- type: none
output: "MacOS_XProtect_Detections - Recalculate to view results"
template: |
/*
# MacOS_XProtect_Detections
*/
SELECT * FROM source(source="MacOS_XProtect_Detections")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS_XProtect_Detections")
LET Output = SELECT *
FROM Rows
WHERE dt > DateAfter
AND dt < DateBefore
AND (violated_rule, exec_path, responsible_path, responsible_signing_id,
exec_cdhash, exec_sha256, responsible_cdhash, responsible_sha256 ) =~ FilterRegex
SELECT * FROM
if(condition="MacOS_XProtect_Detections" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Activities_Cache_ActivityPackageId
notebook:
- type: none
output: "Windows_Activities_Cache_ActivityPackageId - Recalculate to view results"
template: |
/*
# Windows_Activities_Cache_ActivityPackageId
*/
SELECT * FROM source(source="Windows_Activities_Cache_ActivityPackageId")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Windows_Activities_Cache_ActivityPackageId")
LET Output = SELECT format(format="%0X-%0X-%0X-%0X-%0X", args=[
ActivityId[0:4], ActivityId[4:6], ActivityId[6:8],
ActivityId[8:10], ActivityId[10:] ]) AS ActivityId,
Platform, PackageName, ExpirationTime, OSPath
FROM Rows
SELECT * FROM
if(condition="Windows_Activities_Cache_ActivityPackageId" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Activities_Cache_Clipboard
notebook:
- type: none
output: "Windows_Activities_Cache_Clipboard - Recalculate to view results"
template: |
/*
# Windows_Activities_Cache_Clipboard
*/
SELECT * FROM source(source="Windows_Activities_Cache_Clipboard")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Windows_Activities_Cache_Clipboard")
LET Output = SELECT
CreatedTime,
timestamp(epoch=LastModifiedTime) AS LastModifiedTime,
timestamp(epoch=LastModifiedOnClient) AS LastModifiedOnClient,
StartTime,
EndTime,
Payload,
OSPath[1] AS User,
base64decode(string=parse_json_array(data=ClipboardPayload || '[]')[0].content) AS ClipboardPayload,
OSPath AS Path,
Mtime
FROM Rows
WHERE StartTime > DateAfter
AND StartTime < DateBefore
AND ClipboardPayload =~ FilterRegex
SELECT * FROM
if(condition="Windows_Activities_Cache_Clipboard" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_WPNDatabase___Notifications_Notifications
notebook:
- type: none
output: "Windows_WPNDatabase___Notifications_Notifications - Recalculate to view results"
template: |
/*
# Windows_WPNDatabase___Notifications_Notifications
*/
SELECT * FROM source(source="Windows_WPNDatabase___Notifications_Notifications")
LIMIT 50
query: |
LET Rows = SELECT * FROM ApplyFile(SourceName="Windows_WPNDatabase___Notifications_Notifications")
LET Output = SELECT *, Parent || "" AS Parent,
timestamp(winfiletime= ArrivalTime) AS ArrivalTime,
if(condition= ExpirationTime > 0,
then=timestamp(winfiletime= ExpirationTime),
else='Expired') AS ExpirationTime,
format(format="%02x", args=ActivityId) As ActivityId,
WNSId || "" AS WNSId,
if(condition= WNSCreatedTime > 0,
then=timestamp(winfiletime= WNSCreatedTime),
else='') AS WNSCreatedTime,
if(condition= WNSExpirationTime > 0,
then=timestamp(winfiletime= WNSExpirationTime),
else='') AS WNSExpirationTime,
upload(accessor="data",
file=Payload,
name=format(format="Payload%v.png", args=ID)) AS Payload
FROM Rows
SELECT * FROM
if(condition="Windows_WPNDatabase___Notifications_Notifications" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Search_Service_SystemIndex_Gthr
notebook:
- type: none
output: "Windows_Search_Service_SystemIndex_Gthr - Recalculate to view results"
template: |
/*
# Windows_Search_Service_SystemIndex_Gthr
*/
SELECT * FROM source(source="Windows_Search_Service_SystemIndex_Gthr")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Windows_Search_Service_SystemIndex_Gthr")
LET MatchingFiles = SELECT OSPath FROM Rows
LET FormatTimeB(T) = timestamp(winfiletime=parse_binary(
filename=T, accessor="data", struct="uint64b"))
LET FormatTime(T) = timestamp(winfiletime=parse_binary(
filename=T, accessor="data", struct="uint64"))
LET FormatSize(T) = parse_binary(
filename=T, accessor="data", struct="uint64")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT ScopeID, DocumentID, SDID,
FormatTimeB(T=LastModified) AS LastModified,
FileName
FROM parse_ese(file=OSPath, table= "SystemIndex_Gthr")
})
WHERE LastModified > DateAfter AND LastModified < DateBefore
AND FileName =~ FilterRegex
SELECT * FROM
if(condition="Windows_Search_Service_SystemIndex_Gthr" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Search_Service_SystemIndex_GthrPth
notebook:
- type: none
output: "Windows_Search_Service_SystemIndex_GthrPth - Recalculate to view results"
template: |
/*
# Windows_Search_Service_SystemIndex_GthrPth
*/
SELECT * FROM source(source="Windows_Search_Service_SystemIndex_GthrPth")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Windows_Search_Service_SystemIndex_GthrPth")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT Scope, Parent, Name
FROM parse_ese(file=OSPath, table= "SystemIndex_GthrPth")
})
WHERE Name =~ FilterRegex
SELECT * FROM
if(condition="Windows_Search_Service_SystemIndex_GthrPth" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Search_Service_SystemIndex_PropertyStore
notebook:
- type: none
output: "Windows_Search_Service_SystemIndex_PropertyStore - Recalculate to view results"
template: |
/*
# Windows_Search_Service_SystemIndex_PropertyStore
*/
SELECT * FROM source(source="Windows_Search_Service_SystemIndex_PropertyStore")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Windows_Search_Service_SystemIndex_PropertyStore")
LET X = scope()
-- The PropertyStore columns look like
-- <random>-ProperName so we strip the
-- random part off to display it properly.
LET FilterDict(Dict) = to_dict(item={
SELECT split(sep_string="-", string=_key)[1] || _key AS _key, _value
FROM items(item=Dict)
})
LET PropStore(OSPath) = SELECT *,
FormatTime(T=X.System_Search_GatherTime) AS System_Search_GatherTime,
FormatSize(T=X.System_Size) AS System_Size,
FormatTime(T=X.System_DateModified) AS System_DateModified,
FormatTime(T=X.System_DateAccessed) AS System_DateAccessed,
FormatTime(T=X.System_DateCreated) AS System_DateCreated
FROM foreach(row={
SELECT *, FilterDict(Dict=_value) AS _value
FROM items(item={
SELECT * FROM parse_ese(file=OSPath, table="SystemIndex_PropertyStore")
})
}, column="_value")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT *
FROM PropStore(OSPath=OSPath)
})
WHERE System_DateAccessed > DateAfter AND System_DateAccessed < DateBefore
SELECT * FROM
if(condition="Windows_Search_Service_SystemIndex_PropertyStore" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Search_Service_SystemIndex_PropertyStore_Highlights
notebook:
- type: none
output: "Windows_Search_Service_SystemIndex_PropertyStore_Highlights - Recalculate to view results"
template: |
/*
# Windows_Search_Service_SystemIndex_PropertyStore_Highlights
*/
SELECT * FROM source(source="Windows_Search_Service_SystemIndex_PropertyStore_Highlights")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Windows_Search_Service_SystemIndex_PropertyStore_Highlights")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT WorkID,
System_Search_GatherTime,
System_Size,
System_DateModified,
System_DateCreated,
X.System_FileOwner AS System_FileOwner,
X.System_ItemPathDisplay AS System_ItemPathDisplay,
X.System_ItemType AS System_ItemType,
X.System_FileAttributes AS System_FileAttributes,
X.System_Search_AutoSummary AS System_Search_AutoSummary
FROM PropStore(OSPath=OSPath)
})
WHERE System_DateAccessed > DateAfter AND System_DateAccessed < DateBefore
SELECT * FROM
if(condition="Windows_Search_Service_SystemIndex_PropertyStore_Highlights" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Search_Service_BrowsingActivity
notebook:
- type: none
output: "Windows_Search_Service_BrowsingActivity - Recalculate to view results"
template: |
/*
# Windows_Search_Service_BrowsingActivity
*/
SELECT * FROM source(source="Windows_Search_Service_BrowsingActivity")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Windows_Search_Service_BrowsingActivity")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT X.ItemPathDisplay AS ItemPathDisplay,
X.Activity_ContentUri AS Activity_ContentUri,
X.Activity_Description AS Activity_Description
FROM PropStore(OSPath=OSPath)
WHERE Activity_ContentUri
})
SELECT * FROM
if(condition="Windows_Search_Service_BrowsingActivity" =~ RuleFilter, then={
SELECT * FROM Output
})
- name: Windows_Search_Service_UserActivityLogging
notebook:
- type: none
output: "Windows_Search_Service_UserActivityLogging - Recalculate to view results"
template: |
/*
# Windows_Search_Service_UserActivityLogging
*/
SELECT * FROM source(source="Windows_Search_Service_UserActivityLogging")
LIMIT 50
query: |
LET Rows = SELECT * FROM FilterFile(SourceName="Windows_Search_Service_UserActivityLogging")
LET Output = SELECT * FROM foreach(row=MatchingFiles, query={
SELECT X.System_ItemPathDisplay AS System_ItemPathDisplay,
FormatTime(T=X.ActivityHistory_StartTime) AS ActivityHistory_StartTime,
FormatTime(T=X.ActivityHistory_EndTime) AS ActivityHistory_EndTime,
X.ActivityHistory_AppId AS ActivityHistory_AppId
FROM PropStore(OSPath=OSPath)
WHERE ActivityHistory_AppId
})
WHERE ActivityHistory_StartTime > DateAfter
AND ActivityHistory_StartTime < DateBefore
SELECT * FROM
if(condition="Windows_Search_Service_UserActivityLogging" =~ RuleFilter, then={
SELECT * FROM Output
})
docs/../static/artifact/SQLiteHunter.yaml