Hi,
I am trying to create a query that would list all denied logons (EventCode 4625), from a single workstation to many hosts using one or more account ids. This needs to be within a certain time window, say 1 minute.
How can I achieve this? So far I came with this:
index=win_sec (EventCode=4625 AND Logon_Type=3) (Account_Name!="*$" AND Account_Name!="Guest" AND Account_Name!="Administrator") |
eval Account_Name=mvindex(Account_Name,-1) |
bucket _time span=1min |
chart values(host) as host, values(Workstation_Name) as workstation, values(Failure_Reason) as failureReason, values(_time) as timeSpan over Account_Name
This gives me a starting point but I cannot tell if the denied logons happened within the same time window. What am I missing here?
Thank you,
Rob
You can try the following different failed logon approach:
index=win_sec (EventCode=4625 AND Logon_Type=3) (Account_Name!="*$" AND Account_Name!="Guest" AND Account_Name!="Administrator") |
table _time Account_Name Workstation_Name host Failure_Reason
| timechart span=1m count as FailedLogonCount by Account_Name
| eval threshold=200
Created Stacked column chart with Chart Overlay field as threshold (200). When you see failed logon count spiking above threshold you can drilldown to see the details of what failed logons are present.
Ideally, you should consider Splunk Machine Learning Toolkit app (https://splunkbase.splunk.com/app/2890/) to Detect Numerical/Categorical Outlier for Failed Logins.
https://docs.splunk.com/Documentation/MLApp/latest/User/DetectNumericOutliers
Thank you. This actually worked!
@robettinger - if your problem has been solved, please accept the answer.
We've moved the comment to answer so you can do so. If this was not the one that worked, just let us know and we can move the other one down.
@robettinger, Following query will give you count of Failed Logon along with hosts being accessed, failure reason and Account Name involved per workstation per minute. Please try out to confirm whether this is what you need.
index=win_sec (EventCode=4625 AND Logon_Type=3) (Account_Name!="*$" AND Account_Name!="Guest" AND Account_Name!="Administrator") |
timechart span=1m count as Failed_Logon_Attempts values(host) as host values(Failure_Reason) as Failure_Reason values(Account_Name) as Account_Name by Workstation_Name
PS: You can even use span
option with charts (no need to bucket _time). I have removed Account_Name eval expecting it is either not multi-value or even if it is you would be interested in all. In case you need yours you can bring it back. If you need further details, please send some sample anonymized mock data as well.
Hi, thank you for suggestion. It works partially. Basically what I am looking for is the Account Names which have logon denied to many servers, from the same workstation, in a short period of time. The idea is to flag some accounts as potentially compromised if, for example, they have denied logons from 200 servers within 1 minute.... Does this make sense?
Ok this changes from your question where you wanted to identify failed logon from a single workstation. However, seems like you are interested in failed logon from a single account (which your first query was performing). You dont need the following as well?
index=win_sec (EventCode=4625 AND Logon_Type=3) (Account_Name!="*$" AND Account_Name!="Guest" AND Account_Name!="Administrator") |
timechart span=1m count as Failed_Logon_Attempts values(host) as host values(Failure_Reason) as Failure_Reason values(Workstation_Name) as Workstation_Name by Account_Name
If you want to aggregate by both Workstation and Account Name then you can try stats instead or maybe do an | eval key = Workstation_Name. " - ".Account_Name
and perform timechart by key
.
index=win_sec (EventCode=4625 AND Logon_Type=3) (Account_Name!="*$" AND Account_Name!="Guest" AND Account_Name!="Administrator") |
bucket _time span=1min |
stats count as Failed_Logon_Attempts values(host) as host values(Failure_Reason) as Failure_Reason by Account_Name Workstation_Name
Once you find correct group clause, you can then pipe threshold on count to filter out failed logons you are interested in.
| search count>200