| name | crypto-hash-cracking |
| description | How to crack hashes, perform length extension attacks, and break weak password hashing in CTFs. Use this skill whenever the user mentions hash cracking, password recovery, signature forgery, HMAC, MD5, SHA, bcrypt, hashcat, John the Ripper, or any CTF challenge involving cryptographic hashes. Make sure to use this skill for any challenge that involves identifying hash types, cracking password hashes, or exploiting hash length extension vulnerabilities. |
Crypto Hash Cracking
A skill for cracking hashes, performing length extension attacks, and breaking weak password hashing in CTF challenges.
Common CTF Patterns
Watch for these telltale signs:
- "Signature" is actually
hash(secret || message) → length extension attack possible
- Unsalted password hashes → trivial cracking via lookup tables
- Confusing hash with MAC → hash provides no authentication guarantee
- Fast hashes (MD5/SHA1/SHA256) for passwords → vulnerable to brute force
- Same password reused across users → crack one, pivot to others
Hash Length Extension Attack
When to use this
You can exploit length extension when a server computes signatures like:
sig = HASH(secret || message)
using Merkle–Damgård hashes (MD5, SHA-1, SHA-256, SHA-384, SHA-512).
What you need
- The original
message
- The original
sig (hash output)
- The hash function used
- The length of the secret (or ability to brute-force it)
What you get
A valid signature for:
message || padding || appended_data
without knowing the secret.
Important: HMAC is NOT affected
Length extension attacks do NOT work on HMAC (e.g., HMAC-SHA256). HMAC is specifically designed to prevent this attack. If you see HMAC-SHA256 or similar, this technique won't work.
Tools
hash_extender (Python, most common):
pip install hash_extender
hash_extender -h sha256 -s <original_sig> -m "<original_message>" -p "<appended_data>" -l <secret_length>
hashpump (Node.js):
npm install -g hashpump
hashpump -h sha256 -s <original_sig> -m "<original_message>" -a "<appended_data>" -l <secret_length>
Workflow
- Confirm the vulnerability: Check if the signature is
HASH(secret || message) not HMAC(secret, message)
- Identify the hash: Use
hashid or pattern matching
- Estimate secret length: Try common lengths (1-64 bytes) or brute-force
- Run the tool: Use hash_extender or hashpump
- Test the forged signature: Submit to the target
Password Hashing and Cracking
Step 1: Identify the hash
First, figure out what you're dealing with:
hashid <hash>
hashcat --example-hashes | rg -n "<pattern>"
Step 2: Check for salt
Look for salt indicators:
salt$hash format
$ delimiters with multiple sections
- Long hashes with embedded salt
Unsalted hashes are trivial to crack via rainbow tables.
Step 3: Choose your tool
Hashcat (GPU-accelerated, fastest for most cases):
hashcat --help | rg "mode"
hashcat -m <mode> -a 0 hashes.txt wordlist.txt
John the Ripper (simpler, good for crypt formats):
john --wordlist=wordlist.txt hashes.txt
john --wordlist=wordlist.txt --format=<fmt> hashes.txt
john --show hashes.txt
Step 4: Choose attack mode
Dictionary attack (mode 0) - try wordlist:
hashcat -m <mode> -a 0 hashes.txt wordlist.txt
Rule-based attack (mode 0 + rules) - mutate wordlist:
hashcat -m <mode> -a 0 hashes.txt wordlist.txt -r rules/best64.rule
Brute force (mode 3) - try all combinations:
hashcat -m <mode> -a 3 hashes.txt ?a?a?a?a?a?a
Combinator attack (mode 1) - combine two wordlists:
hashcat -m <mode> -a 1 hashes.txt wordlist1.txt wordlist2.txt
Step 5: Optimize for speed
hashcat -m <mode> -a 0 hashes.txt wordlist.txt --force
hashcat -m <mode> -a 0 hashes.txt wordlist.txt --work-load=high
hashcat -m <mode> -a 0 hashes.txt wordlist.txt -s <session_name>
hashcat -m <mode> -a 0 hashes.txt wordlist.txt -r <session_name>
Common Exploitable Mistakes
Weak KDF parameters
Some systems use KDFs with weak parameters:
- PBKDF2 with low iterations (< 10000) → still crackable
- bcrypt with low cost (< 10) → faster to crack
- scrypt with low N → vulnerable
Truncated hashes
If you see truncated hashes (e.g., only first 8 chars):
- Normalize the format
- Adjust your cracking tool accordingly
- Expect more collisions
Custom transforms
Watch for:
- Double hashing:
hash(hash(password))
- Salted but predictable:
hash(password + "static_salt")
- Reversed:
hash(reverse(password))
Quick Reference
Hashcat mode numbers
| Hash Type | Mode |
|---|
| MD5 | 0 |
| MD4 | 1 |
| SHA1 | 100 |
| SHA256 | 1400 |
| SHA512 | 1700 |
| bcrypt | 3200 |
| PBKDF2-SHA256 | 1800 |
| PBKDF2-SHA512 | 1700 |
| NTLM | 1000 |
| LM | 3000 |
John formats
| Hash Type | Format |
|---|
| MD5 | md5 |
| SHA1 | sha1 |
| SHA256 | sha256crypt |
| SHA512 | sha512crypt |
| bcrypt | bcrypt |
| NTLM | netntlm |
Tools to Install
pip install hashid
sudo apt install hashcat john
pip install hash_extender
npm install -g hashpump
sudo apt install wordlists
Debugging Tips
- Hash not cracking? Try different wordlists or rule sets
- Wrong format? Double-check with
hashid or manual inspection
- Too slow? Use GPU acceleration, reduce search space
- Length extension failing? Verify it's not HMAC, check secret length
- Session management? Use
-s flag to save/restore hashcat sessions