Lab Guide
Hands-on exercises: build and run hashcat commands with different parameters.
rockyou.txt wordlist available (or any wordlist of your choice).
Setup: Create Test Hashes
Before starting the exercises, generate some known hashes so you can verify that your commands actually work.
Generate MD5 test hashes
Create a file called test_md5.txt with MD5 hashes of known passwords:
# Linux / macOS
echo -n "password" | md5sum | awk '{print $1}' > test_md5.txt
echo -n "123456" | md5sum | awk '{print $1}' >> test_md5.txt
echo -n "letmein" | md5sum | awk '{print $1}' >> test_md5.txt
echo -n "dragon" | md5sum | awk '{print $1}' >> test_md5.txt
echo -n "sunshine" | md5sum | awk '{print $1}' >> test_md5.txt
On macOS, replace md5sum with md5 -r:
echo -n "password" | md5 -r | awk '{print $1}' > test_md5.txt
echo -n "123456" | md5 -r | awk '{print $1}' >> test_md5.txt
echo -n "letmein" | md5 -r | awk '{print $1}' >> test_md5.txt
echo -n "dragon" | md5 -r | awk '{print $1}' >> test_md5.txt
echo -n "sunshine" | md5 -r | awk '{print $1}' >> test_md5.txt
Create a small wordlist
Create test_wordlist.txt with a few hundred common passwords (or use rockyou.txt). For quick testing, a small list is fine:
printf "password\n123456\nletmein\ndragon\nsunshine\nqwerty\nabc123\nmonkey\nmaster\n" > test_wordlist.txt
Exercise 1 — Basic Dictionary Attack
-m, -a, and -oStep 1: Run a basic MD5 dictionary attack
hashcat -m 0 -a 0 -o results_ex1.txt test_md5.txt test_wordlist.txt
Observe the output. Hashcat should crack all 5 hashes almost instantly.
Step 2: Inspect the results
cat results_ex1.txt
You should see lines in the format hash:password.
Step 3: Change the output format
Re-run with different --outfile-format values and compare:
# Password only
hashcat -m 0 -a 0 -o results_plain.txt --outfile-format 2 test_md5.txt test_wordlist.txt --potfile-disable
# Hash only
hashcat -m 0 -a 0 -o results_hash.txt --outfile-format 1 test_md5.txt test_wordlist.txt --potfile-disable
Note: Use --potfile-disable to prevent hashcat from skipping already-cracked hashes from the potfile.
Self-check: You should have three output files with different formats. Compare them to confirm you understand what each --outfile-format value produces.
Exercise 2 — Mask Attack with Incremental Mode
-a 3 with masks and the -i flagStep 1: Create a hash of a short numeric password
# Hash the password "4521"
echo -n "4521" | md5sum | awk '{print $1}' > test_mask.txt
Step 2: Crack with a fixed-length mask
hashcat -m 0 -a 3 -o results_ex2a.txt test_mask.txt ?d?d?d?d
This tries all 4-digit combinations (0000–9999). Should crack in under a second.
Step 3: Use incremental mode
Now hash a password of unknown length and use increment:
# Hash "83"
echo -n "83" | md5sum | awk '{print $1}' > test_incr.txt
# Crack with increment from 1 to 6 digits
hashcat -m 0 -a 3 -i --increment-min 1 --increment-max 6 \
-o results_ex2b.txt test_incr.txt ?d?d?d?d?d?d
Step 4: Observe the keyspace
Watch the hashcat status output. Notice how it processes length 1 first (?d), then length 2 (?d?d), and so on. Press s during execution to see status.
Self-check: Both hashes should be cracked. Confirm that the incremental mode found "83" by trying lengths 1 and then 2.
Exercise 3 — Dictionary Attack with Rules
-r to expand dictionary coverageStep 1: Create a hash that a plain dictionary won't crack
# "Password1" — capitalized with a digit suffix
echo -n "Password1" | md5sum | awk '{print $1}' > test_rules.txt
# "DRAGON" — all uppercase
echo -n "DRAGON" | md5sum | awk '{print $1}' >> test_rules.txt
# "sunshine123" — word + digits
echo -n "sunshine123" | md5sum | awk '{print $1}' >> test_rules.txt
Step 2: Try without rules (will likely fail)
hashcat -m 0 -a 0 -o results_ex3a.txt test_rules.txt test_wordlist.txt --potfile-disable
Check: did it crack all three? Probably not — the wordlist has "password" but not "Password1".
Step 3: Add the best64 rule file
hashcat -m 0 -a 0 -r rules/best64.rule -o results_ex3b.txt \
test_rules.txt test_wordlist.txt --potfile-disable
The rules mutate each word (capitalize, append digits, toggle case, etc.). Check if more hashes were cracked.
Step 4: Compare results
echo "=== Without rules ==="
cat results_ex3a.txt
echo "=== With rules ==="
cat results_ex3b.txt
Self-check: The rules-based attack should crack more (or all) of the hashes. Note which mutations were needed.
Exercise 4 — Hybrid Attack
-a 6Step 1: Create a hash with a word+digits pattern
echo -n "monkey99" | md5sum | awk '{print $1}' > test_hybrid.txt
echo -n "master42" | md5sum | awk '{print $1}' >> test_hybrid.txt
Step 2: Run a hybrid dictionary + mask attack
hashcat -m 0 -a 6 -o results_ex4.txt test_hybrid.txt test_wordlist.txt ?d?d
This appends every 2-digit combination (00–99) to every word in the wordlist.
Step 3: Verify results
cat results_ex4.txt
Both "monkey99" and "master42" should appear in the output.
Self-check: Both hashes cracked. Think about how this is more efficient than brute-forcing the entire password.
Exercise 5 — Session Management and Workload
--session, --restore, and -wStep 1: Start a named session with a longer-running task
hashcat -m 0 -a 3 --session lab03test -w 1 \
-o results_ex5.txt test_md5.txt ?l?l?l?l?l?l
This tries all 6-character lowercase combinations (~309 million candidates). It may take a few seconds to a minute depending on your hardware.
Step 2: Press q to gracefully quit
While the attack is running, press q to save progress and exit.
Step 3: Resume the session
hashcat --session lab03test --restore
Notice that it picks up where it left off, not from the beginning.
Step 4: Experiment with workload profiles
Run the same attack with -w 3 instead of -w 1 and compare the speed (hashes/second) shown in the status output.
Self-check: Session restore should continue from where it stopped. Higher workload should show increased speed.
Exercise 6 — Build a Complete Command
Challenge
Write a single hashcat command that meets all of these requirements:
- Cracks NTLM hashes (
-m 1000) - Uses a mask attack (
-a 3) - Tries lengths 4 through 8 (incremental mode)
- Uses all printable characters (
?a) - Saves output as hash:password format
- Uses a named session called
ntlm_audit - Sets workload to high (
-w 3)
Expected command
Try to build it yourself before revealing:
hashcat -m 1000 -a 3 -o ntlm_results.txt --outfile-format 3 \
--session ntlm_audit --increment --increment-min 4 --increment-max 8 \
-w 3 ntlm_hashes.txt ?a?a?a?a?a?a?a?a
Note: You can generate NTLM test hashes using Python:
import hashlib
password = "Test"
ntlm_hash = hashlib.new('md4', password.encode('utf-16le')).hexdigest()
print(ntlm_hash)
Self-check: Your command should contain all 8 required elements. Count them off one by one.
rm -f test_*.txt results_*.txt. Also clear the potfile if desired: rm -f hashcat.potfile.