⚠️ Educational Use Only — Password hash cracking must only be performed on hashes you are authorized to test (hashes from systems you own, authorized penetration test targets, or purpose-built lab environments). Cracking credentials without authorization is illegal. These skills teach defenders to recognize weak password policies and improve them.
When to Use
- After obtaining a password hash file from an authorized penetration test target (e.g.,
/etc/shadowdump, database credential leak) - During CTF challenges where a hash is provided as part of the challenge
- When auditing an organization's password policy strength by cracking a sanitized sample of their hashed passwords
- When learning the difference between weak hashing algorithms (MD5, SHA1) and strong ones (bcrypt, Argon2)
- As a prerequisite for understanding credential stuffing, pass-the-hash, and authentication bypass techniques
Prerequisites
- Software: Docker + Docker Compose (Hashcat + John pre-installed)
- Knowledge: What a hash function is, why passwords should be hashed and not stored in plaintext
- Lab:
labs/cryptography/hash-cracking-lab— start withagentlab start hash-cracking-lab - Difficulty: Beginner — no cryptography background required
- Time: 25–40 minutes
Workflow
Step 1: Start the Lab
agentlab start hash-cracking-lab
agentlab exec hash-cracking-lab bash
# A file /lab/hashes.txt is pre-populated with the challenge hashes
cat /lab/hashes.txt
Step 2: Identify Hash Types
Before cracking, identify the hash algorithm:
# Use hash-identifier
hash-identifier
# Or use hashid
hashid /lab/hashes.txt
# Or recognize by length/format:
# MD5: 32 hex chars e.g., 5f4dcc3b5aa765d61d8327deb882cf99
# SHA1: 40 hex chars e.g., 5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8
# SHA256: 64 hex chars
# NTLM: 32 hex chars (same length as MD5, different structure)
# bcrypt: starts with $2a$ or $2b$
Step 3: Dictionary Attack with Hashcat
The most effective cracking technique for common passwords:
# MD5 dictionary attack (mode 0)
hashcat -m 0 /lab/hashes.txt /usr/share/wordlists/rockyou.txt
# SHA1 dictionary attack (mode 100)
hashcat -m 100 /lab/hashes.txt /usr/share/wordlists/rockyou.txt
# NTLM dictionary attack (mode 1000)
hashcat -m 1000 /lab/hashes.txt /usr/share/wordlists/rockyou.txt
# bcrypt dictionary attack (mode 3200) — much slower
hashcat -m 3200 /lab/hashes.txt /usr/share/wordlists/rockyou.txt
# Show cracked hashes
hashcat -m 0 /lab/hashes.txt --show
Step 4: Rule-Based Attack
Wordlist + mutation rules dramatically expand coverage:
# Apply best64 rules to rockyou (adds common mutations: password1, Password!, etc.)
hashcat -m 0 /lab/hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
# OneRuleToRuleThemAll (more comprehensive)
hashcat -m 0 /lab/hashes.txt /usr/share/wordlists/rockyou.txt -r /lab/OneRuleToRuleThemAll.rule
Step 5: John the Ripper
John the Ripper auto-detects hash types and has built-in wordlists:
# Auto-detect and crack
john /lab/hashes.txt
# Use specific wordlist
john --wordlist=/usr/share/wordlists/rockyou.txt /lab/hashes.txt
# Show cracked
john --show /lab/hashes.txt
# Crack /etc/shadow format (lab provides a sample)
john --wordlist=/usr/share/wordlists/rockyou.txt /lab/shadow.txt
Step 6: Crack the Salted Hash
The lab includes a salted MD5 hash. Identify the format:
$apr1$xyz$<hash> — Apache MD5
$1$xyz$<hash> — Linux MD5 crypt
# Hashcat mode for md5crypt (linux shadow)
hashcat -m 500 /lab/shadow_hash.txt /usr/share/wordlists/rockyou.txt
Step 7: Capture the Flag
The flag is the plaintext password of the admin hash in /lab/hashes.txt:
hashcat -m 0 /lab/hashes.txt /usr/share/wordlists/rockyou.txt --show
# Output: 5f4dcc3b5aa765d61d8327deb882cf99:password
Submit: agentlab verify hash-cracking-lab "password"
Key Concepts
| Concept | Definition |
|---|---|
| Hash Function | One-way mathematical function that converts input to a fixed-size digest — cannot be reversed |
| Salt | Random value prepended/appended before hashing to prevent rainbow table attacks |
| Dictionary Attack | Hashing words from a wordlist and comparing against the target hash |
| Rule-Based Attack | Applying mutation rules (append numbers, capitalize, etc.) to wordlist entries |
| Brute Force | Systematically trying all possible character combinations — effective only for short passwords |
| Rainbow Table | Pre-computed hash→plaintext table — defeated by salts |
| bcrypt / Argon2 | Modern, intentionally slow hashing algorithms designed to resist cracking |
| T1110.002 | MITRE ATT&CK: Password Cracking |
Tools
| Tool | Purpose | Lab Availability |
|---|---|---|
hashcat |
GPU-accelerated hash cracking | ✅ Pre-installed (CPU mode in lab) |
john |
CPU-based cracking with auto hash detection | ✅ Pre-installed |
hash-identifier |
Identifies hash algorithm from format/length | ✅ Pre-installed |
hashid |
Python-based hash type identifier | ✅ Pre-installed |
| RockYou.txt | 14M real-world leaked passwords wordlist | ✅ Pre-installed at /usr/share/wordlists/ |
Common Scenarios
Scenario 1: Database Dump with MD5 Passwords
# hashes.txt content from a simulated DB dump:
# admin:5f4dcc3b5aa765d61d8327deb882cf99
# user1:d8578edf8458ce06fbc5bb76a58c5ca4
hashcat -m 0 hashes.txt rockyou.txt --username
# Cracks: admin:password, user1:qwerty
Takeaway: 80%+ of common passwords crack within minutes against MD5. MD5 must never be used for passwords.
Scenario 2: Auditing Password Policy Strength
Given a sanitized sample of bcrypt hashes from an authorization holder:
hashcat -m 3200 sample_hashes.txt rockyou.txt -r best64.rule
If any crack within 24 hours, the organization's password policy is too weak.
Scenario 3: NTLM Hashes from Windows Environment
# Format: username:RID:LMhash:NThash:::
# Example: Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
hashcat -m 1000 nt_hashes.txt rockyou.txt
Output / Verification
agentlab verify hash-cracking-lab "<plaintext-password>"
Score: 100 points per cracked hash (5 hashes total in lab)