Password Spraying
Password spraying tries one password against many accounts rather than many passwords against one account. This avoids lockout because each individual account only receives one failed attempt per spray round. The maximum safe number of attempts per round is always lockout threshold minus one. Never reach the threshold.
Read the domain password policy before starting. See Password Policy and Spray Surface for how to extract threshold and observation window values.
Build a username list
Spray requires a username list. Pull it from LDAP enumeration using any authenticated account, or from earlier object enumeration output.
247 users.txt
Spray over SMB
SMB spray is the most common starting point. Use --continue-on-success so nxc does not stop on the first hit. Watch for STATUS_PASSWORD_MUST_CHANGE alongside failures — that is a valid account with an expired password, still useful.
SMB 10.10.10.10 445 DC01 [-] corp.local\jdoe:Password123! STATUS_LOGON_FAILURE SMB 10.10.10.10 445 DC01 [+] corp.local\svc-backup:Password123!
Spray over LDAP
LDAP spray produces less noise on some configurations than SMB and does not require SMB to be accessible. Use this as an alternative when SMB is filtered or when you want to avoid SMB-specific detections.
LDAP 10.10.10.10 389 DC01 [-] corp.local\jdoe:Password123! INVALID_CREDENTIALS LDAP 10.10.10.10 389 DC01 [+] corp.local\svc-backup:Password123!
Spray timing
When the lockout threshold is 5, spray a maximum of 4 passwords per observation window. Wait for the full observation window to expire between rounds so every account's counter resets before the next attempt.
Example: threshold 5, observation window 30 minutes. You can spray 4 passwords at once, then wait 30 minutes before the next round. If the threshold is 0, there is no lockout — spray freely.
Interpret results
STATUS_LOGON_FAILURE is a wrong password. STATUS_ACCOUNT_LOCKED_OUT means you hit the threshold on that account — stop immediately and wait for the lockout duration to expire. STATUS_PASSWORD_MUST_CHANGE is a valid set of credentials where the password has expired — the account is usable after a password change. STATUS_ACCOUNT_DISABLED confirms the account exists but cannot authenticate.
After finding valid credentials, run Object Enumeration from the new account context before attempting further access. With confirmed credentials, lateral movement paths include Pass-the-Hash over SMB, Evil-WinRM for WinRM access, and RDP Brute Force and Password Spray if RDP is exposed.
References
-
NetExec (nxc) — GitHubgithub.com/Pennyw0rth/NetExec (opens in new tab)
SMB and LDAP spray with --continue-on-success flag reference
Was this helpful?
Your feedback helps improve this page.