Detect Password Spraying in Splunk
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/
SPL Detection Query
index=wineventlog sourcetype="WinEventLog:Security" EventCode=4625
| where LogonType="3" OR LogonType="10"
| where IpAddress!="127.0.0.1" AND IpAddress!="-" AND IpAddress!="" AND IpAddress!="::1"
| bucket _time span=30m
| stats
count as FailureCount,
dc(TargetUserName) as DistinctAccounts,
values(TargetUserName) as TargetAccounts,
earliest(_time) as FirstSeen,
latest(_time) as LastSeen,
values(WorkstationName) as SourceWorkstations
by IpAddress, _time
| where DistinctAccounts >= 10
| eval AvgFailuresPerAccount=round(FailureCount/DistinctAccounts, 2)
| where AvgFailuresPerAccount <= 5
| eval SprayDurationMinutes=round((LastSeen - FirstSeen) / 60, 1)
| sort - DistinctAccounts
| table _time, IpAddress, FailureCount, DistinctAccounts, AvgFailuresPerAccount, SprayDurationMinutes, TargetAccounts, SourceWorkstations Detects on-premises Active Directory password spraying using Windows Security Event ID 4625 (failed logon). Groups failed authentication events by source IP address in 30-minute buckets and identifies sources attempting authentication against 10 or more distinct accounts. The AvgFailuresPerAccount threshold (<=5) distinguishes spray behavior from brute force: spraying is characterized by breadth across many accounts, not depth against individual accounts. LogonType 3 (Network) and 10 (RemoteInteractive) capture the most common remote authentication spray patterns, including SMB, RDP, and LDAP. SprayDurationMinutes provides context on whether the spray was rapid (automated tool) or slow and throttled (APT-style evasion).
Data Sources
Required Sourcetypes
False Positives & Tuning
- Misconfigured service accounts with stale credentials cycling authentication failures across multiple systems during an outage or config change
- Network vulnerability scanners performing authenticated scans with credentials that have expired or changed
- ADFS or reverse proxy infrastructure where a single source IP represents all federated authentications for many users
- Load balancers performing health check authentication against multiple backend nodes that simultaneously fail when a password rotation occurs
- Domain controllers appearing as source IPs during Kerberos delegation or pass-through authentication cascades
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.
- 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.
- 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.
- 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.
- 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.
References (13)
- https://attack.mitre.org/techniques/T1110/003/
- https://www.trimarcsecurity.com/single-post/2018/05/06/Trimarc-Research-Detecting-Password-Spraying-with-Security-Event-Auditing
- https://www.microsoft.com/en-us/security/blog/2024/10/31/chinese-threat-actor-storm-0940-uses-credentials-from-password-spray-attacks-from-a-covert-network/
- http://www.blackhillsinfosec.com/?p=4645
- https://www.us-cert.gov/ncas/alerts/TA18-086A
- https://github.com/dafthack/MSOLSpray
- https://github.com/dafthack/MailSniper
- https://github.com/ropnop/kerbrute
- https://github.com/GhostPack/Rubeus
- https://learn.microsoft.com/en-us/azure/active-directory/reports-monitoring/concept-sign-ins
- https://learn.microsoft.com/en-us/azure/active-directory/reports-monitoring/reference-sign-ins-error-codes
- https://www.microsoft.com/en-us/security/blog/2021/06/25/nobelium-attacking-more-than-150-organizations/
- https://github.com/byt3bl33d3r/CrackMapExec
Unlock Pro Content
Get the full detection package for T1110.003 including response playbook, investigation guide, and atomic red team tests.