Detection Playbook: Password Spraying (T1110.003)

T1110.003 · 2026-06-22

Password Spraying

Credential Access
Containers ESXi IaaS Identity Provider
MITRE ATT&CK →
Technique Password Spraying (T1110.003)
Tactic Credential Access
Platforms Containers, ESXi, IaaS, Identity Provider, Linux, Network Devices, Office Suite, SaaS, Windows, macOS

Overview

Password spraying is a credential access technique where an adversary attempts a single commonly used password — or a very short list — across a large number of accounts, rather than guessing many passwords against one account. This approach is specifically designed to stay under lockout thresholds while maximizing the chance of finding at least one valid credential. A successful spray gives the attacker authenticated access to internal systems, cloud environments, or SaaS applications without needing to exploit any vulnerability.

Every organization is a target for password spraying because it requires no malware, no zero-days, and leaves a relatively small initial footprint. Attackers routinely use it as the first step in ransomware, espionage, and business email compromise campaigns. Security teams that lack visibility into authentication telemetry across on-premises and cloud surfaces will miss this technique entirely until significant damage has already been done.

Attacker Perspective

Attackers use password spraying to gain an initial foothold in an environment using nothing more than a list of usernames and one or two guessed passwords, making it a low-cost, high-reward technique with minimal chance of immediate detection.

  • Active Directory spraying with Kerbrute: Attackers enumerate valid AD usernames and spray using kerbrute passwordspray -d corp.local --dc 10.0.0.1 users.txt Password2024!, leveraging Kerberos pre-authentication failures (event 4771) which generate less noise than NTLM failures.
  • Microsoft 365 spraying with MSOLSpray: Attackers target cloud identity using Invoke-MSOLSpray -UserList users.txt -Password Summer2024!, which authenticates against the Microsoft login endpoint and can bypass legacy per-account lockout controls when legacy authentication protocols are left enabled.
  • SSH spraying with Hydra: Against exposed Linux systems or network devices, attackers run hydra -L users.txt -p Password1 -t 4 ssh://192.168.1.0/24 at a low thread count to avoid triggering rate-based alerts on firewall or IDS sensors.
  • OWA/Exchange spraying with MailSniper: Attackers target external-facing Outlook Web Access using Invoke-PasswordSprayOWA -ExchHostname mail.corp.com -UserList users.txt -Password Fall2024!, which authenticates over HTTPS and blends with legitimate webmail traffic.

Password spraying is attractive because it requires no elevated access, no malware deployment, and can be executed entirely over legitimate authentication channels, making it extremely difficult to distinguish from normal login activity without purpose-built detection logic.

Detection Strategy

Required Telemetry

  • Windows Security Event Log — Failed Logons: Enable “Audit Logon Events” (both success and failure) via GPO: Computer Configuration → Windows Settings → Security Settings → Advanced Audit Policy → Logon/Logoff → Audit Logon = Success, Failure. This generates Event ID 4625 (failed logon) and Event ID 4624 (successful logon). Collect from all domain controllers and member servers. Also enable “Audit Account Logon Events” to capture Event ID 4776 (NTLM credential validation) and Event ID 4771 (Kerberos pre-auth failure).
  • Windows Security Event Log — Account Lockouts: Event ID 4740 is generated on the domain controller when an account is locked out. Collect from all DCs. This is a high-value lagging indicator — if you see it, spraying may already have succeeded or escalated to brute force.
  • Azure AD / Entra ID Sign-In Logs: Enable via Azure Portal: Azure Active Directory → Diagnostic Settings → Send to Log Analytics → Include SignInLogs and NonInteractiveUserSignInLogs. Key fields: ResultType, UserPrincipalName, IPAddress, AppDisplayName, ClientAppUsed, ConditionalAccessStatus. Captures both interactive and non-interactive (service, legacy protocol) authentication attempts against Entra ID and M365.
  • Azure AD / Entra ID Audit Logs: Captures administrative actions such as password resets following a successful spray. Enable alongside Sign-In Logs in the same Diagnostic Setting.
  • Linux PAM / sshd Authentication Logs: Authentication failures appear in /var/log/auth.log (Debian/Ubuntu) or /var/log/secure (RHEL/CentOS). Forward via syslog agent (Filebeat, Fluentd, or rsyslog). For auditd coverage, add the rule: -a always,exit -F arch=b64 -S execve -k auth_attempts. Failed SSH logins generate messages matching Failed password for .* from .* port.
  • Network/Firewall Flow Data: Collect NetFlow or firewall session logs that include source IP, destination IP, destination port, and connection count. Required to detect distributed spraying where each source IP attempts only a small number of authentications — a pattern that evades per-source-IP host-based detection.
  • VPN and Remote Access Authentication Logs: RADIUS authentication logs (typically syslog from the NPS server or VPN appliance). Failed attempts appear as Access-Reject messages. Collect from all VPN concentrators and NPS servers.
  • Web Application / OWA / ADFS Logs: IIS logs for OWA (%SystemDrive%\inetpub\logs\LogFiles) and ADFS event logs (Event IDs 1200, 1201, 411) on ADFS servers. These capture federated authentication attempts that may not produce standard AD events.
  • Identity Provider Logs (Okta, Ping, etc.): Enable System Log export from your IdP. In Okta, stream via the System Log API or EventBridge. Key event types: user.session.start (success) and user.authentication.auth_via_mfa_factor failures, plus user.account.lock.

Key Indicators

  • High volume of Event ID 4625 across many distinct usernames from one source: In Windows Security log, check EventID = 4625, LogonType = 3 (network), FailureReason = %%2313 (wrong password), with SubjectUserName varying across events while IpAddress remains constant. A single source IP generating failures against 20+ distinct accounts within 30 minutes is a strong indicator.
  • High volume of Event ID 4771 (Kerberos pre-auth failure) across many accounts: Check EventID = 4771, FailureCode = 0x18 (wrong password). This is the Kerberos equivalent of 4625 and is specifically targeted by tools like Kerbrute to avoid generating 4625 events. Look for the same source IP or workstation name across many different TargetUserName values in a short window.
  • Low-and-slow spray pattern — few failures per account, many accounts: In any authentication log, look for a source where the count of unique usernames is high but the failure count per username is 1–3. This is the defining behavioral fingerprint of a spray versus a brute force. Example pseudofield query: COUNT(DISTINCT TargetUserName) > 20 WHERE AuthResult = Failure AND SourceIP = X WITHIN 60min.
  • Azure AD Sign-In failures with ResultType 50126 or 50053: In SignInLogs, ResultType = 50126 means invalid username or password; ResultType = 50053 means account locked. A single IPAddress producing ResultType = 50126 against many distinct UserPrincipalName values is a cloud spray indicator.
  • Legacy authentication protocol usage in Azure AD: In SignInLogs, check ClientAppUsed IN ["SMTP", "IMAP", "POP3", "BasicAuth", "Exchange ActiveSync"]. Legacy protocols bypass MFA and Conditional Access, making them a preferred spray vector. Any authentication via these protocols from an external IP deserves scrutiny.
  • Successful logon immediately following a spray pattern: Correlate Event ID 4624 (or Azure AD ResultType = 0) for a user account within a short window after multiple 4625 or 4771 failures targeting that same account or the same source IP. This success-after-failure sequence is the highest-priority indicator of a completed spray.
  • Linux SSH failure pattern: In /var/log/auth.log, match the regex pattern Failed password for .* from (\S+). Extract the source IP and count distinct usernames targeted within a 10-minute window. More than 10 distinct usernames from a single source IP within that window warrants alerting.
  • Distributed spray from multiple source IPs to one destination: In firewall/flow data, look for many distinct source IPs each making a small number of connections to port 443, 389, 88, or 3389 on a single authentication server within the same time window, where each individual source would not trigger a per-IP threshold.

Detection Logic

Rule 1 (Broad — High Sensitivity): Many accounts failing authentication from a single source
IF EventID IN [4625, 4771] AND AuthFailureReason IN ["wrong_password", "0x18", "%%2313"] AND COUNT(DISTINCT TargetUserName) >= 20 AND COUNT(DISTINCT SourceIP) <= 2 WITHIN 30 minutes GROUP BY SourceIP THEN alert("Password Spray - Single Source, Many Accounts")

This catches the most common spray pattern — one external IP, many accounts. Expected volume is low in most environments (0–5 alerts per day), but may fire on legitimate batch authentication tools; tune threshold based on your environment's baseline. This rule will not catch distributed sprays.

Rule 2 (Behavioral): Low failure count per account, high unique account count
IF EventID IN [4625, 4771, 4776] AND AuthFailureReason = "wrong_password" AND COUNT(DISTINCT TargetUserName) >= 15 AND MAX(FailureCount_per_TargetUserName) <= 3 WITHIN 60 minutes GROUP BY SourceIP THEN alert("Password Spray - Low-and-Slow Pattern")

This specifically targets the spray-versus-brute-force behavioral difference: many accounts, very few attempts per account. This rule is more precise than Rule 1 and is much harder for attackers to evade without dramatically slowing their spray. Expected volume is very low — treat all alerts as high priority.

Rule 3 (Cloud-Focused): Azure AD spray pattern using legacy protocols
IF LogSource = "AzureADSignInLogs" AND ResultType = 50126 AND ClientAppUsed IN ["SMTP", "IMAP", "POP3", "Exchange ActiveSync", "Other clients"] AND COUNT(DISTINCT UserPrincipalName) >= 10 WITHIN 20 minutes GROUP BY IPAddress AND NOT IPAddress IN [trusted_corporate_egress_ips] THEN alert("Password Spray - Cloud Legacy Auth")

Targets adversaries exploiting legacy authentication protocols that bypass MFA. This is a highly precise rule — legacy auth from an external IP spraying multiple UPNs has almost no legitimate explanation. Expected volume should be near zero if legacy auth is properly restricted via Conditional Access.

Rule 4 (High Precision): Successful logon following a spray pattern
IF EventID = 4624 AND LogonType = 3 AND TargetUserName IN [accounts_seen_in_recent_spray_alert] WITHIN 15 minutes AFTER spray_alert THEN alert("CRITICAL - Successful Logon After Password Spray", severity=HIGH)

This correlation rule fires when a successful authentication occurs for any account that was targeted in a recent spray alert, indicating the spray likely succeeded. This should be your highest-priority alert and should trigger immediate analyst response. Volume will be very low but every instance must be investigated.

Tuning Guidance

  • Vulnerability scanners and password audit tools: Internal scanners (Tenable, Qualys, Rapid7) performing authenticated scans can generate bursts of failed logons that match spray patterns. Exclude by adding SourceIP IN [scanner_ip_list] or SubjectUserName IN [scan_service_accounts] to your rules. Maintain a documented list of scanner IPs and schedule windows.
  • Misconfigured service accounts with stale passwords: A service account with an expired or changed password repeatedly failing authentication against many systems will look like a single-username brute force, not a spray — but can inflate your failure counts and skew multi-account aggregations. Exclude known service accounts with TargetUserName NOT IN [service_account_list] only after confirming the accounts are truly misconfigured and not compromised.
  • Load balancers and NAT gateways masking many users: Large organizations where many employees egress through a small number of shared NAT IPs will make the single-source-IP spray rule fire on legitimate user activity. Tune by raising thresholds for those specific IPs, or by switching to a per-user failure count rather than per-source-IP, and adding SourceIP NOT IN [corporate_nat_egress_ips].
  • Help desk password reset workflows: Automated password reset portals may attempt authentication with the old credential before resetting, generating a single failure per user. This pattern is usually distinguishable from a spray because it occurs one account at a time rather than in a burst. Exclude by correlating against change management or ITSM ticket data, or by adding SourceIP NOT IN [helpdesk_tool_ips].
  • M365 mobile app re-authentication bursts: When a user's password is changed, all active mobile clients (Outlook mobile, Teams) immediately retry with the old password, generating a burst of failures from many different device IPs for a single user. This is the inverse of a spray (one user, many IPs) and should not trigger your multi-account spray rules. Confirm by checking whether all failures share a single UserPrincipalName before ruling it out.

When the Alert Fires: Investigation Steps

  1. Verify the alert is real — confirm raw events exist in the source log. Pull the raw Event ID 4625, 4771, or Azure AD SignInLogs records that triggered the alert directly from your SIEM. Confirm the volume, source IP, and targeted accounts are accurately reflected in the alert and not an artifact of log parsing or aggregation errors.
  2. Identify all targeted accounts and flag any privileged ones. Extract the full list of TargetUserName values from the spray window and cross-reference against your Active Directory or IdP to identify any admin accounts, service accounts, or executives that were targeted or successfully authenticated. Treat any privileged account match as an immediate escalation trigger.
  3. Determine whether any spray attempt succeeded. Query for Event ID 4624 (Windows), Azure AD ResultType = 0, or Linux Accepted password syslog messages for any account in the targeted list, from the same source IP or within the same time window. A successful logon for any targeted account changes the severity of this investigation entirely.
  4. Profile the source IP and identify the attack infrastructure. Run the source IP through threat intelligence tools (VirusTotal, Shodan, AbuseIPDB, your SIEM's TI feed). Determine whether it is a known VPN exit node, Tor relay, cloud hosting provider, or residential proxy — all of which are commonly used to conduct sprays and proxy the source of the attack.
  5. Check for post-authentication activity if any logon succeeded. If a successful logon was identified in step 3, query your SIEM for all activity from that account and source IP following the successful logon: file access (Event ID 4663), new process creation (Event ID 4688 or Sysmon Event ID 1), email access in M365 Unified Audit Log, and any Azure AD role assignments or MFA registration events (which attackers use to establish persistence).
  6. Look for lateral movement originating from any compromised session. Search for network logon events (Event ID 4624, LogonType = 3) or RDP sessions (Event ID 4778) sourced from any host or account identified in step 5 to other internal systems. Also check for use of PsExec, WMI, or PowerShell Remoting from that account in your EDR or process creation logs within the 24 hours following the successful spray.
  7. Make the escalation decision based on confirmed evidence. If the spray produced zero successful logons and the source IP is external with no prior legitimate history, close as a blocked attack and document the source IP as an IOC. If any logon succeeded, any privileged account was targeted, or any post-authentication activity is found, escalate immediately to a full incident response and move to containment — do not wait for further confirmation.

Response Playbook

Containment

  • Block the source IP(s) at the perimeter firewall and DNS layer immediately. Create a deny rule for all identified spray source IPs on your edge firewall and, if you use DNS firewall or RPZ, add the IPs to your blocklist. If the spray originated from a cloud provider IP range (e.g., AWS, Azure, DigitalOcean), evaluate whether that entire range needs temporary restriction based on your environment's legitimate usage of that provider.
  • Disable or restrict any accounts confirmed to have authenticated successfully. In Active Directory, use Disable-ADAccount -Identity username or the Active Directory Users and Computers console. In Azure AD/Entra ID, navigate to the user and toggle "Account enabled" to off, or use Update-MgUser -UserId upn -AccountEnabled $false. Do not simply reset the password at this stage — disable the account entirely until the scope of access is known.
  • Revoke all active sessions and tokens for any compromised account. In Azure AD, use Revoke-MgUserSignInSession -UserId upn or the "Revoke sessions" button in the Entra ID portal. For Okta, use the Admin Console to clear all active sessions for the user. This invalidates existing OAuth tokens, SAML sessions, and refresh tokens so the attacker cannot maintain access via existing authenticated sessions even after a password reset.
  • If legacy authentication was the spray vector, block it via Conditional Access immediately. In Azure AD, create or update a Conditional Access policy to block all legacy authentication protocols (Client apps: Exchange ActiveSync, Other clients) for all users. This closes the spray vector for any accounts not yet compromised and prevents re-spray via the same mechanism.
  • Isolate any host identified as an internal spray source or post-compromise pivot point. If the spray originated from or pivoted through an internal host, isolate it at the network switch level (port disable or VLAN quarantine) or via your EDR's network isolation feature. Leave the machine powered on to preserve volatile memory and forensic artifacts — do not shut it down.

Eradication

  • Force a full password reset for all accounts targeted in the spray, not just confirmed compromises. Because you cannot always confirm which accounts authenticated successfully before detection, reset passwords for the full targeted account list. Communicate to users that this is a security-driven reset and coordinate with the help desk to handle the volume. Enforce the reset at next logon using Set-ADUser -ChangePasswordAtLogon $true.
  • Search for new MFA device registrations, email forwarding rules, and OAuth app consents on compromised accounts. In the M365 Unified Audit Log, query for Add MFA method, Set-Mailbox -ForwardingAddress, and Add app role assignment to service principal events in the window following the successful logon. Attackers commonly establish these as persistence mechanisms immediately after gaining access. Remove any unauthorized entries found.
  • Hunt for persistence mechanisms on any host that was accessed post-spray. On affected Windows hosts, check for new scheduled tasks (schtasks /query, Event ID 4698), new or modified services (Event ID 7045), Run/RunOnce registry keys (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Run), and new local administrator accounts (Event ID 4720 + 4732). Use your EDR to automate this sweep across all hosts the compromised account authenticated to.
  • Rotate credentials for any service accounts or API keys that were accessible to the compromised user account. Review what resources the compromised account had access to and identify any service account passwords, API tokens, or secrets stored in locations the account could read (file shares, code repositories, password managers, CI/CD pipelines). Rotate all of them — attackers routinely harvest these within minutes of gaining access.
  • Review and close any gaps that enabled the spray. Specifically: confirm MFA is enforced for all targeted accounts, confirm legacy authentication is blocked, confirm the usernames used in the spray are not publicly enumerable (e.g., via OSINT, LinkedIn scraping, or previous breach data), and confirm account lockout policies are appropriate. Address any gaps as part of eradication, not just remediation planning.

Recovery

  • Re-enable affected accounts only after verifying no persistence remains. Before unlocking any disabled account, confirm that the post-spray hunt in eradication found and removed all unauthorized changes. Re-enable the account using Enable-ADAccount -Identity username or the IdP console, and immediately require the user to complete a fresh MFA registration through a verified, out-of-band channel.
  • Re-image any host where post-spray compromise activity was confirmed, rather than attempting to clean in place. If your investigation found evidence of code execution, lateral movement, or tool deployment on a host following a successful spray, treat it as fully compromised. Rebuild from a known-good image, restore data from pre-incident backup, and validate the rebuild before returning it to production.
  • Monitor affected accounts and source systems intensively for 72 hours post-remediation. Create temporary, high-sensitivity detection rules in your SIEM scoped to the affected accounts and previously targeted systems. Alert on any authentication from new locations, any new MFA device registration, any sensitive data access, and any outbound connection to external IPs. This monitoring window catches delayed attacker re-entry attempts using credentials or tokens harvested before containment.
  • Communicate to affected users with clear, non-alarming guidance. Notify users whose accounts were targeted or disabled — even if not confirmed compromised — that their password has been reset as a precaution and that they should report any unusual account activity they noticed before the reset. This surfaces any user-observed indicators that did not appear in your logs.
  • Document the full incident timeline and update your detection rules with new IOCs. Record the start time, detection time, containment time, and all affected accounts, IPs, and systems. Add the spray source IPs to your permanent threat intelligence blocklist. Publish a brief lessons-learned summary covering what the spray targeted, how it was detected, what the dwell time was, and what detection or configuration gaps enabled the attempt — then close the incident formally.

Stay Ahead

Get daily threat intelligence and detection playbooks.

Free. No account. No email. Follow in Feedly, Inoreader, or any RSS reader.