T1110.003 Elastic Security · Elastic

Detect Password Spraying in Elastic Security

Adversaries may use a single or small list of commonly used passwords against many different accounts to attempt to acquire valid account credentials. Password spraying uses one password (e.g. 'Password01'), or a small list of commonly used passwords, that may match the complexity policy of the domain. Logins are attempted with that password against many different accounts on a network to avoid account lockouts that would normally occur when brute forcing a single account with many passwords. This technique is deliberately throttled to avoid triggering per-account lockout thresholds — the defining characteristic that distinguishes spraying from brute force (T1110.001). Adversaries including APT28, APT29, HAFNIUM, Storm-0940, Chimera, and APT33 have used this technique at scale against OWA, Microsoft 365, VPN portals, SSH, RDP, SMB, and LDAP. Slow-spray variants (approximately 4 attempts per account per hour) are specifically designed to evade detection thresholds, and Kerberos-based spraying is used to avoid generating the high-visibility Event ID 4625 typically alerted on.

MITRE ATT&CK

Tactic
Credential Access
Technique
T1110 Brute Force
Sub-technique
T1110.003 Password Spraying
Canonical reference
https://attack.mitre.org/techniques/T1110/003/

Elastic Detection Query

Elastic Security (Elastic)
eql
authentication where event.outcome == "failure"
  and winlog.logon.type in ("Network", "RemoteInteractive")
  and source.ip != null
  and source.ip != "127.0.0.1"
  and source.ip != "::1"
  and source.ip != "-"
  and user.name != null
  and user.name != ""
  and user.name != "ANONYMOUS LOGON"
  and user.domain != "NT AUTHORITY"
/* Deploy as Elastic SIEM Threshold Rule:
   - Rule type: Threshold
   - Threshold field: user.name (count_distinct >= 10)
   - Group by: source.ip
   - Time window: 30m
   Covers winlog EventCode 4625, ECS-normalized Azure AD SigninLogs,
   Okta system events, and Linux SSH/PAM failures via system.auth integration.
   To distinguish spray from brute force, correlate alert-time FailureCount
   against DistinctAccounts: flag only where ratio <= 5. */
high severity high confidence

Detects password spraying via Elastic Threshold rule: a single source IP failing authentication against 10 or more distinct accounts within a 30-minute window with 5 or fewer average failures per account. The EQL filter handles ECS normalization across Windows Security Event 4625, Azure AD, Okta, and Linux SSH failure sources. Spray is distinguished from per-account brute force by the low average-failures-per-account ratio enforced at threshold evaluation time.

Data Sources

Windows Security Event Log (EventCode 4625 via winlogbeat)Azure Active Directory SigninLogs via Azure integrationOkta System Logs via Elastic Okta integrationLinux SSH/PAM via Elastic system.auth integration

Required Tables

winlogbeat-*logs-system.auth-*logs-azure.signinlogs-*logs-okta.system-*.ds-logs-windows.*

False Positives & Tuning

  • Corporate NAT gateways or PAT devices where hundreds of employees egress through a single external IP — mass simultaneous password expiry events cause legitimate users' failed logons to aggregate under one source address and cross the account threshold
  • IT service desk platforms (ServiceNow, Jira Service Management) that validate account status or test connectivity on behalf of many users from a shared agent IP, especially during bulk password reset operations or onboarding waves
  • Security scanning tools (Qualys, Tenable Nessus, Rapid7 InsightVM) executing credentialed authentication checks across Active Directory or LDAP from a fixed scanner IP, hitting many accounts in rapid succession during scheduled scan windows
Download portable Sigma rule (.yml)

Other platforms for T1110.003


Testing Methodology

Validate this detection against 4 adversary techniques from Atomic Red Team. Each test below lists the behaviour to exercise and the telemetry you should expect to see. Executable commands and cleanup steps are available with Pro.

  1. Test 1Local Account Password Spray via Net Use (Windows)

    Expected signal: Windows Security Event ID 4625 — one per iteration with LogonType=3, TargetUserName=each account in the list, SubStatus=0xC0000064 (unknown user) for non-existent accounts or 0xC000006A (wrong password) for existing accounts, IpAddress=127.0.0.1. SecurityEvent 4648 (Explicit Credential Logon) may also fire. With 12 accounts in the list, DistinctAccounts=12 will exceed the default threshold of 10.

  2. Test 2Azure AD Password Spray via PowerShell OAuth Token Request

    Expected signal: Azure AD SigninLogs entries (visible in Azure Portal > Azure AD > Sign-in logs within 5-15 minutes) for each request: ResultType=50126 (InvalidUserNameOrPassword) or 50057 (account disabled), IPAddress=your public egress IP, AppDisplayName='Microsoft Azure PowerShell' or 'Azure Active Directory PowerShell', UserAgent containing 'PowerShell'. With 11 accounts in the list, DistinctAccounts=11 exceeds the SprayAccountThreshold=10.

  3. Test 3Kerberos Password Spray via Rubeus (Low-Visibility Technique)

    Expected signal: Windows Security Event ID 4771 on the Domain Controller for each domain account targeted. Fields: Client Address = spray source IP, Account Name = target username, Service Name = krbtgt, Failure Code = 0x18 (KRB_AP_ERR_BAD_INTEGRITY — wrong password) or 0x6 (KDC_ERR_C_PRINCIPAL_UNKNOWN — unknown account). Event ID 4768 (TGT Request) may appear for accounts that receive AS-REQ. The /delay 2000ms and /jitter 30% simulate slow-spray behavior. Main 4625-based detection does NOT fire, demonstrating the detection gap this technique exploits.

  4. Test 4SMB Password Spray via CrackMapExec Against Subnet

    Expected signal: Windows Security Event ID 4625 on the target host for each account attempted: LogonType=3 (Network), SubStatus=0xC000006A (wrong password) for valid accounts or 0xC0000064 (unknown user) for invalid accounts, IpAddress=attacker IP, WorkstationName=blank (common CrackMapExec behavior), AuthenticationPackageName=NTLM. With 10 accounts, DistinctAccounts=10 meets the default detection threshold. EventID 7045 may appear if CrackMapExec uses service-based execution. Sysmon Event ID 3 (Network Connection) visible on attacking host.

Unlock Pro Content

Get the full detection package for T1110.003 including response playbook, investigation guide, and atomic red team tests.

Response PlaybookInvestigation GuideHunting QueriesAtomic Red Team TestsTuning Guidance

Related Detections