Introduction
Hash cracking is one of the most common skills tested in CTF competitions, appearing in cryptography, forensics, and general skills categories alike. A cryptographic hash function takes an input of any length and produces a fixed-length digest. Hash functions are designed to be one-directional: given a hash, you should not be able to recover the original input through a mathematical shortcut. Cracking means finding that input anyway, by computing hashes of candidate inputs until one matches.
Hash cracking appears in CTF challenges in several forms:
- A file or challenge description contains a raw hex digest; you must reverse it to a password or flag.
- A login form in a web challenge stores passwords as MD5 or SHA-1 hashes; cracking the hash lets you log in.
- A forensics challenge gives you a shadow file or NTLM dump; cracking it recovers the credential.
- The flag itself is the cracked plaintext, not the hash.
This guide walks through every tool and technique you need: recognizing hash types by their digest length, using online rainbow tables for quick wins, running hashcat and John the Ripper locally for anything not already in a database, and applying a systematic workflow so you never waste time on the wrong approach.
Related guides on this site
Hashes are often base64- or hex-encoded before being presented in a challenge. The encodings guide covers decoding that outer layer. The RSA guide covers the broader cryptography context where hashing is used for digital signatures.
Hash types and recognition
The fastest way to identify an unknown hash is by its length. Each algorithm always produces a fixed number of hex characters (two hex chars per byte). Here is what to look for:
| Algorithm | Hex chars | Bytes | Example prefix / pattern |
|---|---|---|---|
| MD5 | 32 | 16 | d41d8cd98f00b204... |
| SHA-1 | 40 | 20 | da39a3ee5e6b4b0d... |
| SHA-224 | 56 | 28 | d14a028c2a3a2bc9... |
| SHA-256 | 64 | 32 | e3b0c44298fc1c14... |
| SHA-384 | 96 | 48 | 38b060a751ac9638... |
| SHA-512 | 128 | 64 | cf83e1357eefb8bd... |
| NTLM | 32 | 16 | 31d6cfe0d16ae931... (all lowercase) |
| bcrypt | 60 | N/A | $2b$12$... (always starts with $2) |
| sha512crypt | variable | N/A | $6$salt$... (Linux /etc/shadow) |
| MD5crypt | variable | N/A | $1$salt$... (older Linux shadow) |
MD5 and SHA-1: broken for collisions, not for cracking
You will often read that MD5 and SHA-1 are "broken". This refers to collision attacks: a researcher can craft two different inputs that produce the same hash. That does not help you crack a hash in a CTF. For CTF purposes, MD5 and SHA-1 are broken in a different and more practical sense: they are fast to compute, so GPUs can test billions of candidates per second, and most common passwords already appear in public databases like CrackStation.
SHA-256 is not broken in either sense. It has no known collision, and it is fast enough that GPU cracking is still feasible. The difference is purely probabilistic: SHA-256 hashes of common passwords are far less likely to appear in pre-computed databases, so you rely on wordlists and rules rather than simple lookup.
bcrypt: intentionally slow
bcrypt is a password hashing scheme designed to be slow. The $2b$12$ prefix means 2^12 = 4096 rounds of the Blowfish key setup. A modern GPU can test roughly 20,000 bcrypt candidates per second (versus billions for MD5). In a CTF, bcrypt challenges are almost always solvable with a short wordlist or a top-10000 password list rather than a brute-force mask attack. Online tools like CrackStation will not help you with bcrypt at all: the cost of pre-computing a bcrypt rainbow table is prohibitive.
NTLM hashes from Windows
NTLM is the hash format Windows uses to store local account passwords. It is just MD5 with a different algorithm (actually MD4 of the UTF-16LE password), so it is equally fast to crack. NTLM hashes look exactly like MD5 hashes (32 lowercase hex chars). The context gives them away: if you extracted them from a Windows SAM dump, a memory image, or a challenge mentioning Windows credentials, assume NTLM and use -m 1000 in hashcat.
Rainbow tables and salting
A rainbow table is a pre-computed lookup structure that maps hash values back to their plaintexts. Instead of storing every hash-to-plaintext pair (which would require enormous storage), rainbow tables use chains of alternating hash and reduction functions to compress billions of entries into a manageable file.
For a CTF player, the practical upshot is simple: sites like CrackStation have already computed the MD5, SHA-1, and SHA-256 hashes of every word in large password lists and every permutation up to a certain length. If the plaintext is a common word or password, you paste the hash and get the answer in under a second.
Why salted hashes defeat rainbow tables
A salt is a random value prepended or appended to the password before hashing: hash(salt + password). Because each user gets a unique salt, a pre-computed table that maps hash("password123") to its plaintext is useless. You would need a separate table for every possible salt, which is not feasible.
In CTF challenges, you can tell whether a hash is salted by the format:
- A bare 32-character hex string is almost certainly an unsalted MD5. Try CrackStation immediately.
- A string starting with
$1$,$2b$,$5$, or$6$is a salted hash in Modular Crypt Format. The salt is embedded in the string itself, so hashcat and John the Ripper can extract it automatically. - If the challenge provides both a salt and a hash separately, construct the input yourself:
echo -n "salthello" | md5sum.
$2, skip online tools entirely and go straight to hashcat or John with a targeted wordlist.Hashcat
Hashcat is the fastest GPU-accelerated password cracker available. It supports hundreds of hash types via -m mode numbers and several attack modes. When online lookup fails, hashcat is the next tool to reach for.
Installation
# Ubuntu / Debiansudo apt install hashcat# macOS (with Homebrew)brew install hashcat# Verify GPU is recognizedhashcat -I
The -m flag: hash type numbers
Every hashcat command requires -m <number> to tell it which algorithm to use. The most common values you will need in picoCTF:
| -m value | Hash type | Notes |
|---|---|---|
| 0 | MD5 | Most common in CTF, also the fastest |
| 100 | SHA-1 | 40 hex chars; also fast |
| 1400 | SHA-256 | 64 hex chars; slower than MD5 but still GPU-friendly |
| 1700 | SHA-512 | 128 hex chars; noticeably slower per-candidate |
| 1000 | NTLM | Windows password hashes; same length as MD5 |
| 3200 | bcrypt | Very slow; use a small targeted wordlist |
| 1800 | sha512crypt ($6$) | Linux shadow file passwords |
| 500 | MD5crypt ($1$) | Older Linux shadow file passwords |
| 10 | md5($pass.$salt) | Hash the password then append salt |
| 20 | md5($salt.$pass) | Prepend salt then hash |
Attack mode 0: wordlist (dictionary) attack
The dictionary attack hashes every line in a wordlist and compares against your target. This is the most effective first attempt for any CTF hash. The rockyou.txt wordlist (14 million real-world passwords) cracks the majority of CTF hashes.
# Basic wordlist attack on an MD5 hashhashcat -m 0 -a 0 hash.txt /usr/share/wordlists/rockyou.txt# SHA-256 with rockyouhashcat -m 1400 -a 0 hash.txt /usr/share/wordlists/rockyou.txt# bcrypt with a targeted top-passwords listhashcat -m 3200 -a 0 hash.txt /usr/share/wordlists/rockyou.txt# hash.txt contains one hash per line:# 5f4dcc3b5aa765d61d8327deb882cf99
Rule-based attacks
Rules transform each wordlist entry before hashing: capitalize the first letter, append numbers, substitute letters with symbols, etc. Hashcat ships with several built-in rule files. The best64.rule file applies 64 of the most effective transformations and dramatically increases coverage without needing a larger wordlist.
# Apply best64 rules to rockyou wordlisthashcat -m 0 -a 0 hash.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule# Stack multiple rule fileshashcat -m 0 -a 0 hash.txt /usr/share/wordlists/rockyou.txt \-r /usr/share/hashcat/rules/best64.rule \-r /usr/share/hashcat/rules/toggles1.rule
Attack mode 3: mask (brute-force) attack
A mask attack generates every combination that fits a pattern. Use this when you know the password format (e.g., the flag format tells you the answer is 8 lowercase letters followed by 2 digits).
# Charset placeholders:# ?l = lowercase a-z# ?u = uppercase A-Z# ?d = digits 0-9# ?s = special characters# ?a = all printable ASCII# Brute-force all 6-character lowercase passwordshashcat -m 0 -a 3 hash.txt ?l?l?l?l?l?l# 4 digits (PIN brute-force)hashcat -m 0 -a 3 hash.txt ?d?d?d?d# Specific pattern: capital + 5 lowercase + 2 digitshashcat -m 0 -a 3 hash.txt ?u?l?l?l?l?l?d?d# Increment length from 1 to 8 charshashcat -m 0 -a 3 hash.txt --increment --increment-min=1 ?l?l?l?l?l?l?l?l
Useful hashcat flags
--show # Print previously cracked hashes from the potfile--potfile-path # Use a custom potfile location-O # Optimized kernel (faster, but max password length limited to 32)-w 3 # Workload profile: 1=low, 2=default, 3=high, 4=nightmare--status # Print progress updates while running--remove # Remove hashes from the input file once cracked
Wordlists beyond rockyou
The SecLists repository (available on GitHub and pre-installed on Kali/Parrot) contains dozens of specialized wordlists. For CTF challenges that hint at a theme (a challenge named after a movie, a sport, a video game), a domain-specific wordlist can crack the hash in seconds.
# Install SecListssudo apt install seclists# Common locations after install:/usr/share/seclists/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt/usr/share/seclists/Passwords/xato-net-10-million-passwords.txt/usr/share/seclists/Passwords/Leaked-Databases/rockyou-75.txt
--force -D 1 to run on the CPU. Performance will be much lower (MD5: ~50 million/s on CPU vs. ~10 billion/s on a mid-range GPU) but it is enough for short wordlists or simple masks.John the Ripper
John the Ripper(usually called just "john") is the other major password cracker. It has a simpler interface than hashcat and automatically detects many hash formats, which makes it a good choice when you are not sure what you are dealing with or when you need a quick first attempt.
Installation
sudo apt install john# The Jumbo version has more formats (recommended for CTF):sudo apt install john-data
Automatic format detection
John can usually detect the hash type without you specifying it. Just point it at a file containing one hash per line:
# Let john detect the formatjohn hash.txt# View what formats john detectedjohn --show hash.txt# List all supported formatsjohn --list=formats
Specifying the format manually
When john guesses wrong, or when it is ambiguous (NTLM and MD5 have the same length), force the format:
john --format=raw-md5 hash.txtjohn --format=raw-sha1 hash.txtjohn --format=raw-sha256 hash.txtjohn --format=raw-sha512 hash.txtjohn --format=nt hash.txt # NTLMjohn --format=bcrypt hash.txtjohn --format=sha512crypt hash.txt # $6$ Linux shadow
Wordlist mode
# Use rockyou wordlistjohn --wordlist=/usr/share/wordlists/rockyou.txt hash.txt# With format specifiedjohn --format=raw-sha256 --wordlist=/usr/share/wordlists/rockyou.txt hash.txt
Rule-based mangling
John has a powerful built-in rule engine. The --rules flag applies word-mangling rules to each wordlist entry before hashing. Rules are defined in john.conf and cover capitalization, number suffixes, leet substitution, and more.
# Apply default rules to rockyoujohn --wordlist=/usr/share/wordlists/rockyou.txt --rules hash.txt# Use a specific rule set (defined in john.conf)john --wordlist=/usr/share/wordlists/rockyou.txt --rules=Jumbo hash.txt
Incremental (brute-force) mode
When wordlists fail, john can try every combination of characters up to a specified length. This is slow but exhaustive for short passwords:
# Brute-force lowercase alpha up to 6 charsjohn --incremental=lower hash.txt# Brute-force digits onlyjohn --incremental=digits hash.txt# All printable ASCII (very slow beyond 5-6 chars)john --incremental hash.txt
Cracking shadow files and zip archives
John ships with helper utilities that convert protected file formats into john-compatible hash files:
# /etc/shadow (Linux password file)unshadow /etc/passwd /etc/shadow > combined.txtjohn --wordlist=/usr/share/wordlists/rockyou.txt combined.txt# Protected ZIP filezip2john protected.zip > zip.hashjohn --wordlist=/usr/share/wordlists/rockyou.txt zip.hash# Password-protected PDFpdf2john document.pdf > pdf.hashjohn --wordlist=/usr/share/wordlists/rockyou.txt pdf.hash
john --show hash.txt to display all successfully cracked entries. Cracked results are saved to ~/.john/john.pot.Online lookup tools
For unsalted MD5, SHA-1, and SHA-256 hashes, online tools can return the plaintext instantly if the password is common. Always try these first before spinning up hashcat, since they are zero-effort and cover millions of real-world passwords.
CrackStation
The most comprehensive free lookup database. Contains over 15 billion entries covering MD5, SHA-1, SHA-256, and several others. Handles up to 20 hashes at once. URL: crackstation.net
What it can crack:
- MD5, SHA-1, SHA-256, SHA-512, LM, NTLM, MySQL4.1
- Common English words, names, passwords from major leaks (RockYou, LinkedIn, Adobe)
- Simple variations: password123, P@ssw0rd, etc.
What it cannot crack:
- bcrypt hashes (computationally infeasible to pre-compute)
- Any salted hash format ($1$, $2b$, $5$, $6$)
- Obscure or randomly-generated passwords not in its wordlists
- MD5 of a custom string like a CTF flag format (picoCTF{...})
hashes.com
A community-driven hash lookup and cracking service. You can submit hashes to their queue and receive email notification when cracked. Also has a free instant lookup that covers MD5 and NTLM. Useful for NTLM hashes from Windows challenges.
MD5Hashing.net / md5decrypt.net
Smaller databases focused on MD5. Good as a second check if CrackStation misses something. They maintain separate databases contributed by their users over the years.
Niph.net / sha1.online
SHA-1 focused lookup databases. Use after CrackStation returns no result.
Identifying the hash type
When you are handed an unknown digest, you need to determine the algorithm before you can crack it. The two main tools for this are hashid and hash-identifier.
hashid (Python-based)
pip install hashid# Identify a single hashhashid 5f4dcc3b5aa765d61d8327deb882cf99# Output:# Analyzing '5f4dcc3b5aa765d61d8327deb882cf99'# [+] MD2# [+] MD5# [+] MD4# Use -m to show hashcat mode numbershashid -m 5f4dcc3b5aa765d61d8327deb882cf99# Use -j to show john format nameshashid -j 5f4dcc3b5aa765d61d8327deb882cf99
hash-identifier (Kali built-in)
hash-identifier# (interactive: paste hash at the prompt)# Or pipe it in:echo '5f4dcc3b5aa765d61d8327deb882cf99' | hash-identifier
Browser-based tool on this site
If you prefer not to install anything, this site has a hash identification tool that runs entirely in your browser:
Manual identification by length
In practice, counting the hex characters is usually faster than running a tool. Check the quick reference table at the bottom of this page for a one-look guide.
-m 0 and -m 1000 in sequence, or use --identify in hashcat (version 6.2.5+).Decision workflow
Follow this numbered sequence every time you encounter a hash in a CTF challenge. It is ordered from fastest to slowest so you do not waste compute time:
- 1
Identify the hash type
Count the hex characters and check against the reference table. Run
hashid -m <hash>to confirm and get the hashcat mode number. Look for dollar-sign prefixes ($2b$,$6$) that immediately reveal the algorithm and salt. - 2
Check if it is salted
Bare hex = likely unsalted. Dollar-sign format = salted. If salted, skip step 3 and go straight to hashcat or John (they can read the embedded salt automatically).
- 3
Try online lookup (unsalted only)
Paste into CrackStation. If it returns a result, you are done. This takes under 10 seconds and works on the majority of CTF hashes. For NTLM, also try hashes.com.
- 4
Run hashcat with rockyou wordlist
hashcat -m <mode> -a 0 hash.txt /usr/share/wordlists/rockyou.txt. This covers 14 million real passwords and completes in seconds for MD5/SHA-1. - 5
Add rules to the wordlist attack
Append
-r best64.ruleto catch variations like Password1, p@ssword, HELLO123. Then tryrockyou-30000.rulefor broader coverage. - 6
Try SecLists specialized wordlists
Use domain-specific lists if the challenge hints at a theme. A challenge called "Star Wars" probably uses a character name or quote as the password.
- 7
Mask attack if you know the password format
If the challenge hints at a format (e.g., "the answer is a 4-digit PIN" or the flag format gives you length information), use
hashcat -a 3with the appropriate mask. - 8
Re-read the challenge for hints
If nothing has worked, the challenge itself probably contains a hint about the password. Look for names, dates, challenge descriptions, filenames, or any string that could be the answer. Try hashing those strings yourself to verify the algorithm.
picoCTF 2025 hash cracking challenges
These picoCTF 2025 challenges are solved directly with the techniques above. Each writeup walks through the identification, tool selection, and exact commands used.
hashcrack
picoctf-2025-hashcrackA direct hash cracking challenge where you are given a digest and must recover the plaintext. Demonstrates the full workflow: identify the algorithm by length, check CrackStation, and fall back to hashcat with rockyou if needed. A great introductory challenge for understanding hash cracking mechanics.
Hash Only 1
picoctf-2025-hash-only-1An introduction to hashing where you encounter a salted or formatted hash and must determine the correct hashcat mode. Covers recognizing hash format from context and using John with the correct format flag.
Hash Only 2
picoctf-2025-hash-only-2The harder follow-up. Requires either a rule-based attack or a mask attack after the basic wordlist fails. The challenge hints in the description narrow down the password structure, making the mask approach viable.
General approach for all three challenges
# Step 1: identify the hash (count hex chars or use hashid)hashid -m <paste-hash-here># Step 2: try CrackStation (browser) for fast win# Step 3: hashcat with rockyou if online failshashcat -m <mode> -a 0 hash.txt /usr/share/wordlists/rockyou.txt# Step 4: add rules if plain wordlist failshashcat -m <mode> -a 0 hash.txt /usr/share/wordlists/rockyou.txt \-r /usr/share/hashcat/rules/best64.rule# Step 5: view cracked resulthashcat -m <mode> hash.txt --show
Quick reference
Hash recognition table
| Hash type | Hex chars | Hashcat -m | John format | Crackable online? |
|---|---|---|---|---|
| MD5 | 32 | 0 | raw-md5 | Yes (CrackStation) |
| SHA-1 | 40 | 100 | raw-sha1 | Yes (CrackStation) |
| SHA-224 | 56 | 1300 | raw-sha224 | Sometimes |
| SHA-256 | 64 | 1400 | raw-sha256 | Sometimes |
| SHA-512 | 128 | 1700 | raw-sha512 | Sometimes |
| NTLM | 32 | 1000 | nt | Yes (hashes.com) |
| bcrypt ($2b$) | 60 (full string) | 3200 | bcrypt | No |
| sha512crypt ($6$) | varies (full string) | 1800 | sha512crypt | No |
| MD5crypt ($1$) | varies (full string) | 500 | md5crypt | No |
Essential hashcat commands
| Goal | Command |
|---|---|
| MD5 + rockyou wordlist | hashcat -m 0 -a 0 hash.txt rockyou.txt |
| SHA-256 + rockyou + rules | hashcat -m 1400 -a 0 hash.txt rockyou.txt -r best64.rule |
| bcrypt + targeted list | hashcat -m 3200 -a 0 hash.txt rockyou.txt |
| 4-digit PIN brute-force | hashcat -m 0 -a 3 hash.txt ?d?d?d?d |
| 6 lowercase letters | hashcat -m 0 -a 3 hash.txt ?l?l?l?l?l?l |
| Show cracked results | hashcat -m 0 hash.txt --show |
| NTLM + rockyou | hashcat -m 1000 -a 0 hash.txt rockyou.txt |
Essential John commands
| Goal | Command |
|---|---|
| Auto-detect + wordlist | john --wordlist=rockyou.txt hash.txt |
| Force MD5 format | john --format=raw-md5 --wordlist=rockyou.txt hash.txt |
| With rules | john --wordlist=rockyou.txt --rules hash.txt |
| Brute-force lowercase | john --incremental=lower hash.txt |
| Show cracked passwords | john --show hash.txt |
| Linux shadow file | unshadow passwd shadow > c.txt; john c.txt |
All picoCTF hash cracking writeups