Windows.Events.TrackProcesses.UseExistingSysmonOnly

This is a modified version of Windows.Events.TrackProcesses for servers that do not use the Inventory service. It assumes that Sysmon is already installed and running. The option to forward updates to the server is also removed.

This artifact uses sysmon and pslist to keep track of running processes using the Velociraptor process tracker.

The Process Tracker keeps track of exited processes, and resolves process callchains from it in memory cache.

This event artifact enables the global process tracker and makes it possible to run many other artifacts that depend on the process tracker.


name: Windows.Events.TrackProcesses.UseExistingSysmonOnly
description: |
  **This is a modified version of Windows.Events.TrackProcesses for servers
  that do not use the Inventory service.  It assumes that Sysmon
  is already installed and running. The option to forward updates to the server
  is also removed.**
  
  This artifact uses sysmon and pslist to keep track of running
  processes using the Velociraptor process tracker.

  The Process Tracker keeps track of exited processes, and resolves
  process callchains from it in memory cache.

  This event artifact enables the global process tracker and makes it
  possible to run many other artifacts that depend on the process
  tracker.

type: CLIENT_EVENT

parameters:
  - name: MaxSize
    type: int64
    description: Maximum size of the in memory process cache (default 10k)

  - name: AddEnrichments
    type: bool
    description: Add process information enrichments (can use more resources)

sources:
  - precondition:
      SELECT OS From info() where OS = 'windows'

    query: |
      LET UpdateQuery =
            SELECT * FROM foreach(row={
              SELECT *,
                     get(member='EventData') AS EventData
              FROM watch_etw(guid='{5770385f-c22a-43e0-bf4c-06f5698ffbd9}')
            }, query={
              SELECT * FROM switch(
              start={
                SELECT EventData.ProcessId AS id,
                       EventData.ParentProcessId AS parent_id,
                       "start" AS update_type,

                       -- We need to manually build the dict here so
                       -- we can maintain column ordering.
                       dict(
                           Pid=EventData.ProcessId,
                           Ppid=EventData.ParentProcessId,
                           Name=split(sep_string="\\", string=EventData.Image)[-1],
                           StartTime=EventData.UtcTime,
                           EndTime=NULL,
                           Username=EventData.User,
                           Exe=EventData.Image,
                           CommandLine= EventData.CommandLine,
                           CurrentDirectory= EventData.CurrentDirectory,
                           FileVersion=EventData.FileVersion,
                           Description= EventData.Description,
                           Company= EventData.Company,
                           Product= EventData.Product,
                           ParentImage= EventData.ParentImage,
                           ParentCommandLine= EventData.ParentCommandLine,
                           TerminalSessionId= EventData.TerminalSessionId,
                           IntegrityLevel= EventData.IntegrityLevel,
                           Hashes=parse_string_with_regex(regex=[
                             "SHA256=(?P<SHA256>[^,]+)",
                             "MD5=(?P<MD5>[^,]+)",
                             "IMPHASH=(?P<IMPHASH>[^,]+)"],
                           string=EventData.Hashes)
                       ) AS data,
                       EventData.UtcTime AS start_time,
                       NULL AS end_time
                FROM scope()
                WHERE System.ID = 1
              },
              end={
                SELECT EventData.ProcessId AS id,
                       NULL AS parent_id,
                       "exit" AS update_type,
                       dict() AS data,
                       NULL AS start_time,
                       EventData.UtcTime AS end_time
                FROM scope()
                WHERE System.ID = 5
              })
            })

      LET SyncQuery =
              SELECT Pid AS id,
                 Ppid AS parent_id,
                 CreateTime AS start_time,
                 dict(
                   Name=Name,
                   Username=Username,
                   Exe=Exe,
                   CommandLine=CommandLine) AS data
              FROM pslist()

      LET Tracker <= process_tracker(
         enrichments=if(condition=AddEnrichments, then=[
           '''x=>if(
                condition=NOT x.Data.VersionInformation AND x.Data.Image,
                then=dict(VersionInformation=parse_pe(file=x.Data.Image).VersionInformation))
           ''',
           '''x=>if(
                condition=NOT x.Data.OriginalFilename OR x.Data.OriginalFilename = '-',
                then=dict(OriginalFilename=x.Data.VersionInformation.OriginalFilename))
           '''], else=[]),
        sync_query=SyncQuery, update_query=UpdateQuery, sync_period=60000)

      SELECT * FROM process_tracker_updates()
      WHERE update_type = "stats"