Splunk Search

Windows Session Tracking

dfarr
Explorer

Hello, I am trying to build a search to identify windows user sessions. The main goal was a list/track of users who do not log off of shared systems at the end of the day. There are more use cases I would like to get like identifying concurrent sessions. I think I am close, but I only get open sessions and some weird durations that are not correct. Any suggestions would be appreciated. 

index="main" sourcetype=WinEventLog:Security ((EventCode=4624 AND (Logon_Type=2 OR Logon_Type=3 OR Logon_Type=10 OR Logon_Type=11)) OR EventCode=4634 OR EventCode=4647)
| eval TargetUserName=coalesce(TargetUserName, Account_Name)
| where TargetUserName!="$*" AND TargetUserName!="SYSTEM" AND TargetUserName!="LOCAL SERVICE" AND TargetUserName!="NETWORK SERVICE"
| eval EventType = case(EventCode=4624, "Logon", EventCode=4634 OR EventCode=4647, "Logoff")
| sort 0 TargetUserName host -_time
| streamstats count(eval(EventType="Logoff")) as session_rev by TargetUserName host
| stats earliest(eval(if(EventType="Logon", _time, null()))) as firstLogOnEpoch
       latest(eval(if(EventType="Logoff", _time, null()))) as lastLogOffEpoch
        min(_time) as SessionStartEpoch
        max(_time) as SessionEndEpoch
        count(eval(EventType="Logon")) as LogonCount
        count(eval(EventType="Logoff")) as LogoffCount
    by TargetUserName host session_rev
| eval SessionDurationSec = SessionEndEpoch - SessionStartEpoch
| eval SessionDuration = if(isnull(SessionDurationSec),"N/A", tostring(SessionDurationSec,"duration"))
| eval SessionStart = strftime(SessionStartEpoch,"%Y-%m-%d %H:%M:%S")
| eval SessionEnd   = strftime(SessionEndEpoch,"%Y-%m-%d %H:%M:%S")
| eval firstLogOn = if(isnull(firstLogOnEpoch),"", strftime(firstLogOnEpoch,"%Y-%m-%d %H:%M:%S"))
| eval lastLogOff  = if(isnull(lastLogOffEpoch),"", strftime(lastLogOffEpoch,"%Y-%m-%d %H:%M:%S"))
| eval IsOpenSession = if(isnull(lastLogOffEpoch), 1, 0)
| eval Notes = case(
    IsOpenSession=1, "Open session: No logoff found after this logon",
    firstLogOn==SessionStart, "SessionStart is first event in search window: firstLogOn may precede search window", 1==1, "")
| table TargetUserName host firstLogOn lastLogOff SessionStart SessionEnd SessionDuration LogonCount LogoffCount IsOpenSession Notes
| sort -SessionStartEpoch
Labels (3)
0 Karma

bowesmana
SplunkTrust
SplunkTrust

There are many ways to achieve this with streamstats, but my example goes with sorting in ascending time and calculating duration in the streamstats.

See this example which creates 10 dummy logon/off events for a single user/host (SPL can demo up to 4 by changing the 'random() mod value from 1 to 4 in user/host eval)

| makeresults count=10
| eval EventType=mvindex(split("Logon,Logoff", ","), random() % 2)
| eval TargetUserName="USER".mvindex(split("ABCD", ""), random() % 1)
| eval host="HOST".mvindex(split("ABCD", ""), random() % 1)
| eval _time=_time - random() % 3600
| fields EventType Target* host _time
| sort 0 TargetUserName host  _time
| streamstats range(_time) as SessionDurationSec reset_after="("EventType=\"Logoff\"")" by TargetUserName host
| streamstats count(eval(SessionDurationSec=0)) as session by TargetUserName host
| eval SessionStart=if(EventType="Logoff", _time - SessionDurationSec, null())
``` Change this to stats to collapse data ```
| eventstats 
  max(SessionDurationSec) as SessionDurationSec
  min(SessionStart) as SessionStart
  count(eval(EventType="Logon")) as LogonCount
  min(eval(if(EventType="Logon", _time, null()))) as firstLogOn
  max(eval(if(EventType="Logoff", _time, null()))) as lastLogOff
  by TargetUserName host session
| eval SessionDuration = if(SessionDurationSec=0,"N/A", tostring(SessionDurationSec,"duration"))
| eval IsOpenSession = if(isnull(lastLogOff), 1, 0)
| eval Notes = case(
    IsOpenSession=1, "Open session: No logoff found after this logon",
    isnull(firstLogOn), "No prior login state found in search window", 1==1, "")
| foreach SessionStart firstLogOn lastLogOff [ eval <<FIELD>>=if(isnull(<<FIELD>>),null(), strftime(<<FIELD>>,"%F %T")) ]
```| table EventType TargetUserName host firstLogOn lastLogOff SessionStart SessionEnd SessionDuration LogonCount LogoffCount IsOpenSession Notes```

I've used an eventstats rather than stats so you can see the effect of the decisions made in the SPL, but you can change that to stats to get rid of the unwanted events.

The example ignores multiple logoff events and treats a logoff with no prior login (since a previous logoff) as a 0 length session.

Hope this helps

 

0 Karma
Got questions? Get answers!

Join the Splunk Community Slack to learn, troubleshoot, and make connections with fellow Splunk practitioners in real time!

Meet up IRL or virtually!

Join Splunk User Groups to connect and learn in-person by region or remotely by topic or industry.

Get Updates on the Splunk Community!

Event Series: Telemetry Pipeline Management

Balancing Scale and Spend: Gaining Control Over High-Volume Metrics in Splunk Observability Cloud As ...

Kick the Tires Before You Commit: A Hands-On Tour of the Splunk Observability Cloud ...

Evaluating an enterprise observability platform usually goes like this: fill out a form, get a free trial with ...

Deep insights, no barriers: Splunk Observability Cloud Free Edition

As software delivery cycles continue to accelerate, observability shouldn’t be a luxury — it should be a ...