Alerting

Building an Account Lockout Alert

Explorer

Hello,

I was reviewing a previous Splunk Answer (https://answers.splunk.com/answers/447037/how-to-edit-my-search-to-trigger-when-an-account-i.html) that has an great answer, but it seems the SPL has an error in it that was never corrected and the Splunk user who answered it is no longer active. I've tried to play with it to solve the error, but I'm not sure what in the stats command is causing the error despite the message presented. (Below)

The Error: Error in 'stats' command: The eval expression for dynamic field 'eval(if(lockout="Yes"), _time null())' is invalid. Error='The operator at ', _time null()' is invalid.'.

sourcetype="WinEventLog:Security" (EventCode="4740" OR EventCode==644 OR EventCode=4625 OR EventCode=4771) user="admin*"  
  | eval src_nt_host=coalesce(src_nt_host,host)
  | eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No") 
  | stats latest(eval(if(lockout="Yes"), _time, null())) as time, latest(src_nt_host) as host, latest(lockout) as locked out values(dest_nt_domain) as dest_nt_domain count(eval(EventCode=4625 OR EventCode=4771)) as count values(Source_Network_Address) as Source_Network_Address by user 
  | eval time=strftime(time,"%c") 
  | rename user to "User Name", Source_Network_Address to "IP Address", count to "Number of Failures"
  | table dest_nt_domain "User Name" host lockedout time "IP Address" "Number of Failures"

Any assistance would be wonderful. Thank you.

Labels (1)
0 Karma
1 Solution

SplunkTrust
SplunkTrust

stats does not like spaces within an eval. Try ... | stats latest(eval(if(lockout="Yes"),_time,null())) as time, ....
If that doesn't work then break out the eval.

...
| eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No")
| eval time =  if(lockout="Yes", _time, null())
| stats latest(time) as time, ... 
---
If this reply helps you, an upvote would be appreciated.

View solution in original post

0 Karma

SplunkTrust
SplunkTrust

stats does not like spaces within an eval. Try ... | stats latest(eval(if(lockout="Yes"),_time,null())) as time, ....
If that doesn't work then break out the eval.

...
| eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No")
| eval time =  if(lockout="Yes", _time, null())
| stats latest(time) as time, ... 
---
If this reply helps you, an upvote would be appreciated.

View solution in original post

0 Karma

Explorer

Hello. Based on your recommendations, I edited the SPL to the following:

sourcetype="WinEventLog:Security" (EventCode="4740" OR EventCode==644 OR EventCode=4625 OR EventCode=4771) user="admin*"  
   | eval src_nt_host=coalesce(src_nt_host,host)
   | eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No")
   | eval time = if(lockout="Yes"),_time, null())
   | stats latest(time) as time, latest(src_nt_host) as host, latest(lockout) as locked out values(dest_nt_domain) as dest_nt_domain count(eval(EventCode=4625 OR EventCode=4771)) as count values(Source_Network_Address) as Source_Network_Address by user 
   | eval time=strftime(time,"%c") 
   | rename user to "User Name", Source_Network_Address to "IP Address", count to "Number of Failures"
   | table dest_nt_domain "User Name" host lockedout time "IP Address" "Number of Failures"

However, it throws up this error now: Error in 'eval' command: The arguments to the 'if' function are invalid.

I tried working with the spacing in the eval if statement, but it doesn't seem to be picking up the opening parentheses.

0 Karma

SplunkTrust
SplunkTrust

The parentheses are not matched. Try my corrected answer.

---
If this reply helps you, an upvote would be appreciated.
0 Karma

Explorer

Thanks! I also found a spacing error between "locked" and "out" on line 5. Corrected below and added your edits.

sourcetype="WinEventLog:Security" (EventCode="4740" OR EventCode==644 OR EventCode=4625 OR EventCode=4771) user="*"  
    | eval src_nt_host=coalesce(src_nt_host,host)
   | eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No")
 | eval time =  if(lockout="Yes", _time, null())
 | stats latest(time) as time, latest(src_nt_host) as host, latest(lockout) as lockedout values(dest_nt_domain) as dest_nt_domain count(eval(EventCode=4625 OR EventCode=4771)) as count values(Source_Network_Address) as Source_Network_Address by user 
    | eval time=strftime(time,"%c") 
    | rename user to "User Name", Source_Network_Address to "IP Address", count to "Number of Failures"
    | table dest_nt_domain "User Name" host lockedout time "IP Address" "Number of Failures"

While this SPL is not throwing up an error now, I'm not receiving any results and I've seen examples of account lockouts in the last 24 hours. I'm not sure what it might be missing. Any ideas? Thanks again.

0 Karma

SplunkTrust
SplunkTrust

Run the search one pipe at a time until you get no results. That last pipe likely will be the cause.

---
If this reply helps you, an upvote would be appreciated.
0 Karma

Explorer

Thanks Rich. I went through it and corrected sourcetype to source and found an extra "=" in one of the EventCode. The table now appears using the SPL below:

source="WinEventLog:Security" (EventCode=4740 OR EventCode=644 OR EventCode=4625 OR EventCode=4771) user=* 
| eval src_nt_host=coalesce(src_nt_host,host)
| eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No")
| eval time =  if(lockout="Yes", _time, null())
| stats latest(time) as time, latest(src_nt_host) as host, latest(lockout) as lockedout values(dest_nt_domain) as dest_nt_domain count(eval(EventCode=4625 OR EventCode=4771)) as count values(Source_Network_Address) as Source_Network_Address by user 
| eval time=strftime(_time,"%c")
| rename user to "User Name", Source_Network_Address to "IP Address", count to "Number of Failures"
| table dest_nt_domain "User Name" host lockedout time "IP Address" "Number of Failures"

Last thing - I get no eval time results. I attempted to correct it using trial and error with _time vs time, but nothing surfaced. Thanks again for your continued assistance. I'm learning a lot from this.

0 Karma

SplunkTrust
SplunkTrust

Glad you're making progress.

eval time=strftime(_time, "%c") will fail because the _time field is not passed on by stats.
You may be getting no eval time results because of the eval time = if(lockout="Yes", _time, null()) statement. If all events have lockout="No" then the time field will always be NULL and stats latest(time) will be NULL.

---
If this reply helps you, an upvote would be appreciated.
0 Karma

Explorer

That did it! Thank you so much, Rich. This will help me greatly. The corrected SPL is below so that others in the community can utilize it if needed now that the time is populating as intended.

source="WinEventLog:Security" (EventCode=4740 OR EventCode=644 OR EventCode=4625 OR EventCode=4771) user=* 
 | eval src_nt_host=coalesce(src_nt_host,host)
 | eval lockout=if(EventCode==644 OR EventCode==4740,"Yes","No")
 | eval time =  if(lockout="Yes", _time, null())
 | stats latest(_time) as time, latest(src_nt_host) as host, latest(lockout) as lockedout values(dest_nt_domain) as dest_nt_domain count(eval(EventCode=4625 OR EventCode=4771)) as count values(Source_Network_Address) as Source_Network_Address by user 
 | eval time=strftime(time,"%c")
 | rename user to "User Name", Source_Network_Address to "IP Address", count to "Number of Failures"
 | table dest_nt_domain "User Name" host lockedout time "IP Address" "Number of Failures"
0 Karma