Adversaries may be attempting to brute force their way into a system by cycling through multiple accounts from a single public IP address, leveraging repeated failed login attempts to identify valid credentials. SOC teams should proactively hunt for this behavior in Azure Sentinel to detect potential credential compromise and prevent unauthorized access before it escalates.
KQL Query
// Query #2: Look for machines failing to log-on to multiple machines or using multiple accounts
// Note - RemoteDeviceName is not available in all remote logon attempts
DeviceLogonEvents
| where isnotempty(RemoteDeviceName)
| extend Account=strcat(AccountDomain, "\\", AccountName)
| summarize
Successful=countif(ActionType == "LogonSuccess"),
Failed = countif(ActionType == "LogonFailed"),
FailedAccountsCount = dcountif(Account, ActionType == "LogonFailed"),
SuccessfulAccountsCount = dcountif(Account, ActionType == "LogonSuccess"),
FailedComputerCount = dcountif(DeviceName, ActionType == "LogonFailed"),
SuccessfulComputerCount = dcountif(DeviceName, ActionType == "LogonSuccess")
by RemoteDeviceName
| where
Successful > 0 and
((FailedComputerCount > 100 and FailedComputerCount > SuccessfulComputerCount) or
(FailedAccountsCount > 100 and FailedAccountsCount > SuccessfulAccountsCount))
id: 89cc68d2-1330-40ce-aaca-5c76fc4f52b3
name: Account brute force (1)
description: |
Query #1: Look for public IP addresses that failed to logon to a computer multiple times, using multiple accounts, and eventually succeeded.
requiredDataConnectors:
- connectorId: MicrosoftThreatProtection
dataTypes:
- DeviceLogonEvents
query: |
// Query #2: Look for machines failing to log-on to multiple machines or using multiple accounts
// Note - RemoteDeviceName is not available in all remote logon attempts
DeviceLogonEvents
| where isnotempty(RemoteDeviceName)
| extend Account=strcat(AccountDomain, "\\", AccountName)
| summarize
Successful=countif(ActionType == "LogonSuccess"),
Failed = countif(ActionType == "LogonFailed"),
FailedAccountsCount = dcountif(Account, ActionType == "LogonFailed"),
SuccessfulAccountsCount = dcountif(Account, ActionType == "LogonSuccess"),
FailedComputerCount = dcountif(DeviceName, ActionType == "LogonFailed"),
SuccessfulComputerCount = dcountif(DeviceName, ActionType == "LogonSuccess")
by RemoteDeviceName
| where
Successful > 0 and
((FailedComputerCount > 100 and FailedComputerCount > SuccessfulComputerCount) or
(FailedAccountsCount > 100 and FailedAccountsCount > SuccessfulAccountsCount))
| Sentinel Table | Notes |
|---|---|
DeviceLogonEvents | Ensure this data connector is enabled |
Scenario: Scheduled Job Credential Rotation
Description: A system administrator uses a script (e.g., PowerShell, Python) to rotate credentials for a scheduled job, which results in multiple failed login attempts before the new credentials are applied.
Filter/Exclusion: Exclude events where the source IP is internal (e.g., source.ip in ('10.0.0.0/8', '172.16.0.0/12', '192.168.0.0/16')) or where the account is a service account with known credential rotation activity.
Scenario: Remote Management Tool Session
Description: A legitimate remote management tool (e.g., Microsoft Remote Desktop, TeamViewer, AnyDesk) is used to connect to a server, and the tool attempts to authenticate multiple times before establishing a session.
Filter/Exclusion: Exclude events where the source IP is associated with a known remote management tool (e.g., source.ip in ('192.168.1.100', '10.10.10.10')) or where the username matches a known remote management account (e.g., username = 'admin' or username = 'remoteuser').
Scenario: Admin Task with Multiple Credential Attempts
Description: An administrator uses a tool like PsExec or Invoke-Command to run a script that requires multiple authentication attempts due to credential caching or misconfiguration.
Filter/Exclusion: Exclude events where the username is a known admin account (e.g., username = 'Administrator') or where the process is initiated by a known admin user (e.g., user = 'DomainAdmin').
Scenario: Multi-Factor Authentication (MFA) Retry