Bruteforce Qurey

Copper Contributor

Is it the right query to know if some one is trying to brute force attempt with 5 failed login attempts.

 

SecurityEvent
| where TimeGenerated >= ago(1d)
| where EventID == 4625
| summarize FailedLogins=count(5) by Account, Computer
| sort by FailedLogins desc

2 Replies

@zubairrahimsoc There are a couple of Brute force queries available OOTB that you can use as a baseline.  For instance, the code below is from the Bruce force attack against Azure Portal.  You could remove the line:

| where AppDisplayName has "Azure Portal"

to make it more generic

 

let failureCountThreshold = 5;
let successCountThreshold = 1;
let authenticationWindow = 20m;
let aadFunc = (tableName:string){
table(tableName)
| extend DeviceDetail = todynamic(DeviceDetail), Status = todynamic(DeviceDetail), LocationDetails = todynamic(LocationDetails)
| extend OS = DeviceDetail.operatingSystem, Browser = DeviceDetail.browser
| extend StatusCode = tostring(Status.errorCode), StatusDetails = tostring(Status.additionalDetails)
| extend State = tostring(LocationDetails.state), City = tostring(LocationDetails.city), Region = tostring(LocationDetails.countryOrRegion)
| where AppDisplayName has "Azure Portal"
// Split out failure versus non-failure types
| extend FailureOrSuccess = iff(ResultType in ("0", "50125", "50140", "70043", "70044"), "Success", "Failure")
| summarize StartTime = min(TimeGenerated), EndTime = max(TimeGenerated), IPAddress = make_set(IPAddress), make_set(OS), make_set(Browser), make_set(City),
make_set(State), make_set(Region),make_set(ResultType), FailureCount = countif(FailureOrSuccess=="Failure"), SuccessCount = countif(FailureOrSuccess=="Success")
by bin(TimeGenerated, authenticationWindow), UserDisplayName, UserPrincipalName, AppDisplayName, Type
| where FailureCount >= failureCountThreshold and SuccessCount >= successCountThreshold
| mvexpand IPAddress
| extend IPAddress = tostring(IPAddress)
| extend timestamp = StartTime, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress
};
let aadSignin = aadFunc("SigninLogs");
let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs");
union isfuzzy=true aadSignin, aadNonInt
There are many ways to achieve this. If it is for AAD then this should work and is generic for any application access that uses AAD accounts.

let timeframe = <set the time frame window>;
let threshold = <set max failures>;
SigninLogs
| where TimeGenerated >= ago(timeframe)
| where ResultType in ("50126", "50074")
| summarize min(TimeGenerated), max(TimeGenerated), FailedLogonCount = count() by ResultType, UserDisplayName , UserPrincipalName,AlternateSignInName,IPAddress
| where FailedLogonCount >= threshold