Offline Password Cracking with Hashcat: Shadow Files and Active Directory NTDS
Identified Linux hashes with hashcat --identify (descrypt 1500, md5crypt 500, sha256/512crypt), then cracked them with a dictionary attack, recovering beva:Spring23, jorestes:Qwertyu1, and hrio:12345678, using --show --username to display results and --left to list what remained. For the AD side, secretsdump.py extracted NTDS.dit; awk revealed all 2,258 accounts shared the empty LM hash (aad3b435b51404eeaad3b435b51404ee), and sed stripped machine accounts. A dictionary attack against the NTLM hashes recovered 46/1,845 (Password1-4, Welcome1, seasonal patterns). A mask attack (?u?l?l?l?l?l?l?d) pushed it to 95/1,845, and a best64 rule attack reached 105/1,845 in four seconds, beating the six-minute mask run.
Commands
1. Identify the hash types
hashcat --identify returned four candidate modes for the shadow file (descrypt 1500, md5crypt 500, sha256crypt 7400, sha512crypt 1800). The /etc/passwd-style lines throw a token-length exception, which is expected: those lines have no crackable hash.
hashcat slingshot.hashes --identify
2. Dictionary attack and show results
A straight dictionary attack (-a 0 -m 1500) against the descrypt hashes, then --show --username to display the cracked pairs: beva:Spring23, jorestes:Qwertyu1, hrio:12345678. --show reads the potfile so results survive between runs.
hashcat -a 0 -m 1500 slingshot.hashes /usr/share/wordlists/passwords.txt hashcat -m 1500 slingshot.hashes --show --username
3. List what remains
--left prints the hashes still uncracked (lrenate, rkaede, asayaka, alucasta), which tells you exactly where to point the next, more expensive attack instead of re-running the whole set.
hashcat -m 1500 slingshot.hashes --left --username
4. Extract NTLM hashes from NTDS.dit
secretsdump.py parsed the extracted Active Directory database and SYSTEM hive locally, writing NTLM hashes (with history). This is the offline-cracking input that matters most in a domain compromise: every account's password hash in one file.
secretsdump.py -system registry/SYSTEM -ntds "Active Directory/ntds.dit" LOCAL -outputfile w99 -history
5. Analyze LM hashes and strip machine accounts
awk on the LM-hash column showed all 2,258 accounts share aad3b435b51404eeaad3b435b51404ee, the empty LM hash, which means LM is disabled (good). sed then stripped machine accounts (names ending in $) so the crack focuses on user passwords.
cat w99.ntds | awk -F: '{print $3}' | sort | uniq -c
sed -i '/\$/d' w99.ntds6. Dictionary, then mask, then rules
Autodetect resolved the hashes as NTLM (mode 1000). A dictionary attack cracked 46/1,845 (Password1-4, Welcome1, seasonal). A mask attack (?u?l?l?l?l?l?l?d, an 8-char Upper+6lower+digit pattern) reached 95/1,845 but took six minutes. A best64 rule attack cracked 105/1,845 in four seconds, expanding 44,488 words into 3.4 million candidates. Rules gave the best value by a wide margin.
hashcat -a 0 w99.ntds /usr/share/wordlists/passwords.txt hashcat -a 3 w99.ntds ?u?l?l?l?l?l?l?d hashcat -a 0 w99.ntds /usr/share/wordlists/passwords.txt -r /opt/hashcat/rules/best64.rule
Key Findings
- All 2,258 AD accounts shared the empty LM hash (aad3b435b51404eeaad3b435b51404ee): LM disabled
- Dictionary attack cracked 46/1,845 NTLM: Password1-4, Welcome1, seasonal patterns
- Mask attack (?u?l?l?l?l?l?l?d) reached 95/1,845 in ~6 minutes
- best64 rule attack reached 105/1,845 in 4 seconds (44,488 words -> 3.4M candidates)
- Cracked passwords were policy artifacts, not wordlist inventions
Security Controls
- Password filters banning seasonal and Password<N> patterns
- Breached-password screening
- Length-based policy (passphrases) over 8-char complexity
- MFA to blunt cracked-credential impact
- NTDS.dit / SYSTEM hive protection and access monitoring