Generic.Forensic.SQLiteHunter

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).



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

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 _value FROM foreach(row=["All","MacOS","Chrome","Browser","Edge","Firefox","InternetExplorer","Windows"]) WHERE get(field=_value)
  LET category_regex <= join(sep="|", array=all_categories._value)
  LET AllGlobs <= filter(list=Specs.globs, condition="x=> x.tags =~ category_regex")
  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)

parameters:
- name: MatchFilename
  description: |
    If set we use the filename to detect the type of sqlite file.
    When unset we use heristics (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 targets with category All
  type: bool
  default: Y


- name: MacOS
  description: Select targets with category MacOS
  type: bool
  default: N


- name: Chrome
  description: Select targets with category Chrome
  type: bool
  default: N


- name: Browser
  description: Select targets with category Browser
  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: 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
  query: |
    SELECT * FROM AllFiles


- name: iMessage_Profiles
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="iMessage_Profiles")
    SELECT timestamp(epoch=date / 1000000000 + 978307200) AS Timestamp, *
    FROM Rows
    WHERE Timestamp > DateAfter AND Timestamp < DateBefore
      AND (MessageText, RoomName) =~ FilterRegex
    


- name: Chromium Browser Autofill_Profiles
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Autofill_Profiles")
    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
    


- name: Chromium Browser Autofill_Masked Credit Cards
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Autofill_Masked Credit Cards")
    SELECT * FROM Rows


- name: Chromium Browser Bookmarks
  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
    
    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="")
      })
    })
    


- name: Chromium Browser_Cookies
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser_Cookies")
    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
    


- name: Chromium Browser Extensions
  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
    
    -- Find the Locale file to help with.
    LET LocaleData = SELECT *, if(condition=Manifest.default_locale, else=dict(),
         then=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`
    
    SELECT OSPath, Manifest.author.email AS Email,
      ResolveName(Message = Manifest.name, Locale=Locale) AS name,
      ResolveName(Message = Manifest.description, Locale=Locale) AS description,
      Manifest.oauth2.scopes as Scopes,
      Manifest.permissions as Permissions,
      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
    


- name: Chromium Browser Favicons
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Favicons")
    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
    


- name: Chromium Browser History_Visits
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser History_Visits")
    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
    


- name: Chromium Browser History_Downloads
  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')
    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', `20`='Network Error', `21`='Operation Timed Out',
      `22`='Connection Lost', `23`='Server Down', `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')
    
    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
    


- name: Chromium Browser History_Keywords
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser History_Keywords")
    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
    


- name: Chromium Browser Media_History
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Media_History")
    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
    


- name: Chromium Browser Media_Playback Session
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Media_Playback Session")
    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
    


- name: Chromium Browser Network_Predictor
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Network_Predictor")
    SELECT * FROM Rows
    WHERE UserText =~ FilterRegex
    


- name: Chromium Browser Notifications_Site Engagements
  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
    
    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)
    })
    


- name: Chromium Browser Notifications_App Banners
  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
    
    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)
    })
    


- name: Chromium Browser Notifications_Notification Preferences
  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
    
    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)
    })
    


- name: Chromium Browser Notifications_Notification Interactions
  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()
    
    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())
    })
    


- name: Chromium Browser Shortcuts
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Shortcuts")
    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
    


- name: Chromium Sessions_Sessions
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Sessions_Sessions")
    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
    


- name: Chromium Browser Top Sites
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Chromium Browser Top Sites")
    SELECT * FROM Rows
    WHERE ( URL =~ FilterRegex OR Title =~ FilterRegex )
    


- name: Edge Browser Autofill_CombinedAutofill
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Edge Browser Autofill_CombinedAutofill")
    SELECT timestamp(epoch=date_last_used) AS DateLastUsed
    FROM Rows
    WHERE DateLastUsed > DateAfter AND DateLastUsed < DateBefore
    


- name: Edge Browser Navigation History_Navigation History
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Edge Browser Navigation History_Navigation History")
    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
    


- name: Firefox Places
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox Places")
    LET BookmarkTypes <= dict(`1`="URL", `2`="Folder", `3`="Separator")
    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
    


- name: Firefox Places_Downloads
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox Places_Downloads")
    SELECT PlaceID, Content,
       timestamp(epoch=dateAdded) AS DateAdded,
       timestamp(epoch=lastModified) AS LastModified,
       OSPath
    FROM Rows
    WHERE LastModified > DateAfter AND LastModified < DateBefore
      AND Content =~ FilterRegex
    


- name: Firefox Places_History
  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')
    
    SELECT VisitID, FromVisitID,
       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 LastVisitDate > DateAfter AND LastVisitDate < DateBefore
      AND (Title, URL, Description) =~ FilterRegex
    


- name: Firefox Cookies
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox Cookies")
    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 )
    


- name: Firefox Downloads
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox Downloads")
    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
    


- name: Firefox Favicons
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox Favicons")
    SELECT ID, PageURL, FaviconURL,
       timestamp(epoch= expire_ms) AS Expiration,
       OSPath
    FROM Rows
    


- name: Firefox Form History
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Firefox Form History")
    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 )
    


- name: IE or Edge WebCacheV01_All Data
  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)
    })
    
    SELECT * FROM foreach(row=MatchingFiles, query={
      SELECT * FROM AllHits(OSPath=OSPath)
    })
    WHERE AccessedTime > DateAfter AND AccessedTime < DateBefore
      AND Url =~ FilterRegex
    


- name: IE or Edge WebCacheV01_Highlights
  query: |
    LET Rows = SELECT * FROM FilterFile(SourceName="IE or Edge WebCacheV01_Highlights")
    SELECT * FROM foreach(row=MatchingFiles, query={
      SELECT AccessedTime, ModifiedTime, ExpiryTime, Url
      FROM AllHits(OSPath=OSPath)
    })
    WHERE AccessedTime > DateAfter AND AccessedTime < DateBefore
      AND Url =~ FilterRegex
    


- name: MacOS Applications Cache
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS Applications Cache")
    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
    


- name: MacOS NetworkUsage
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS NetworkUsage")
    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
    


- name: MacOS Notes
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS Notes")
    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 )
    


- name: MacOS XProtect Detections
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="MacOS XProtect Detections")
    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
    


- name: Windows Activities Cache_ActivityPackageId
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Windows Activities Cache_ActivityPackageId")
    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
    


- name: Windows Activities Cache_Clipboard
  query: |
    LET Rows = SELECT * FROM ApplyFile(SourceName="Windows Activities Cache_Clipboard")
    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
    


- name: Windows Search Service_SystemIndex_Gthr
  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")
    
    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
    


- name: Windows Search Service_SystemIndex_GthrPth
  query: |
    LET Rows = SELECT * FROM FilterFile(SourceName="Windows Search Service_SystemIndex_GthrPth")
    SELECT * FROM foreach(row=MatchingFiles, query={
       SELECT Scope, Parent, Name
       FROM parse_ese(file=OSPath, table= "SystemIndex_GthrPth")
    })
    WHERE Name =~ FilterRegex
    


- name: Windows Search Service_SystemIndex_PropertyStore
  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")
    
    SELECT * FROM foreach(row=MatchingFiles, query={
       SELECT *
       FROM PropStore(OSPath=OSPath)
    })
    WHERE System_DateAccessed > DateAfter AND System_DateAccessed < DateBefore
    


- name: Windows Search Service_SystemIndex_PropertyStore_Highlights
  query: |
    LET Rows = SELECT * FROM FilterFile(SourceName="Windows Search Service_SystemIndex_PropertyStore_Highlights")
    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
    


- name: Windows Search Service_BrowsingActivity
  query: |
    LET Rows = SELECT * FROM FilterFile(SourceName="Windows Search Service_BrowsingActivity")
    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
    })
    


- name: Windows Search Service_UserActivityLogging
  query: |
    LET Rows = SELECT * FROM FilterFile(SourceName="Windows Search Service_UserActivityLogging")
    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