To detect a failed login following by successful login (within a 60 second) period, I run:
index=myindex sourcetype=wineventlog:security (EventCode=4624 OR EventCode=4625)
| transaction Account_Name, host startswith="EventCode=4625" endswith="EventCode=4624" maxspan=60s
| eval baduser = mvindex(Account_Name,2)
| eval nextsuccess = mvindex(Account_Name,1)
| table baduser nextsuccess host _time
To detect a username that looks like a password (14+ characters and 3 of 4 character classes), I run:
index=myindex sourcetype="wineventlog:security" EventCode=4625
| eval Account_Name = mvindex(Account_Name,1)
| search Account_Name!="*$"
| rex field=Account_Name "(?<"pass">(?=^.{14,}$)((?=.*\d)(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[^A-Za-z0-9])(?=.*[a-z])|(?=.*[^A-Za-z0-9])(?=.*[A-Z])(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])(?=.*[^A-Za-z0-9]))^.*)"
| stats count by pass
| fields - count
The question is how do I combine these searches? For each bad `Acount_Name` in the second search, I would like to find the next successful logon in a 60 second period. My end goal is a table containing 2 fields: failed login `Account_Name` and next successful login `Account_Name`. The input is the standard Windows security event log. For example:
Possible_Password | Next_success
oopsTh1sismypassw0rd!! | msmith67
↧