Skip to main content
← Back to lab
SEC504 - Hacker Tools, Techniques, and Incident Handling | Printable command sheet
Offline Password Cracking with Hashcat: Shadow Files and Active Directory NTDS

Offline Password Cracking with Hashcat: Shadow Files and Active Directory NTDS

Password Management & Cryptography | SEC504 | Aug 2026

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.

Tools: Hashcat 6.2.5, secretsdump.py (Impacket), awk, sed, Slingshot Linux

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
--identify: list candidate -m modes for the input

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
-a 0: dictionary --show: print cracked from potfile --username: include the account

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
--left: show hashes not yet in the potfile

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
LOCAL: parse offline files -history: include password 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.ntds
awk $3: the LM hash column sed '/$/d': drop machine accounts

6. 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
-a 0 dictionary -a 3 mask (?u upper ?l lower ?d digit) -r rules: mangle each word

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
Lab Print Sheet | Luis Javier Lozoya