Windows.EventLogs.LogonSessions

This artifact searches for logon and logoff events within Security event logs identified by Event ID 4624 and 4634. These logon/logoff events are grouped by “TargetLogonId” field into “logon sessions”. For each of these logon sessions, start, end and duration are derived


name: Windows.EventLogs.LogonSessions
description: |
    This artifact searches for logon and logoff events within Security event logs identified
    by Event ID 4624 and 4634. These logon/logoff events are grouped by "TargetLogonId" field
    into "logon sessions". For each of these logon sessions, start, end and duration
    are derived


author: "Marinus Boekelo - Northwave"

type: CLIENT

parameters:
  - name: EvtxGlob
    default: '%SystemRoot%\System32\Winevt\Logs\Security.evtx'
  - name: UsernameRegex
    description: "Target username Regex"
    default: .
    type: regex
  - name: UsernameWhitelist
    description: "Target username witelist Regex"
    default: '\\$$'
    type: regex
  - name: ServerRegex
    description: "Target server regex"
    default: .
    type: regex
  - name: ProcessNameRegex
    description: "Target process Regex"
    default: .
  - name: ProcessNameWhitelist
    description: "Target process whitelist Regex"
    type: regex
  - name: SearchVSS
    description: "Add VSS into query."
    type: bool
  - name: DateAfter
    type: timestamp
    description: "search for events after this date. YYYY-MM-DDTmm:hh:ssZ"
  - name: DateBefore
    type: timestamp
    description: "search for events before this date. YYYY-MM-DDTmm:hh:ssZ"

sources:
  - query: |

      -- firstly set timebounds for performance
      LET DateAfterTime <= if(condition=DateAfter,
          then=timestamp(epoch=DateAfter),
          else=timestamp(epoch="1600-01-01")
      )
      LET DateBeforeTime <= if(condition=DateBefore,
          then=timestamp(epoch=DateBefore),
          else=timestamp(epoch="2200-01-01")
      )

      -- expand provided glob into a list of paths on the file system (fs)
      LET fspaths <= SELECT FullPath
      FROM glob(globs=expand(path=EvtxGlob))

      -- function returning list of VSS paths corresponding to path
      LET vsspaths(path) = SELECT FullPath
      FROM Artifact.Windows.Search.VSS(SearchFilesGlob=path)

      -- function to search evtx files
      LET logonSearchAndGroup(PathList) =
        SELECT
          TargetLogonId,
          min(item=EventTime) as Start,
          max(item=EventTime) as End,
          max(item=System.TimeCreated.SystemTime)-min(item=System.TimeCreated.SystemTime) as Duration,
          System.Computer as SourceHost,
          enumerate(items=EventData) as EventDataList
        FROM foreach(
          row=PathList,
          query={
            SELECT
              timestamp(epoch=int(int=System.TimeCreated.SystemTime)) AS EventTime,
              EventData.TargetLogonId as TargetLogonId, EventData, System
            FROM
              parse_evtx(filename=FullPath)
            WHERE System.EventID.Value IN (4624,4634)
            AND EventData.TargetLogonId != 999
            AND EventTime < DateBeforeTime
            AND EventTime > DateAfterTime
          }
        ) GROUP BY TargetLogonId


      LET evtxsearch(PathList) =
      SELECT
        Start, End, Duration, SourceHost,
        EventDataList.SubjectUserSid AS SubjectUserSid,
        EventDataList.SubjectUserName AS SubjectUserName,
        EventDataList.SubjectDomainName AS SubjectDomainName,
        EventDataList.TargetLogonId AS TargetLogonId,
        EventDataList.TargetUserName AS TargetUserName,
        EventDataList.TargetDomainName AS TargetDomainName,
        EventDataList.TargetLogonId AS TargetLogonId,
        EventDataList.LogonType AS LogonType,
        EventDataList.LogonProcessName AS LogonProcessName,
        EventDataList.ProcessName AS ProcessName,
        EventDataList.IpAddress AS IpAddress
      FROM logonSearchAndGroup(PathList=PathList)
      WHERE TargetUserName =~ UsernameRegex
      AND NOT if(condition=UsernameWhitelist,
          then= TargetUserName =~ UsernameWhitelist,
          else= FALSE)
      AND ProcessName =~ ProcessNameRegex
      AND NOT if(condition=ProcessNameWhitelist,
          then= ProcessName =~ ProcessNameWhitelist,
          else= FALSE)
      ORDER BY Start


      -- include VSS in calculation and deduplicate with GROUP BY by file
      LET include_vss =
        SELECT * FROM foreach(
          row=fspaths,
          query={ SELECT * FROM evtxsearch(PathList={ SELECT FullPath FROM vsspaths(path=FullPath) }) }
        )

      -- exclude VSS in EvtxHunt`
      LET exclude_vss = SELECT *
        FROM evtxsearch(PathList={SELECT FullPath FROM fspaths})

      -- return rows
      SELECT * FROM if(condition=SearchVSS,
        then={ SELECT * FROM include_vss },
        else={ SELECT * FROM exclude_vss })