Cracking Password Hashes with John the Ripper

Tutorial · Crypto

A CTF challenge hands you a string like 5f4dcc3b5aa765d61d8327deb882cf99 and tells you it's a password hash — your job is to recover the original text. John the Ripper ("john") is the standard tool for this: it takes a hash, guesses candidate passwords using a wordlist or a set of rules, hashes each guess the same way, and checks for a match. This tutorial covers the workflow you'll reuse on nearly every hash-cracking challenge.

1. Identify the hash format

Cracking starts with knowing what you're looking at — an MD5 hash, a SHA-256 hash, and a bcrypt hash all need to be attacked differently. hashid gives a quick guess based on length and character set:

hashid '5f4dcc3b5aa765d61d8327deb882cf99'

It'll usually offer a few candidates ranked by likelihood — a 32-character hex string is almost always MD5, a 64-character one is usually SHA-256. When a challenge tells you the format directly (a common courtesy in CTFs), skip this step and go straight to cracking.

2. Save the hash in John's format

Put the hash in a text file, one per line:

echo '5f4dcc3b5aa765d61d8327deb882cf99' > hash.txt

For most raw hash types this is enough. Some formats (shadow file entries, ZIP or PDF passwords, SSH keys) need a matching *2john helper script first — zip2john, pdf2john.py, ssh2john.py — to convert the file into a hash John understands before you can crack it.

3. Run a wordlist attack

rockyou.txt — a leaked password list with roughly 14 million entries — is the default starting point for almost any CTF hash:

john --format=raw-md5 --wordlist=rockyou.txt hash.txt

Drop --format if you're not sure and let John auto-detect, though being explicit avoids it guessing the wrong variant when a hash type is ambiguous. Once it finds a match, retrieve it with:

john --show hash.txt

4. When the wordlist alone doesn't work

If plain rockyou.txt comes up empty, two things usually help before giving up: apply John's built-in mangling rules, which try common variations (capitalization, appended numbers, leetspeak substitutions) on every wordlist entry —

john --format=raw-md5 --wordlist=rockyou.txt --rules hash.txt

— or, if the challenge hints at a small keyspace (a 4-digit PIN, a short known-length password), switch to an incremental brute-force instead of a wordlist:

john --format=raw-md5 --incremental hash.txt

Wrapping up

Identify the format, get the hash into a file John can read, run rockyou.txt first, and reach for rules or incremental mode only once a plain wordlist attack fails. That order — cheapest attack first — is what keeps hash-cracking challenges fast instead of turning into an overnight brute-force. For the broader toolkit each CTF category expects, see the Getting Started with CTF guide, and browse writeups for full challenge walkthroughs.

Back to Blog