Security

How to detect password in username field followed by successful logon?

kenster89
Engager

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

0 Karma

danielansell
Path Finder

I found your post looking for the same thing you were. I used your transaction based search to help out. I required Sub_Status=0xc0000064 as a requirement to the failed logon attempt because it means the attempt was from an unknown user. You could probably further increase the probability of detecting a password by incorporating your regex against the baduser field. I know this is almost 4 years old, but here is what I came up with:

index=whatever sourcetype="wineventlog:security" EventCode=4624 OR (EventCode=4625 Sub_Status=0xc0000064)
| transaction host startswith="EventCode=4624" endswith="EventCode=4625" maxspan=180s
| eval baduser=mvindex(Account_Name,1), gooduser=mvindex(Account_Name=-1)
| reverse
| table _time, host, baduser, gooduser, Account_Name, duration

Note - this search  ran extremely slow for me. I decided a couple years ago I want to be able to search all logon activity very quickly, so I created a summary index with that data in it. When searching that index, my results are returned very quickly. Alternatively you can probably do an accelerated data model. 

 

Hopefully this helps somebody, even if you're no longer after the answer. 

 

0 Karma
Career Survey
First 500 qualified respondents will receive a $20 gift card! Tell us about your professional Splunk journey.
Get Updates on the Splunk Community!

Tech Talk Recap | Mastering Threat Hunting

Mastering Threat HuntingDive into the world of threat hunting, exploring the key differences between ...

Observability for AI Applications: Troubleshooting Latency

If you’re working with proprietary company data, you’re probably going to have a locally hosted LLM or many ...

Splunk AI Assistant for SPL vs. ChatGPT: Which One is Better?

In the age of AI, every tool promises to make our lives easier. From summarizing content to writing code, ...