Skip to main content
See Security Labs

SEC504 - Hacker Tools, Techniques, and Incident Handling

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

Solo, Lab

Focus: Password Management & Cryptography

Level: SEC504

Date: Aug 2026

Artifacts: Sanitized Hashcat output against Linux shadow hashes and an extracted Active Directory NTDS.dit from the SEC504 lab (CPU-only)

TL;DR

  • hashcat --identify plus the attack-mode ladder cracked Linux shadow and Active Directory NTLM hashes
  • All 2,258 AD accounts shared the empty LM hash; cracked NTLM passwords were Password1-4 and seasonal patterns
  • A best64 rule attack cracked 105/1,845 in 4 seconds, beating a 6-minute mask run: rules give the best value

Skills demonstrated

Hash identification (hashcat --identify, autodetect)Dictionary, mask, and rule-based attack modes (-a 0/-a 3/-r)NTDS.dit extraction with secretsdump.pyResult management (--show, --left, --username)Reading crack results as a password-policy audit

Note: Course-provided PCAPs and lab instructions are not shared. Only my own captures and sanitized notes are published.

Why this matters

Offline cracking is what happens after a hash dump, and the results here are a direct readout of password policy: the cracked passwords were seasonal patterns and Password1 through Password4, which no wordlist invents, they exist because policy allowed them. The attack-mode ladder matters because rules turned 44,488 words into 3.4 million candidates in four seconds and out-cracked a mask attack that ran for six minutes. For a defender, the lesson is that the crack rate is set by your password policy, not by the attacker's wordlist.

Context

This lab works the Hashcat attack-mode ladder against two real hash sources: Linux shadow-file hashes and an Active Directory NTDS.dit dumped with secretsdump.py. It moves from identifying hash types, through a straight dictionary attack, to a mask attack against a known password pattern, to a rule-based attack, and shows why rules give the best value per second. All CPU-only, which makes the speed differences between attack modes obvious.

Tools used

Hashcat 6.2.5secretsdump.py (Impacket)awksedSlingshot Linux

Steps taken

1Identify 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
--identifylist candidate -m modes for the input

2Dictionary 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 0dictionary
--showprint cracked from potfile
--usernameinclude the account

3List 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
--leftshow hashes not yet in the potfile

4Extract 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
LOCALparse offline files
-historyinclude password history

5Analyze 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 $3the LM hash column
sed '/$/d'drop machine accounts

6Dictionary, 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 rulesmangle 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

Outcome / Lessons learned

Cracked Linux shadow hashes and Active Directory NTLM hashes with the full Hashcat attack-mode ladder. The AD results were a password-policy readout: Password1 through Password4, Welcome1, and seasonal patterns. A best64 rule attack cracked 105/1,845 hashes in four seconds, out-performing a six-minute mask run.

Treat the crack results as a policy audit: ban Password1-style and seasonal patterns with a password filter and screen against breached-password lists, because those are what cracked. Enforce length over complexity (passphrases resist dictionary+rule attacks far better than 8-char patterns), and deploy MFA so a cracked hash is not game over. Confirm LM is disabled everywhere (the empty LM hash here shows it was) and protect NTDS.dit and the SYSTEM hive as the crown-jewel files they are.

Security controls relevant

  • 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

What I took away from this

The crack rate is a readout of your password policy, not the attacker's skill. Password1 through Password4 and Autumn2020 are not in any clever wordlist by accident, they are there because rules generate exactly the patterns that a complexity policy permits and users reach for. If those crack, the fix is a password filter and length requirements, not a better firewall.

The attack-mode ladder has a clear winner. A dictionary attack is cheap but shallow; a mask attack is precise but slow when you guess the pattern; rules are the sweet spot, turning 44,488 words into 3.4 million candidates in four seconds and out-cracking a six-minute mask run. Understanding that ordering is what lets an analyst estimate how exposed a given hash set really is, and how fast.

Evidence gallery

Offline Password Cracking with Hashcat: Shadow Files and Active Directory NTDS | Luis Javier Lozoya