id: 1ce5e766-26ab-4616-b7c8-3b33ae321e80 name: Failed host logons but success logon to AzureAD description: | 'Identifies a list of IP addresses with a minimum number(default of 5) of failed logon attempts to remote hosts. Uses that list to identify any successful logons to Azure Active Directory from these IPs within the same timeframe.' severity: Medium requiredDataConnectors: - connectorId: AzureActiveDirectory dataTypes: - SigninLogs - connectorId: AzureActiveDirectory dataTypes: - AADNonInteractiveUserSignInLogs - connectorId: SecurityEvents dataTypes: - SecurityEvent - connectorId: Syslog dataTypes: - Syslog queryFrequency: 1d queryPeriod: 1d triggerOperator: gt triggerThreshold: 0 tactics: - InitialAccess - CredentialAccess relevantTechniques: - T1078 - T1110 query: | //Adjust this threshold to fit environment let signin_threshold = 5; //Make a list of IPs with failed Windows host logins above threshold let win_fails = SecurityEvent | where EventID == 4625 | where LogonType in (10, 7, 3) | where IpAddress != "-" | summarize count() by IpAddress | where count_ > signin_threshold | summarize make_list(IpAddress); //Make a list of IPs with failed *nix host logins above threshold let nix_fails = Syslog | where Facility contains 'auth' and ProcessName != 'sudo' | extend SourceIP = extract("(([0-9]{1,3})\\.([0-9]{1,3})\\.([0-9]{1,3})\\.(([0-9]{1,3})))",1,SyslogMessage) | where SourceIP != "" and SourceIP != "127.0.0.1" | summarize count() by SourceIP | where count_ > signin_threshold | summarize make_list(SourceIP); //See if any of the IPs with failed host logins hve had a sucessful Azure AD login let aadFunc = (tableName:string){ table(tableName) | where ResultType !in ("0", "50125", "50140") | where IPAddress in (win_fails) or IPAddress in (nix_fails) | extend Reason= "Multiple failed host logins from IP address with successful Azure AD login" | extend timstamp = TimeGenerated, AccountCustomEntity = UserPrincipalName, IPCustomEntity = IPAddress, Type = Type }; let aadSignin = aadFunc("SigninLogs"); let aadNonInt = aadFunc("AADNonInteractiveUserSignInLogs"); union isfuzzy=true aadSignin, aadNonInt entityMappings: - entityType: Account fieldMappings: - identifier: FullName columnName: AccountCustomEntity - entityType: IP fieldMappings: - identifier: Address columnName: IPCustomEntity