Hashcat Tutorial: Crack Hashes with Wordlists, Rules, and Masks

Deepak Prasad
Tested on Kali GNU/Linux Rolling 2026.2 (kali-rolling)
Package hashcat 7.1.2+ds1-4
pocl-opencl-icd (CPU OpenCL when no GPU)
Lab environment Pentest lab
Cert prep CompTIA PenTest+ PT0-003 — password attacks and offline hash cracking
Privilege Normal user for cracking; sudo for apt install
Scope Hashcat workflow on Kali: -m vs -a, identify modes, dictionary and rules, masks and hybrids, potfile and --show, Cracked vs Exhausted, and common load errors. Does not cover live login brute force, rainbow tables, or cracking third-party dumps without authorization.
Related guides SSH brute force attack
Short on time?Beta Get the gist of this 17-minute read in seconds, then ask follow-up questions

Hashcat recovers plaintext by hashing candidate passwords and comparing them to your target. Beginners often mix up two independent flags: -m names the hash algorithm, and -a names how candidates are generated.

I ran every command below on Kali Rolling with hashcat 7.1.2 against hashes I created under /tmp/hashcat-lab. This lab VM has no discrete GPU, so OpenCL came from PoCL on the CPU. Speeds change on a machine with a real GPU. The workflow does not.

IMPORTANT
Crack only hashes you created in a lab or that come from systems you own or are authorized to test in your rules of engagement. Do not run hashcat against production dumps, customer data, or random pastebin files.

Understand -m and -a first

Before long install notes, lock these two decisions:

text
┌──────────────────────┐     ┌──────────────────────┐
│  Hash file / string  │     │  Candidates          │
└──────────┬───────────┘     └──────────┬───────────┘
           ↓                            ↓
┌──────────────────────┐     ┌──────────────────────┐
│  -m  hash mode       │     │  -a  attack mode     │
│  (what algorithm?)   │     │  (how are guesses    │
│                      │     │   built?)            │
└──────────┬───────────┘     └──────────┬───────────┘
           └────────────┬───────────────┘
                        ↓
              hashcat compares digests
Flag Question it answers Examples
-m What algorithm produced this digest? 0 MD5, 1000 NTLM, 3200 bcrypt
-a How should candidates be built? 0 wordlist, 3 mask, 6/7 hybrid

Wrong -m loads nothing or cracks the wrong thing. Wrong -a wastes a correct mode on a useless candidate space. Treat them as two separate choices every time.


Verify hashcat and hardware

Confirm the package version so your help text and example hashes match what you see in docs for the 7.x line:

bash
hashcat --version
output
v7.1.2

List OpenCL, CUDA, or HIP devices next. This is where you learn whether hashcat sees a GPU or only a CPU runtime:

bash
hashcat -I
output
OpenCL Platform ID #1
  Vendor..: The pocl project
  Name....: Portable Computing Language
  Version.: OpenCL 3.0 PoCL 7.1+debian  Linux, None+Asserts, RELOC, SPIR-V, LLVM 21.1.8, SLEEF, DISTRO, POCL_DEBUG

  Backend Device ID #01
    Type...........: CPU
    Vendor.........: GenuineIntel
    Name...........: cpu-haswell-12th Gen Intel(R) Core(TM) i7-1255U
    Processor(s)...: 2

No platform listed usually means a missing OpenCL, CUDA, or HIP runtime, not a broken hashcat binary. On this VM I installed pocl-opencl-icd for CPU OpenCL after hashcat -I reported CL_PLATFORM_NOT_FOUND_KHR. NVIDIA and AMD hosts need their vendor stacks instead.

A short benchmark shows how radically speed depends on the algorithm, not only on hardware. Compare MD5 and bcrypt on the same device:

bash
hashcat -b -m 0
output
* Hash-Mode 0 (MD5)
Speed.#01........: 32386.5 kH/s (16.92ms) @ Accel:287 Loops:1024 Thr:1 Vec:8

Repeat the benchmark for bcrypt so you can compare a slow hash on the same device:

bash
hashcat -b -m 3200
output
* Hash-Mode 3200 (bcrypt $2*$, Blowfish (Unix)) [Iterations: 32]
Speed.#01........:      221 H/s (16.13ms) @ Accel:2 Loops:32 Thr:1 Vec:1

Same CPU, same hashcat build: MD5 sat near 32 million hashes per second, bcrypt near 221. GPU usually wins on massively parallel fast hashes, but a slow algorithm stays expensive on any device. Do not compare your MD5 GPU number to someone else's bcrypt CPU number and call one setup broken.


Identify the correct hash mode

Create a lab directory and a known MD5 so every later step is reproducible:

bash
mkdir -p /tmp/hashcat-lab && cd /tmp/hashcat-lab

mkdir is silent on success, so generate the MD5 of password into a hash file next:

bash
echo -n 'password' | md5sum | awk '{print $1}' | tee md5_password.hash
output
5f4dcc3b5aa765d61d8327deb882cf99

Ask hashcat which modes fit that string. Autodetect lists several matches because a 32-character hex digest is ambiguous:

bash
hashcat --identify md5_password.hash
output
The following 12 hash-modes match the structure of your input hash:

      # | Name                                                       | Category
  ======+============================================================+======================================
    900 | MD4                                                        | Raw Hash
      0 | MD5                                                        | Raw Hash
     70 | md5(utf16le($pass))                                        | Raw Hash
   2600 | md5(md5($pass))                                            | Raw Hash salted and/or iterated
   3500 | md5(md5(md5($pass)))                                       | Raw Hash salted and/or iterated
   4400 | md5(sha1($pass))                                           | Raw Hash salted and/or iterated
  20900 | md5(sha1($pass).md5($pass).sha1($pass))                    | Raw Hash salted and/or iterated
  32800 | md5(sha1(md5($pass)))                                      | Raw Hash salted and/or iterated
   4300 | md5(strtoupper(md5($pass)))                                | Raw Hash salted and/or iterated
   1000 | NTLM                                                       | Operating System
   9900 | Radmin2                                                    | Operating System
   8600 | Lotus Notes/Domino 5                                       | Enterprise Application Software (EAS)

MD5 (0) and NTLM (1000) both appear. Context decides: a Unix web dump is not an Active Directory NTLM hash just because the hex length matches. When you know the source, force -m from that knowledge. When you do not, use example hashes and --hash-info instead of guessing.

Pull the official example and category for the modes you care about:

bash
hashcat -m 0 --hash-info
output
Hash mode #0
  Name................: MD5
  Category............: Raw Hash
  Slow.Hash...........: No
  Example.Hash........: 8743b52063cd84097a65d1633f5c74f5
  Example.Pass........: hashcat

NTLM is the Windows counterpart that often collides with MD5 on --identify. Check its info block the same way:

bash
hashcat -m 1000 --hash-info
output
Hash mode #1000
  Name................: NTLM
  Category............: Operating System
  Slow.Hash...........: No
  Example.Hash........: b4b9b02e6f09a9bd760f388b67351e2b
  Example.Pass........: hashcat

Then pull bcrypt so you can see a Slow.Hash marked Yes and an embedded $2a$ example:

bash
hashcat -m 3200 --hash-info
output
Hash mode #3200
  Name................: bcrypt $2*$, Blowfish (Unix)
  Category............: Operating System
  Slow.Hash...........: Yes
  Example.Hash........: $2a$05$MBCzKhG1KhezLh.0LRa0Kuw12nLJtpHy6DIaU.JAnqJUDYspHC.Ou
  Example.Pass........: hashcat
Mode Name Slow.Hash Lab note
0 MD5 No Fast raw digest; common in CTFs and old apps
1000 NTLM No Windows; same hex length as MD5, different algorithm
3200 bcrypt Yes Deliberately slow; expect tiny H/s relative to MD5

--example-hashes is an alias of --hash-info on this build. Prefer -m N --hash-info when you already know the candidate mode number.


Dictionary attack with -a 0

Straight mode (-a 0) tries each line in a wordlist as-is. Build a tiny list that contains the known password, then crack the MD5:

bash
printf 'password\nadmin\nwelcome\nlabpass123\nWinter2024\nPassword1\n' > tiny.lst

With the list on disk, run a straight dictionary attack (-a 0) against the MD5:

bash
hashcat -m 0 -a 0 md5_password.hash tiny.lst -O -w 2 --potfile-path /tmp/hashcat-lab/hashcat.pot --logfile-disable
output
5f4dcc3b5aa765d61d8327deb882cf99:password

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 0 (MD5)
Hash.Target......: 5f4dcc3b5aa765d61d8327deb882cf99
Guess.Base.......: File (tiny.lst)
Speed.#01........:       71 H/s (0.01ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 6/6 (100.00%)
Candidates.#01...: password -> Password1

Read the status block before you chase speed numbers:

Field What it means
Status Current job state; detailed Cracked vs Exhausted examples below
Hash.Mode Confirms the -m you chose
Speed Current hash rate on each device
Progress How far through the candidate space you are
Recovered Digests cracked versus total loaded
Candidates Sample of what is being tried right now
Time.Estimated ETA for the current attack

The 71 H/s line looks weak because the six-word list is tiny; hashcat warned that the keyspace was too small to fill the device. That is normal for a teaching wordlist.

On Kali, expand to rockyou after you decompress it once. Install or refresh packages with apt when hashcat or wordlists are missing:

bash
sudo gzip -dk /usr/share/wordlists/rockyou.txt.gz

Point the same -m 0 -a 0 command at the full rockyou file:

bash
hashcat -m 0 -a 0 md5_password.hash /usr/share/wordlists/rockyou.txt -O -w 2 --potfile-path /tmp/hashcat-lab/hashcat.pot --logfile-disable
output
5f4dcc3b5aa765d61d8327deb882cf99:password

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 0 (MD5)
Guess.Base.......: File (/usr/share/wordlists/rockyou.txt)
Speed.#01........:   206.9 kH/s (8.33ms) @ Accel:1024 Loops:1 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 2048/14344385 (0.01%)
Candidates.#01...: 123456 -> lovers1

password sits early in rockyou, so Recovered hit 100% after a tiny slice of the file. Progress at 0.01% with Status Cracked is success, not a stalled job.

NTLM uses the same attack mode with a different -m. Build an NTLM of Password1 and crack it from the same tiny list:

bash
python3 -c "import hashlib; print(hashlib.new('md4', 'Password1'.encode('utf-16le')).hexdigest())" | tee ntlm.hash
output
64f12cddaa88057e06a81b54e73b949b

This worked on the tested Kali build because its OpenSSL configuration exposes MD4. On distributions where Python reports unsupported hash type md4, use a known NTLM test hash or enable the distribution-supported legacy provider rather than changing the Hashcat command.

Crack that NTLM with mode 1000 and the same tiny wordlist:

bash
hashcat -m 1000 -a 0 ntlm.hash tiny.lst -O -w 2 --potfile-path /tmp/hashcat-lab/hashcat.pot --logfile-disable
output
64f12cddaa88057e06a81b54e73b949b:Password1

Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 1000 (NTLM)
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)

Same wordlist, different hash mode. That is the -m versus -a split in practice.


Cracked versus Exhausted

Exhausted is not a crash. It means hashcat finished every candidate without recovering all digests.

Prove it with a hash whose plaintext is missing from the list:

bash
echo -n 'secret' | md5sum | awk '{print $1}' | tee md5_secret.hash
output
5ebe2294ecd0e0f08eab7690d2a6ee69

Build a three-word list that deliberately omits secret:

bash
printf 'password\nadmin\nwelcome\n' > tiny_miss.lst

Run the dictionary attack against that incomplete list and watch the final Status line:

bash
hashcat -m 0 -a 0 md5_secret.hash tiny_miss.lst -O -w 2 --potfile-path /tmp/hashcat-lab/miss.pot --logfile-disable
output
Session..........: hashcat
Status...........: Exhausted
Hash.Mode........: 0 (MD5)
Hash.Target......: 5ebe2294ecd0e0f08eab7690d2a6ee69
Guess.Base.......: File (tiny_miss.lst)
Recovered........: 0/1 (0.00%) Digests (total), 0/1 (0.00%) Digests (new)
Progress.........: 3/3 (100.00%)
Candidates.#01...: password -> welcome

Progress 100% with Recovered 0/1 means the strategy failed, not the tool. Next step is a better wordlist, rules, a mask that matches a known pattern, or confirming -m is still correct.

Status Meaning Typical next step
Cracked All loaded digests recovered hashcat --show / potfile for reporting
Exhausted Candidate space finished; some digests remain Change list, rules, mask, or mode
Running Attack still in progress Watch Recovered and Time.Estimated

Add rules to a wordlist

Rules mutate each base word (case changes, digits, leetspeak) without rewriting the dictionary by hand. Kali ships rule files under /usr/share/hashcat/rules/. This build includes best66.rule (there is no best64.rule in the package I tested).

Crack Winter2024 from a lowercase base word plus rules:

bash
echo -n 'Winter2024' | md5sum | awk '{print $1}' | tee md5_winter.hash
output
2a28bf27d9b2f12a7213bf4635f3f1c6

Put the lowercase base word in a short list:

bash
printf 'winter2024\npassword\n' > rules_base.lst

Apply best66.rule so case and digit mutations can reach Winter2024:

bash
hashcat -m 0 -a 0 md5_winter.hash rules_base.lst -r /usr/share/hashcat/rules/best66.rule -O -w 2 --potfile-path /tmp/hashcat-lab/rules.pot --logfile-disable
output
2a28bf27d9b2f12a7213bf4635f3f1c6:Winter2024

Session..........: hashcat
Status...........: Cracked
Guess.Base.......: File (rules_base.lst)
Guess.Mod........: Rules (/usr/share/hashcat/rules/best66.rule)
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)

Guess.Mod confirms rules applied. For engagement-specific dictionaries (company names, product codes), build or refine lists with a wordlist generator workflow, then layer rules instead of inventing every variant yourself.


Mask attacks with -a 3

Masks describe each character position with a charset placeholder. Use them when you know the pattern better than you know the exact password.

Placeholder Character set
?l lowercase a-z
?u uppercase A-Z
?d digits 0-9
?s specials
?a ?l?u?d?s (printable)
?b full byte 0x00-0xff

Keyspace grows fast. Compare total candidates for three masks on this build:

bash
hashcat --total-candidates -a 3 '?l?l?l?l'
output
456976

Add four digit positions and measure again:

bash
hashcat --total-candidates -a 3 '?l?l?l?l?d?d?d?d'
output
4569760000

Finally count eight full ?a positions so the jump in keyspace is obvious:

bash
hashcat --total-candidates -a 3 '?a?a?a?a?a?a?a?a'
output
6634204312890625

Four lowercase letters are under half a million candidates. Four lowercase plus four digits jumps to about 4.6 billion. Eight full ?a positions is over six quadrillion. That ?a example is here to show keyspace growth, not as a recommended attack. Broad masks become impractical quickly, especially for slow hashes such as bcrypt or Argon2. Knowing the likely password structure can reduce an impractical keyspace to one that can actually finish.

Crack a short ?l?l?l?d password (lab1) to see mask status fields:

bash
echo -n 'lab1' | md5sum | awk '{print $1}' | tee md5_lab1.hash
output
e274b0a65912e49a28a9ae5c1479bdce

Attack it with mask mode and the ?l?l?l?d pattern:

bash
hashcat -m 0 -a 3 md5_lab1.hash '?l?l?l?d' -O -w 2 --potfile-path /tmp/hashcat-lab/mask.pot --logfile-disable
output
Session..........: hashcat
Status...........: Cracked
Hash.Mode........: 0 (MD5)
Guess.Mask.......: ?l?l?l?d [4]
Speed.#01........: 15134.0 kH/s (1.02ms) @ Accel:1024 Loops:16 Thr:1 Vec:8
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)
Progress.........: 32768/175760 (18.64%)

Guess.Mask shows the pattern. Progress can sit below 100% when the match appears early; Status Cracked is the signal that matters.


Custom charsets with -1 through -4

When policy or OSINT narrows the alphabet, build a custom charset instead of spraying ?a everywhere. -1 through -4 define custom sets; ?1 through ?4 use them in the mask.

Crack Lab! with letters in -1 and three symbols in -2:

bash
echo -n 'Lab!' | md5sum | awk '{print $1}' | tee md5_labbang.hash
output
5c1d4df6ecadc2e6a01b727af5799c69

Define two custom sets and reference them as ?1 and ?2 in the mask:

bash
hashcat -m 0 -a 3 md5_labbang.hash -1 '?l?u' -2 '!@#' '?1?1?1?2' -O -w 2 --potfile-path /tmp/hashcat-lab/cs.pot --logfile-disable
output
Session..........: hashcat
Status...........: Cracked
Guess.Mask.......: ?1?1?1?2 [4]
Guess.Charset....: -1 ?l?u, -2 !@#, -3 N/A, -4 N/A, -5 N/A, -6 N/A, -7 N/A, -8 N/A
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)

Quote custom charsets when the shell would eat ! or other specials. Narrow alphabets are for authorized testing where you already know policy shape, not for blind spraying of every printable character.


Hybrid attacks (-a 6 and -a 7)

Hybrids combine a wordlist with a mask:

Mode Layout Typical use
-a 6 wordlist + mask on the right admin + year digits
-a 7 mask on the left + wordlist prefix digits/symbols + base word

Crack admin2024 as dictionary word plus four digits:

bash
echo -n 'admin2024' | md5sum | awk '{print $1}' | tee md5_admin2024.hash
output
8d4db54daf7d67db5f3c96e43f61c609

Keep the base words in a two-line list:

bash
printf 'admin\nroot\n' > hybrid.lst

Run hybrid mode 6 so each word is followed by four digits:

bash
hashcat -m 0 -a 6 md5_admin2024.hash hybrid.lst '?d?d?d?d' -O -w 2 --potfile-path /tmp/hashcat-lab/hybrid.pot --logfile-disable
output
8d4db54daf7d67db5f3c96e43f61c609:admin2024

Session..........: hashcat
Status...........: Cracked
Guess.Base.......: File (hybrid.lst), Left Side
Guess.Mod........: Mask (?d?d?d?d) [4], Right Side
Recovered........: 1/1 (100.00%) Digests (total), 1/1 (100.00%) Digests (new)

Reach for hybrid when users append seasons, years, or ticket numbers to a short dictionary word. Leave obscure attack modes alone until straight, rules, mask, and hybrid are exhausted.


Sessions, restore, potfile, and --show

Name long jobs with --session so you can stop and continue later:

bash
hashcat -m 0 -a 3 md5_lab1.hash '?l?l?l?d' --session labdemo -O -w 2 --potfile-path /tmp/hashcat-lab/hashcat.pot --logfile-disable
output
Session..........: labdemo
Status...........: Cracked

On a job that is still running, resume with the same session name after a clean stop. For a long-running job, press c to stop at the next checkpoint so the restore state is current. q quits immediately and can lose progress made since the most recent restore point. On this Kali package, session files are stored under ~/.local/share/hashcat/sessions/; other installation layouts may use a different location:

bash
hashcat --session labdemo --restore

That command picks up the saved restore point instead of restarting the keyspace from zero.

Cracked pairs land in the potfile. Show them against the original hash list without rerunning the attack:

bash
hashcat -m 0 md5_password.hash --show --potfile-path /tmp/hashcat-lab/hashcat.pot
output
5f4dcc3b5aa765d61d8327deb882cf99:password

Use --potfile-path in labs so teaching runs do not pollute your default pot, and so --show reads the same file you just wrote.


Hashcat troubleshooting

Hash-loading errors usually point to the input format or the selected -m, not the candidate attack. The examples below reproduce the common parser messages so you can recognize them quickly.

Token length exception

A truncated or wrong-length token for the selected mode fails before any candidates run:

bash
printf 'deadbeef\n' > short.hash

Load that truncated string as MD5 and read the parser error:

bash
hashcat -m 0 -a 0 short.hash tiny.lst -O -w 2 --potfile-path /tmp/hashcat-lab/err.pot --logfile-disable
output
Hashfile 'short.hash' on line 1 (deadbeef): Token length exception
Parsing Hashes: 0/1 (0.00%)...
* Token length exception: 1/1 hashes
  This error happens if the wrong hash type is specified, if the hashes are
  malformed, or if input is otherwise not as expected (for example, if the
  --username or --dynamic-x option is used but no username or dynamic-tag is present)

No hashes loaded.

Common causes:

  • Wrong -m for the string you have
  • Truncated copy/paste or trailing cut-off
  • Extra whitespace or a header line treated as a hash
  • Username or dynamic-tag options enabled without matching fields

Separator unmatched

Salted or structured modes expect delimiters. Feeding a raw MD5 into mode 10 (MD5 $pass.$salt) fails like this:

bash
printf '5f4dcc3b5aa765d61d8327deb882cf99\n' > plain_as_salted.hash

Select salted mode 10 against that unsalted line:

bash
hashcat -m 10 -a 0 plain_as_salted.hash tiny.lst -O -w 2 --potfile-path /tmp/hashcat-lab/err.pot --logfile-disable
output
Hashfile 'plain_as_salted.hash' on line 1 (5f4dcc3b5aa765d61d8327deb882cf99): Separator unmatched
Parsing Hashes: 0/1 (0.00%)...No hashes loaded.

Common causes:

  • Hash file format does not match the selected mode
  • Wrong file (wordlist or export) passed as the hash list
  • Extracted line missing salt, iteration, or $…$ wrappers

No hashes loaded

Empty lines and junk produce the same final line. Whitespace-only input:

bash
printf '\n' > empty.hash

Ask hashcat to load it as MD5:

bash
hashcat -m 0 -a 0 empty.hash tiny.lst -O -w 2 --potfile-path /tmp/hashcat-lab/err.pot --logfile-disable
output
Parsing Hashes: 0/1 (0.00%)...No hashes loaded.

Garbage under bcrypt:

bash
printf 'not-a-bcrypt-hash\n' > junk.hash

Force bcrypt mode against that junk line:

bash
hashcat -m 3200 -a 0 junk.hash tiny.lst -w 2 --potfile-path /tmp/hashcat-lab/err.pot --logfile-disable
output
Hashfile 'junk.hash' on line 1 (not-a-bcrypt-hash): Separator unmatched
Parsing Hashes: 0/1 (0.00%)...No hashes loaded.

Fix the input and -m first. Candidate strategy does not matter until at least one digest loads.

GPU not detected or poor speed

Symptom Likely cause Fix
CL_PLATFORM_NOT_FOUND_KHR / no devices Missing OpenCL, CUDA, or HIP runtime Install vendor runtime or PoCL for CPU labs; re-run hashcat -I
Tiny H/s on bcrypt/Argon2 Slow hash by design Expected; compare same -m across machines
Tiny H/s on MD5 with a six-word list Keyspace too small to fill the device Use a real wordlist or mask; ignore teaching-list speed
Friend's benchmark much faster Different GPU, driver, -m, or -O/-w Match mode and options before comparing
Pure kernel ATTENTION message Optimized kernel not selected Add -O when password length fits the optimized limit

John the Ripper versus hashcat

Topic Hashcat John the Ripper (Jumbo)
Strength GPU-oriented high-throughput attack engine; large mode catalog Single mode, convenient *2john converters, mixed CPU workflows
Mode selection Explicit -m / -a --format plus cracking mode flags
Rules / masks First-class -r and -a 3 Rules and mask/incremental modes
File prep Often needs an already extracted hash zip2john, ssh2john, pdf2john, unshadow
When I reach for it Bulk fast hashes, masks, GPU time Archives, odd formats, single-host CPU work

Neither tool wins every job. Prepare the hash correctly, then pick the engine that matches hardware and input shape. For John's input pipeline see John the Ripper.


Summary

Hashcat work is two independent decisions plus a feedback loop: identify the digest (-m), choose how candidates are built (-a), read Status and Recovered, then refine. Autodetect on a 32-character hex string can list MD5 and NTLM together, so where the hash came from matters more than hex length alone.

Exhausted means the selected candidate space finished without recovering every hash; change or expand the attack strategy if further testing is justified. Token length exception, Separator unmatched, and No hashes loaded are input or mode problems. Fix those before you tune wordlists.

Start with a controlled dictionary run. Add rules when users mutate passwords. Use masks and custom charsets when the pattern is known. Keep long jobs under a named session and pull plaintext with --show against the potfile. For live login guessing rather than offline hashes, use a service attack path such as SSH brute force instead of hashcat.


References


Frequently Asked Questions

What is the difference between hashcat -m and -a?

-m selects the hash type and -a selects the candidate-generation method. Hashcat 7 can attempt hash-mode autodetection when -m is omitted, while attack mode defaults to -a 0; in repeatable pentest workflows, explicitly setting the known values makes the command easier to verify.

Why does hashcat say No hashes loaded?

The file did not yield any digests that match the selected mode. Typical causes are the wrong -m, truncated lines, empty or whitespace-only files, missing salts for salted modes, or a wordlist accidentally passed as the hash file.

What does Status Exhausted mean in hashcat?

Hashcat finished the entire candidate space without recovering every loaded digest. It is not a crash. Expand or change the wordlist, add rules, tighten a mask, or verify the hash mode.

Why is my hashcat benchmark much slower than someone else's?

Compare the same hash mode, similar hardware class, and similar options (-O, workload). Fast hashes on a discrete GPU differ wildly from bcrypt on a CPU OpenCL runtime. Different -m values make speed comparisons meaningless.

How do I show cracked passwords in hashcat?

Run hashcat -m <mode> hashfile --show with the same potfile path you used while cracking. Matches are stored as hash:plaintext in the potfile so you do not need to repeat the attack.

Finished reading?Beta Get the key takeaways in seconds, then ask follow-up questions
Kennedy Muthii

Information Security Analyst

Accomplished professional proficient in Python, ethical hacking, Linux, cybersecurity, and OSINT. With a track record including winning a national cybersecurity contest, launching a startup in Kenya, and holding a degree in information science, he is currently engaged in cutting-edge research in ethical hacking.

  • Python (programming language)
  • Certified Ethical Hacker
  • White Hat (Computer Security)
  • Linux
  • Penetration Testing