Overview

Questions about hardware and drivers that no longer exist have moved to the archived FAQ. Nothing was deleted, but nothing there should be followed either.

Pre-Installation

Why does a window pop up and close immediately?

(short URL: https://hashcat.net/faq/ubernoobs)

The reason for this is that the hashcat tools are command line tools only.

See the wiki page Help for ubernoobs to troubleshoot this problem.

Windows says hashcat is a virus, or deletes it after download. What now?

This happens to nearly everyone on Windows and it does not mean your download is bad.

hashcat.exe is not code signed. There is no certificate in the file, so SmartScreen has nothing to check and warns about an unrecognised app. Separately, antivirus products flag password recovery tools by category rather than by behaviour, so a clean hashcat is often quarantined or deleted straight out of the archive.

The right response is not to trust us, it is to check the download yourself. Every release is signed with the project's PGP key even though the binary is not, so verify the archive before you extract it: see How do I verify the PGP signatures? A good signature tells you the archive is the one we published, which is the question antivirus cannot answer for you.

Once you have verified it, you will need to allow it in whatever flagged it. Use your antivirus's own exclusion list for the hashcat folder. Do not disable protection wholesale, and do not download hashcat from anywhere but hashcat.net, because “antivirus-free hashcat” builds circulating elsewhere are exactly what you should be afraid of.

I am a complete noob, what can I do for getting started?

The best way to get started with software from hashcat.net is to use the wiki, especially the general guide links. You can also use the forum to search for your specific questions (forum search function).

Please do not immediately start a new forum thread - first use the built-in search function and/or a web search engine to see if the question was already posted/answered.

There are also some tutorials listed under Howtos, videos, papers, articles etc in the wild to learn the very basics. Note these resources can be outdated.

NOTE: YOU CANNOT USE HASHCAT TO RECOVER ONLINE ACCOUNTS (Google, Facebook, Instagram, Twitter, etc.) - even if you have permission from the account owner. This isn't just because it's wrong or potentially illegal; it's also because hashcat doesn't work that way.

I know an online username. How can I use hashcat to crack it?

(short URL: https://hashcat.net/faq/online)

You can't. That's not the way hashcat works.

hashcat cannot help you if you only have a username for some online service (like Facebook, Google, Instagram, Twitter, etc.). hashcat can only attack back-end password hashes.

Hashes are a special way that passwords are stored on the server side. it's like cracking open a shell to get the nut inside - hence hash “cracking”. If you don't have the password hash to attack offline, there's nothing for hashcat to attack.

We cannot recommend other ways to recover online passwords - that would require the explicit permission of both the account holder and the company operating the website or service. If you don't have both of those things, you're probably doing something that could get you into serious trouble.

It doesn't matter if it's your own account. It doesn't matter if you have your “friend's” permission.

Don't do it.

Why are there different versions of *hashcat?

There is one hashcat. It cracks on GPUs and on CPUs, in the same binary, and it picks the fastest way to talk to each device it finds:

  • CUDA on NVIDIA
  • HIP on AMD
  • Metal on Apple
  • OpenCL everywhere else, including CPUs, and as the fallback when a compiler package is missing

Use hashcat -I to see which of these came up on your machine.

It was not always one program. oclHashcat, oclHashcat-plus and oclHashcat-lite were separate, and hashcat 3.00 merged them: its changelog opens “This release marks the fusion of hashcat and oclHashcat into hashcat”. hashcat-legacy is a different thing again, the CPU-only program under its post-split name, and it is retired. If you are reading a guide that names any of the old ones, it predates 3.00. See the Archive.

Why are there so many binaries, which one should I use?

The archive holds two binaries, both 64 bit:

  • hashcat.bin for Linux
  • hashcat.exe for Windows

macOS is supported, hashcat has a Metal backend for Apple's GPUs, but no macOS binary is shipped in the archive. Build it from source, or install it through a package manager.

CPU usage is normally low while cracking, but there are two cases where it is not, and neither is a fault: an OpenCL capable CPU you selected as a device, and the six bridged modes, where part or all of the work runs on the CPU by design. Those are -m 70000, 70100, 70200, 72000, 73000 and 74000, and --help marks each of them [Bridged: …].

How do I verify the PGP signatures?

Linux

Start by fetching the signing key. Ask for it by its full fingerprint rather than the short ID, because short IDs can be forged:

$ gpg --keyserver keyserver.ubuntu.com --recv-keys A70833229D040B4199CC00523C17DA8B8A16544F

Then download hashcat and its signature:

$ wget https://hashcat.net/files/hashcat-7.1.2.7z
$ wget https://hashcat.net/files/hashcat-7.1.2.7z.asc

And verify:

$ gpg --verify hashcat-7.1.2.7z.asc hashcat-7.1.2.7z
gpg: Signature made Sat 23 Aug 2025 10:54:21 AM CEST
gpg:                using RSA key A70833229D040B4199CC00523C17DA8B8A16544F
gpg: Good signature from "Hashcat signing key <signing@hashcat.net>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: A708 3322 9D04 0B41 99CC  0052 3C17 DA8B 8A16 544F

“Good signature” is the line that matters. The warning below it is normal and does not mean the check failed: it only says you have not personally signed our key to say you trust it. What you do need to do by hand is compare the fingerprint above against the one printed on the download page. They must match character for character.

Two keyservers that used to be recommended are no longer good advice. keys.gnupg.net has been shut down and no longer resolves at all. keys.openpgp.org does hold the key, but it serves it with the name and address stripped off, because that service only publishes an address the owner has confirmed to it. gpg then imports a key with no user ID and cannot tell you who signed the file, which defeats the point.

Windows

  1. Download GPG4Win. You want the top download, which will give you a graphical front-end named Kleopatra.
  2. Click Settings, then Configure Kleopatra, and add a keyserver if one is not already set:
    • Scheme: hkps
    • Server Name: keyserver.ubuntu.com
    • Check the box labeled “OpenPGP”
  3. Click Apply and close that window.
  4. Click “Lookup Certificates on Server” and search for the full fingerprint A70833229D040B4199CC00523C17DA8B8A16544F. Searching by address is less reliable, and a short ID can be forged.
  5. Check that the result is “Hashcat signing key”, select it, and click Import.
  6. Download hashcat and its matching .asc signature into the same folder.
  7. In Explorer, right-click the .asc file, open “More GpgEX options” and click “Verify”. Check that “Input file is a detached signature” is ticked, then click “Decrypt/verify”.
  8. You want it to report a good signature from “Hashcat signing key”, with the fingerprint above. As on Linux, a warning that the key is not certified is expected and is not a failure. Compare the fingerprint against the download page yourself.

Is there a hashcat GUI?

There is no official GUI, and this FAQ no longer names a third-party one, because both that it used to point at have disappeared: hashkiller.co.uk/hashcat-gui.aspx no longer answers, and github.com/s77rt/hashcat.launcher has been removed from GitHub.

We neither develop nor maintain these tools, so we can not offer support for them. Please ask the authors of the software for support or post questions on the forums you got the software from.

The main reason why there is no GUI developed by hashcat.net is because we believe in the power and flexibility of command line tools and well… *hashcat is an advanced password recovery tool (and being able to use the command line should be a bare minimum requirement to use this software).

Installation

How do I install hashcat?

There is nothing to install: extract the archive and run it from that folder.

One note on how the commands in this FAQ are written. The archive ships hashcat.bin on Linux and hashcat.exe on Windows, and puts nothing on your PATH, so from the extracted folder you type ./hashcat.bin or hashcat.exe. A distribution package installs a hashcat command instead. This FAQ writes plain hashcat for brevity; substitute whichever you have.

On macOS there is more to it, because the archive contains no macOS binary: build from source or install through a package manager.

Please note, your GPU must be supported and the driver must be correctly installed to use this software.

If your operating system or Linux distribution does have some pre-build installation package for hashcat, you may be able to install it using those facilities. For example, you can use the following under Ubuntu or Debian or Kali Linux:

$ sudo apt-get update && sudo apt-get install hashcat

and update it with:

$ sudo apt-get update && sudo apt-get upgrade

Even if package installation is supported by some distributions, we do not directly support those packages here, since it depends on the package maintainers to update the packages, install the correct dependencies (some packages may add wrappers, etc), and use reasonable paths.

In case something isn't working with the packages that you install via your package manager, we encourage you to just download the hashcat archive directly, enter the folder, and run hashcat. This is the preferred and only directly supported method to “install” hashcat.

Distribution packages can lag a long way behind, not just by a little: an LTS release may carry a hashcat several major versions old, which is old enough to lack modes and options this wiki documents. Check what you have with hashcat -V against the download page before assuming a missing feature is a wiki error. See this Repology list of hashcat package status.

How does one install the correct driver for the GPU(s)?

A GPU needs two things, not one. hashcat compiles its kernels while it runs, and on NVIDIA and AMD the compiler does not come with the driver. Install the driver and you get OpenCL, which works but is slower. Install the matching compiler package as well and you get the fast backend, CUDA or HIP.

your hardware what to install backend you get
NVIDIA GPU the NVIDIA driver, plus the CUDA Toolkit CUDA
AMD GPU, Linux ROCm HIP
AMD GPU, Windows the Adrenalin driver, plus the AMD HIP SDK HIP
Intel GPU the Intel Graphics Compute Runtime, known as NEO OpenCL
CPU the Intel CPU Runtime for OpenCL, or PoCL OpenCL
Apple nothing, macOS carries Metal and OpenCL itself Metal

A missing compiler package is a warning, not an error. hashcat says so and carries on through OpenCL:

* Device #1: CUDA SDK Toolkit not installed or incorrectly installed.
             CUDA SDK Toolkit required for proper device support and utilization.

Use the vendor's own packages and repositories. That is not the old advice of never using a package manager, since ROCm and CUDA are both delivered that way now, but a driver that arrived with your distribution or through Windows Update is a different thing and is worth replacing.

The rest of this answer is the per-platform detail, because this is where most people get stuck.

NVIDIA on Linux

Install the driver and the CUDA Toolkit. hashcat opens two libraries at run time: libcuda.so from the driver, and libnvrtc.so from the Toolkit.

The trap is that libnvrtc.so without a version suffix only exists in the development package. Release 7.1.2 looks for exactly libnvrtc.so and then libnvrtc.so.1, and no CUDA package has ever shipped the second name. So a machine with the CUDA runtime libraries but not the development package has no CUDA backend, even though everything looks installed. On Debian and Ubuntu the symlink comes from nvidia-cuda-dev. (Master scans for versioned names instead and no longer needs it.)

Two version traps beyond that:

  • A Toolkit newer than the driver breaks it. hashcat's kernels go through PTX, and NVIDIA is explicit that applications compiling device code to PTX do not work on older drivers. So do not install a new Toolkit against an old driver.
  • A Toolkit that is too new for the card breaks it too. NVRTC in CUDA 13.x accepts only compute_75 and newer, so a Maxwell, Pascal or Volta card cannot have its kernels compiled by a CUDA 13 NVRTC. Older cards need an older Toolkit.

To verify:

$ cat /proc/driver/nvidia/version     # the driver is loaded
$ nvidia-smi                          # the card is visible
$ hashcat -I                          # a CUDA Info: section exists

Note that the CUDA.Version. line in -I is the driver's CUDA version, from cuDriverGetVersion, not the Toolkit you installed. hashcat never prints the NVRTC or Toolkit version, so -I cannot tell you whether the Toolkit is the right one. The same goes for nvidia-smi, whose “CUDA Version” is also the driver's capability.

AMD on Linux

Install ROCm. hashcat opens two libraries: the HIP runtime libamdhip64.so and the HIP compiler libhiprtc.so, both by their plain unversioned names in 7.1.2. AMD's own hip-runtime-amd package ships those symlinks, which is a good reason to use AMD's repository rather than assembling it by hand.

Group membership is the most common cause of a card that simply is not there. hashcat checks for it and its own advice is incomplete:

Cannot access /dev/dri/card0: Permission denied.
This causes some drivers to crash when OpenCL is used!
Adding your user to the "video" group usually fixes this problem:
$ sudo usermod -a -G video $LOGNAME

video alone is not enough for ROCm, which also needs render for the DRM render nodes its compute path uses. Add both, then log out and back in, because group membership is only picked up at login:

$ sudo usermod -a -G video,render $LOGNAME

Two things about that check are worth knowing. It only looks at card0, so on a machine where the AMD card is card1 it never runs and you get no warning at all. And it is skipped entirely for root, which is why running as root appears to “fix” the problem and is not the fix.

When /dev/kfd is unusable, which is what missing groups produce in practice, the card disappears from both backends: hashcat prints hipInit(): no ROCm-capable device is detected. rocminfo fails the same way, with HSA_STATUS_ERROR_OUT_OF_RESOURCES.

To verify:

$ rocminfo | grep -E 'Name|gfx'       # ROCm sees the card
$ hashcat -I                          # a HIP Info: section exists

A card that is not on AMD's supported list may still work: hashcat enumerates whatever ROCm enumerates. HSA_OVERRIDE_GFX_VERSION can make an unsupported card report a supported ISA, but it applies to every GPU in the machine rather than the one you meant, and a malformed value makes them all report gfx000, which is unusable.

AMD on Windows

Install the Adrenalin driver and the AMD HIP SDK. The minimums are Adrenalin 23.7.2 and HIP SDK 23.Q3.

7.1.2 finds the HIP libraries only through the HIP_PATH environment variable. If it is not set there is no HIP backend at all, and the SDK installer is what normally sets it. Worse, 7.1.2 builds the DLL names by parsing the literal \ROCm\X.Y out of that path, so:

  • a HIP_PATH that does not contain \ROCm\X.Y in that shape yields no HIP compiler
  • whether HIP_PATH ends in a backslash changes which runtime gets loaded, because the runtime path is built without a separator of its own

The runtime has a fallback to the plain amdhip64.dll the graphics driver installs; the compiler has none. So the usual Windows symptom is an AMD card working through OpenCL while HIP silently never appears. (Master finds the newest DLL in the directory instead, which removes all of this.)

7.1.2 also refuses HIP on Windows for any AMD device whose architecture does not parse as gfx1000 or higher, printing This HIP version does not support this device on Windows. Falling back to OpenCL. So pre-RDNA cards are OpenCL-only on Windows whatever you install.

Intel GPUs

Install the Intel Graphics Compute Runtime, known as NEO. An Intel GPU is OpenCL only: hashcat has four backends, CUDA, HIP, Metal and OpenCL, and there is no Level Zero or oneAPI backend, so there is no fast path to reach. hashcat enforces no minimum version for NEO and uses it on a best-effort basis, so if it misbehaves, check its version yourself.

A word on Mesa's rusticl, since it comes up. It is a real OpenCL implementation and hashcat will use it, but it is not a drop-in alternative and this wiki is not going to talk you into it:

  • It advertises no devices at all by default. Mesa's own documentation says so, and says that advertising them “can impact system stability until remaining core issues are ironed out”. You have to set RUSTICL_ENABLE before hashcat can see anything through it.
  • On the 7.1.2 release you lose hardware monitoring for a rusticl device: no temperature, no fan speed, no clocks. The release has no path for the extensions that would supply a PCI address, and its AMD-specific queries only fire when the platform vendor is AMD, which rusticl's is not. This is fixed on master.
  • rusticl reports the AMD vendor id while answering none of the AMD extension queries, so anything keying off the vendor id alone gets the wrong answer about it.

hashcat enforces no minimum version for rusticl and uses it on a best-effort basis, which also means hashcat cannot tell you when a rusticl problem is rusticl's. If your card has a vendor runtime available, ROCm on AMD or NEO on Intel, use that instead. See Mesa's rusticl documentation if you want to enable it anyway.

CPUs

Two options, and hashcat treats them differently:

  • the Intel CPU Runtime for OpenCL, which works on AMD processors too despite the name. hashcat requires the 2020 release or newer, since the version is year-first, and skips an older one with Outdated or broken Intel OpenCL runtime
  • PoCL, where hashcat requires PoCL 5.0 and LLVM 10.0. It reads both from the platform version string, so a PoCL build whose version string omits the LLVM part is skipped no matter how new it is

CPU devices are off by default, because a busy CPU slows down GPU synchronisation. Ask for one with -D 1, or -D 1,2 for both. The exception is a machine with no OpenCL GPU at all, where hashcat enables the CPU by itself so a CPU-only box needs no flag.

macOS

Nothing to install. macOS carries Metal and OpenCL itself, and hashcat uses Metal. The archive ships no macOS binary, so build from source or install through a package manager.

What hashcat refuses, and what it merely grumbles about

7.1.2 does not treat the vendors alike:

  • NVIDIA below CUDA 9.0, driver or NVRTC, is fatal. hashcat prints Outdated NVIDIA CUDA driver version '8000' detected! and exits rather than falling back. --backend-ignore-cuda is the way to run on OpenCL anyway, since it stops hashcat opening CUDA at all.
  • AMD below HIP 6.2.0 on Linux, or 4.4 on Windows, is not fatal. hashcat prints Unsupported AMD HIP runtime version '6.1.0' detected! Falling back to OpenCL… and carries on.
  • An AMD OpenCL driver below 3000 makes hashcat skip that device, and --force does override that one.
  • A GPU below CUDA compute capability 5.0 is only warned about, not skipped. You keep the device.

--force does not lift the CUDA or HIP runtime version gates in 7.1.2.

GPU device not found, why?

  • Run hashcat -I to see what loaded. A backend that did not come up has no section at all, so a machine with an NVIDIA card and no CUDA Info: block is missing the CUDA Toolkit. That absence is the most useful thing in the output.
  • But do not use -I to decide whether a device is usable. It deliberately turns the version and suitability checks off, so it lists devices a real attack would refuse. To see the skip reasons, start an actual run: those messages are printed then, not by -I.
  • Check you installed the compiler package as well as the driver, see the question above. A card that is present but missing its compiler shows up under OpenCL and not under CUDA or HIP.
  • A runtime below hashcat's minimum version is refused, and hashcat says which one and what it found. On NVIDIA that ends the run; on AMD it drops to OpenCL. See the driver question for the numbers. --force does not lift these in 7.1.2.
  • hashcat has two different messages for finding nothing, and they mean different things. ATTENTION! No OpenCL, HIP or CUDA compatible platform found means no runtime loaded at all, so nothing is installed or nothing is reachable. No devices found/left means a runtime did load but every device in it was excluded, by -d, by --backend-devices, or by a suitability check.
  • On Linux, a headless machine does not need an X session for CUDA or ROCm. The old advice about xorg.conf, DISPLAY and xhost belongs to a driver generation that is gone.
  • If a conflicting driver is already installed, see I may have the wrong driver installed. What should I do?

hashcat -I lists my GPU more than once. Is that wrong?

No, that is expected. A card that more than one backend can reach is listed once per backend, and hashcat cross-references the copies so you can see they are the same hardware:

HIP Info:
  Backend Device ID #01 (Alias: #03)
    Name...........: AMD Radeon RX 9070 XT

OpenCL Info:
  Backend Device ID #03 (Alias: #01)
    Name...........: AMD Radeon RX 9070 XT

That is one GPU, reachable through HIP and through OpenCL. Two GPUs plus a CPU can easily report six device entries this way. hashcat uses one of each alias pair rather than both, so nothing is being counted twice during an attack.

One other thing in that output surprises people: the CPU is listed under a platform named for a different vendor. An AMD processor showing up under Name….: Intel(R) OpenCL is normal, because Intel's CPU runtime drives AMD CPUs too.

I may have the wrong driver installed, what should I do?

(short URL: https://hashcat.net/faq/wrongdriver)

The usual cause is not a wrong driver but a missing compiler package, so read the driver question before you uninstall anything. Work through this in order, because each step is cheaper than the one after it.

1. Find out what is actually loaded

$ hashcat -I

A backend that did not come up has no section. No CUDA Info: on an NVIDIA box means the Toolkit is missing or unreachable; no HIP Info: on an AMD box means the same for HIP. That absence is the diagnosis, and it usually points at a package rather than a broken install.

Remember that -I deliberately skips the suitability checks, so it lists devices a real run would refuse. If -I looks fine but an attack does not, start an attack and read those messages instead.

2. Clear the caches

This is worth doing before anything drastic, because a stale compile survives a driver change and produces failures that look like a broken driver.

There is more than one cache, and hashcat's own is the smallest and least likely culprit:

  • hashcat's kernel cache. Beside the binary for an extracted archive, otherwise under your home. See Where does hashcat keep its compiled kernels?
  • The runtime's own compiler cache, which hashcat does not disable in a release build. NVIDIA's CUDA JIT cache is ~/.nv/ComputeCache, movable with CUDA_CACHE_PATH and disableable with CUDA_CACHE_DISABLE=1. AMD's ROCm compiler cache is ~/.cache/comgr. PoCL's is ~/.cache/pocl. Mesa and rusticl use ~/.cache/mesa_shader_cache.

The size difference is the point. On one machine here hashcat's cache is under a megabyte while the runtime caches come to nearly three gigabytes between them, so after a driver change the runtime cache is the one more likely to be serving you something stale.

Note that ~/.local/share/hashcat is not a cache: it holds your potfile and your sessions. Do not delete it to fix a driver.

3. Windows: remove the old driver with the vendor's own tool

Uninstall through Settings, Apps first. If that leaves a mixed state, both vendors publish a cleaner and there is no need for anything third-party:

  • AMD ship the AMD Cleanup Utility, which removes driver files, registry entries and driver store packages, and is meant to be run before a fresh install.
  • NVIDIA's own installer has a clean installation option, which discards the existing profiles and settings rather than upgrading over them.

Reboot between removing and installing. Then install the driver and its compiler package, and on AMD check that HIP_PATH is set, since 7.1.2 finds HIP only through it.

4. Linux: remove the old driver the way you installed it

Match the removal to the install route, because mixing them is what creates the mess in the first place:

  • installed from NVIDIA's .run installer: nvidia-uninstall
  • installed from packages: purge them rather than removing them, so the configuration goes too
  • ROCm installed with amdgpu-install: use its own uninstall option

Then check the ICD loader. Several packages can legitimately provide a libOpenCL, so do not purge everything that offers one: on a healthy machine a vendor runtime and ocl-icd-libopencl1 coexist. What matters is which one the loader picks, and which vendors are registered:

$ ldconfig -p | grep libOpenCL
$ ls /etc/OpenCL/vendors/

That directory is how the loader finds each vendor, so a driver that installed no .icd file there will not be found through OpenCL however well it is installed otherwise.

Reinstall, then add yourself to the right groups if you have not: video and render for ROCm, followed by a logout.

5. Verify, and report properly if it is still broken

$ clinfo | head            # the ICD loader sees a platform
$ hashcat -I               # hashcat sees the devices
$ hashcat -b -m 0          # it can actually compile and run

If it still does not work, ask on the forum with the full output of hashcat -I, your exact command line and the hashcat version. Without those three nobody can tell a driver problem from a hashcat problem.

Where does hashcat keep its compiled kernels?

hashcat compiles its kernels the first time it needs them and caches the result, which is why the first run of a mode is slow and later ones start at once. A stale cache is worth clearing after a driver change.

There is more than one cache involved, and hashcat's own is the smallest. That matters, because the usual reason for clearing anything is a driver change, and a driver change invalidates the runtime's cache rather than hashcat's.

hashcat's own kernel cache

On Windows it is always the kernels directory beside hashcat.exe, because the home-directory logic is POSIX-only. On Linux and macOS it depends on how hashcat was installed:

  • Run from the extracted archive or a git build, which is how most people run it: a kernels directory beside the binary. Delete that directory.
  • Installed to a system prefix, by make install or a distribution package: under your home instead, because the program directory is not yours to write to. That is $XDG_CACHE_HOME/hashcat/kernels, meaning ~/.cache/hashcat/kernels unless you set the variable. hashcat 7.1.2 prefers ~/.hashcat/kernels if that directory already exists, for the sake of older installs.

The runtime's cache, which hashcat does not disable

Every backend compiler keeps its own cache as well, and a release build of hashcat leaves them all enabled. (It disables the CUDA and PoCL caches only in a debug build, where its own cache is off too.)

what writes it default location environment variable
NVIDIA CUDA JIT ~/.nv/ComputeCache CUDA_CACHE_PATH, CUDA_CACHE_DISABLE
AMD ROCm compiler, which hashcat's HIP compile writes into ~/.cache/comgr
PoCL ~/.cache/pocl POCL_CACHE_DIR, POCL_KERNEL_CACHE
Mesa, rusticl ~/.cache/mesa_shader_cache

The scale is worth seeing. On one machine here hashcat's cache is 908 KB while ~/.cache/comgr is 1.5 GB and ~/.cache/pocl is 1.3 GB. So if you cleared hashcat's cache after a driver change and nothing improved, the reason is that you cleared the wrong one.

hashcat also sets TMPDIR to its own profile directory when TMPDIR is unset, so a runtime that caches into TMPDIR lands inside hashcat's directory rather than /tmp.

What is not a cache

~/.local/share/hashcat is hashcat's data directory. It holds hashcat.potfile and sessions/. Deleting it loses your cracked passwords and your restore state, so keep it out of any cleanup.

Finding what you have

$ ls kernels                                    # beside the binary
$ ls ~/.cache/hashcat/kernels ~/.hashcat/kernels
$ du -sh ~/.nv/ComputeCache ~/.cache/comgr ~/.cache/pocl 2>/dev/null

What does the clCreateBuffer() -61 error mean?

hashcat 7.1.2 prints this as clCreateBuffer(): CL_INVALID_BUFFER_SIZE. The number -61 is what older versions printed, and is kept here so people arriving from old forum threads find the page.

This is the typical out-of-memory error, and it is not driver related. It refers to your GPU memory, not host memory.

There is a limit on how much can be allocated in a single block, which is lower than the card's total memory, and that is usually what you have hit. Do not go looking for a fixed figure: it depends on the backend, the runtime and the device. OpenCL guarantees only that a quarter of total memory can be allocated at once, and a runtime is free to allow more. On one machine here the same question gets four different answers, from a quarter up to 85 percent.

Read your own number off hashcat -I. Where the runtime reports a single-block limit, hashcat prints it next to the total:

  Memory.Total...: 16304 MB (limited to 13858 MB allocatable in one block)

Not every device prints the suffix. When it is absent the runtime did not report a separate limit.

What to try:

  • reduce -n (--kernel-accel)
  • reduce -w
  • reduce the number of hashes, or split the list and run it in parts
  • --backend-devices-keepfree sets a percentage of device memory hashcat leaves alone, which exists for exactly this situation

What does the clEnqueueCopyBuffer() -30 error mean?

hashcat 7.1.2 prints this as clEnqueueCopyBuffer(): CL_INVALID_VALUE. The number -30 is what older versions printed.

This is not a driver related error. This error occurs mostly in cases where you are using too many rules. You can adjust the following parameters to reduce your total rule count:

  • decrease the -g value
  • decrease the number of stacked -r files

There is an arithmetic ceiling you can work out rather than guess at. The release's docs/limits.txt gives it: a rule is capped at 31 functions, which makes each rule 128 bytes on the device, and the whole rule buffer has to fit in one allocation. So the limit is roughly the single-allocation size divided by 128, which that file works out as about 16M rules on an 8 GB card.

What does the cuStreamSynchronize() 702 error mean?

702 is CUDA's CUDA_ERROR_LAUNCH_TIMEOUT. A kernel ran for longer than the display driver's watchdog allows, so the driver killed it and reset the device. It has nothing to do with your rule count.

This happens on a card that is also driving a monitor, because that is where the watchdog applies, and it gets more likely the harder you push. In order:

  • lower the workload with -w 2 or -w 1
  • lower --kernel-accel (-n) or --kernel-loops (-u) by hand
  • best of all, run the attack on a card that is not driving a display

If you need full speed on the card that runs your screen, the watchdog itself can be turned off. On Windows that is a documented Microsoft registry value, and Driver Timeout Patch has the exact steps for Windows and for X11.

Note that 7.1.2 gives you no hint about this: hashcat used to warn “Kernel exec timeout is not disabled” at startup and that warning is commented out in this release, so the timeout is the first you hear of it.

The same overrun on the OpenCL backend usually surfaces as CL_OUT_OF_RESOURCES or a bare driver reset rather than a 702.

How can I use old hashcat/oclHashcat versions?

Old archives stay on hashcat.net, but there is no index to browse: the URL is https://hashcat.net/files/hashcat-<version>.7z, so hashcat-6.2.6.7z and so on. Tagged releases are also on GitHub.

That said, use the current version unless you have a specific reason not to. A newer release generally brings fixes, more modes and better hardware support, and a problem you hit on an old version may simply be one that was fixed. In our opinion, there is only one valid reason to use older versions of hashcat: when AMD/NVidia dropped support for your graphics card and hashcat developers decided that it is more appropriate to support the newer generation cards (and hence support/optimize code for the more recent driver versions) instead of keeping support for no-longer supported GPUs.

Post-Installation

I see only the usage, it seems to be a syntax error. What should I do?

Look at the Usage line at the top of --help:

Usage: hashcat [options]... hash|hashfile|hccapxfile [dictionary|mask|directory]...

The positional arguments have a fixed order: the hash or hash file first, then the wordlist or mask. Options are not positional and can go anywhere, including after the mask.

$ hashcat -m 0 -a 3 hash.txt ?l?l?l?l        # right
$ hashcat -m 0 -a 3 ?l?l?l?l hash.txt        # wrong

The wrong one does not give you the usage, though. hashcat takes ?l?l?l?l as the hash and stops with Hash '?l?l?l?l': Token length exception and No hashes loaded, which is the same thing you see when a hash file path is wrong. See Line-length exception, wait what?

The usage means the number of positional arguments does not fit your attack mode. hashcat counts them per mode and prints the usage when the count is wrong, before it looks at anything else. The two common cases:

  • a command line of options only, with no hash or hash file at all
  • a combinator attack, -a 1, given one wordlist or three. It wants exactly two

Three things people blame for this do something else entirely, and knowing their real symptom saves you time:

  • forgetting -m runs autodetect. You get a table of candidate modes and Please specify the hash-mode with -m [hash-mode].
  • forgetting -a leaves you in straight mode, so your mask is treated as a wordlist path and you get ?l?l?l?l: No such file or directory
  • a shell that ate your mask leaves surplus words, which are dropped in silence

Quote a mask anyway: on Linux if your shell expands ?, and on Windows if it contains ^ or &. Be aware that hashcat will not tell you when this has happened. Surplus words left by an expansion are dropped in silence, so the run proceeds with a mask you did not intend. Check Guess.Mask on the status screen against what you typed.

If that is not your problem, read the full --help output and search the wiki.

hashcat unpacks to 1GB or more, do I really need all the files?

Yes, mostly. hashcat 7.1.2 extracts to about 380 MB, and there is only one thing in there worth deleting.

Almost all of it is modules, the per-hash-mode plugins, and the archive ships both platforms: 582 .so files for Linux and 582 .dll files for Windows. You only ever load one set, so the other set is dead weight.

On Linux:

$ rm modules/*.dll

On Windows:

C:\> del modules\*.so

That takes the folder from 380 MB to about 220 MB on Linux, or about 205 MB on Windows, and nothing stops working. The same is true of the two top-level binaries and the bridges folder, which also carry both platforms, but those are small enough not to bother with.

Do not go looking for kernels to delete. Old advice told you to remove precompiled .ptx files for GPUs you do not own, or AMD kernels by VLIW generation. hashcat ships no precompiled kernels at all. It ships OpenCL source in OpenCL, 27 MB of it, and compiles what it needs on first use into a kernels directory that does not exist until you run it. Deleting from OpenCL will break modes you later want.

The kernels directory is the one thing in the folder that keeps growing, since it gains a file per mode and device combination you use. It is safe to delete whenever you like; hashcat rebuilds what it needs, at the cost of a slow first run. See Where does hashcat keep its compiled kernels?

Basic cracking knowledge

What does "Status: Exhausted" mean?

Exhausted simply means hashcat has tried every possible password combination in the attack you have provided, and failed to crack 100% of all hashes given. In other words, hashcat has finished doing everything you told it to do – it has exhausted its search to crack the hashes. You should run hashcat again with a different attack/word list/mask etc.

What is a hashcat mask file?

A hashcat mask file is a set of masks stored in a single plain text file with extension .hcmask.

The format of the lines is defined here: hashcat mask file

Each line of a .hcmask file could contain this information (the order of the fields is exactly as mentioned here):

  • --custom-charset1 (short -1, optional): define a custom char set which you can reference in the mask with ?1
  • --custom-charset2 (short -2, optional): define a custom char set which you can reference in the mask with ?2
  • --custom-charset3 (short -3, optional): define a custom char set which you can reference in the mask with ?3
  • --custom-charset4 (short -4, optional): define a custom char set which you can reference in the mask with ?4
  • mask (required): specify the mask

Each and every field mentioned above is separated by a comma (“,”, without quotes). If an optional field is not specified, the comma does not need and can't be written down, hence if you only want to specify a mask (without the optional custom char sets), the lines should look like this:

?u?l?l?l?l?s
?u?l?l?l?l?l?s
?l?l?l?l?l
?l?l?l?l?l?s

Note: all the custom char sets were not set here (-1, -2, -3, -4), nor used (?1, ?2, ?3, ?4), hence we only have 1 single field (and hence no commas).

On the other hand, if you for instance only need --custom-charset1 (or short -1), your lines would look something like this:

?l?d,?l?l?l?l?1
?l?u,?1?1?1?1?1?1

Note: here the --custom-charset1 would be set to ?l?d with the first hashcat mask file line and to ?l?u with the second line (those 2 lines are independent). Also note that when the --custom-charset1 (or short -1) field was set, it should also be used within the mask with ?1. The opposite is also true, when you use a custom char set within the mask (?1) you should also set the --custom-charset1 (or short -1) field to a valid value.

If 2 custom char sets are needed, you would use something like this:

?l?d,?u?l,?2?1?1?1?1?1?1

Note: here we set --custom-charset1 (or short -1) to ?l?d and --custom-charset2 (or short -2) to ?u?l and then use those custom char sets within the mask.

… and so on and so forth (up to the 8 supported custom charsets).

There are 4 important syntax rules:

  • if you use \, the comma will be seen by *hashcat as a literal character, i.e. the backward slash escapes the comma (which would otherwise be seen as a separator between the different fields: -1, -2, -3, -4 and the mask)
  • if you use # at the beginning of the line, the line will be treated as a comment and hence ignored
  • if you use \# at the beginning of the line, the # will be used literally as a character (since the backward slash escapes the # which otherwise would be seen as a comment)
  • if you want to use a question mark (“?”, without quotes) within your mask or within your custom charsets, you need to escape it with an additional question mark, i.e. ?? means that the question mark is used as a literal symbol

You can use .hcmask files as simple as this:

$ ./hashcat.bin -m 0 -a 3 md5_hash.txt my.hcmask

In other words, you simply specify the path to the .hcmask file at the position in the command line where you normally would use the single mask.

What exactly is a weak hash?

A hash whose plaintext is empty, that means a 0-length password, typically when somebody just hit enter.

hashcat used to check for these by itself at startup, and --weak-hash-threshold set how many salts it would do that for. That feature was removed, because it cost startup time on a list with many salts and caused crashes on macOS. hashcat no longer looks for empty passwords on its own.

You can still try one, and it costs a single candidate. Put an empty line in a wordlist:

$ printf '\n' > empty.dict
$ hashcat -m 0 -a 0 hash.txt empty.dict
d41d8cd98f00b204e9800998ecf8427e:

What is a potfile?

(short URL: https://hashcat.net/faq/potfile)

The potfile stores which hashes were already cracked, and thus won't be cracked again.

The reason for this is that otherwise e.g. the output file (--outfile, -o) could contain the same and identical hash output again and again (if different attack types lead to the same password candidates which do match).

It also has an enormous effect on cracking salted hashes. If hashcat notices that all hashes which are bound to a specific salt are cracked, it's safe to not generate new guesses for this specific salt anymore. This means, for example, if you have 2 hashes with different salts and one is cracked, the speed is doubled. Now if you restart the session for any reason the potfile marks the one cracked hash as cracked and so the salt is marked as cracked. You startup with doubled guessing speed.

You can disable potfile support completely by using --potfile-disable. However we strongly recommend leaving it enabled. If you have a large list of salted hashes for example and you do not use --remove and for whatever reason you have to restart this cracking session all your bonus guessing speed is loss.

Note that using a potfile is very different from the idea which you have in mind when you are used to use --remove. Having a hashlist with only uncracked hashes is fine, but with potfile you can do the same if you use the --left switch. For example, if your cracking session is finished and you want to have a left list, you simply run:

$ ./hashcat.bin --left -o leftlist.txt -m 0 hash.txt

Now you have both, the original list and the left list.

It's also safe to copy (or append) the data from one potfile to another.

The potfile is a file named hashcat.potfile in hashcat's profile folder, and --potfile-path overrides the location.

Where the profile folder is depends on how hashcat was installed, not on the operating system. If you extracted the archive and run hashcat from that folder, which is how most people run it, the profile folder is that folder, so the potfile sits next to hashcat.bin or hashcat.exe and not under your home directory at all.

The home-directory locations apply to a build installed to a system prefix, by make install or by a distribution package, and only on Unix-likes and macOS. There hashcat picks the first of:

  • $HOME/.hashcat/ if that directory already exists. Versions before 6.2.2 created it.
  • $XDG_DATA_HOME/hashcat if XDG_DATA_HOME is set.
  • $HOME/.local/share/hashcat/ otherwise.

If you cannot find it, that list is the search order. Note this is the data directory, which also holds your sessions, so it is not the same thing as the kernel cache and should not be cleared casually. See Where does hashcat keep its compiled kernels?

How can I identify the hash type?

There is no concrete method for identifying a hash algorithm using the hash alone.

Some hashes have signatures which give a strong indication of which algorithm was used, such as “$1$” for md5crypt. Usually you can rely on this information; however, this method of identification is not bullet-proof! For example, consider an algorithm such as crypt(sha256(pass), “$1$”).

For hashes which have no signature, it is virtually impossible to distinguish which algorithm was used. A string of 32 hex characters could be LM, NTLM, MD4, MD5, double MD5, triple md5, md5(sha512(pass)), so on and so forth. There is literally an infinite number of possibilities for what the algorithm may be!

hashcat can narrow it down for you. --identify lists every mode whose structure matches your hash:

$ hashcat --identify hash.txt
The following hash-mode match the structure of your input hash:

      # | Name                                                       | Category
  ======+============================================================+========================
    500 | md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5)                  | Operating System

Note what it says: match the structure. It is not telling you what the hash is, it is telling you what it could be. For a signatured hash like that one there is a single candidate and you are done. For a bare 32 hex characters, the same command offers 12:

$ hashcat --identify hash.txt
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
   ...

NTLM is in that list too, further down. The point is the length of it, not the order.

Third-party “hash identifier” tools do the same regular expression matching but present one answer as though it were certain, which is worse than presenting twelve.

So use --identify to get the shortlist, then pick from it using what you know about where the hash came from: which operating system, which application, which version. That knowledge is what actually decides it. If you can read the source of the thing that made the hash, read it.

For some example hashes see the example hashes wiki page.

I left out -m and hashcat printed a list of hash modes and stopped. What now?

Leaving -m off does not pick a default. hashcat tries to work the mode out from the shape of your hash, and there are two outcomes.

One mode fits, so it uses it and warns you that it guessed:

Hash-mode was not specified with -m. Attempting to auto-detect hash mode.
The following mode was auto-detected as the only one matching your input hash:

    500 | md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5) | Operating System

NOTE: Auto-detect is best effort. The correct hash-mode is NOT guaranteed!
Do NOT report auto-detect issues unless you are certain of the hash type.

Several fit, so it refuses to choose and stops:

The following 12 hash-modes match the structure of your input hash:
...
Please specify the hash-mode with -m [hash-mode].

That second one is not an error in your command, it is hashcat declining to guess. A bare 32 character hex string really could be a dozen things. Pick the right number from the list using what you know about where the hash came from, and pass it with -m.

To ask for the shortlist deliberately, without starting an attack, use --identify. See How can I identify the hash type?

Hashcat reports "Status: Cracked", but did not print the hash value, and the outfile is empty. What happened?

When nothing is printed and everything was already cracked, hashcat tells you so and tells you what to do:

INFO: All hashes found as potfile and/or empty entries! Use --show to display them.

If only some were already known, you get a count instead:

INFO: Removed 3 hashes found as potfile entries.

and the singular form INFO: Removed hash found as potfile entry. for one. A hash whose password is the empty string is reported separately, as INFO: Removed hash found as empty hash.

Either way the hashes are not cracked again, for these reasons:

  • you already cracked the hash, hence cracking the same hash would be a waste of resources;
  • the potfile has already all the information to be able to show the password (use --show);
  • potfile support wasn't disabled, thus a check for every hash in your hash file (or the one hash in the command line) will be performed. If it was found in the .potfile, it will be marked as already cracked and will not be loaded by hashcat

The reason for not showing/storing the same crack is that it is a waste of resources to crack a single hash more than once and hashcat assumes that if it was already cracked, the user did already “see” the password. The potfile-reading feature (at startup) will check if some hashes within the hash list were already cracked and marked them as “already cracked” without trying to crack them again and again.

It is possible to show all the cracks with --show and this will show every previous cracks (stored within the .potfile). The path to the .potfile can be specified by the --potfile-path command line argument. This way it is possible that you use different .potfile files for each and every different hash list (the default name is “hashcat.potfile”).

It is possible to avoid the warning and the storage of all cracks by using --potfile-disable.

How can I show previously cracked passwords, and output them in a specific format (e.g. email:password)?

To accomplish this, you need to use the --show switch.

--show is always used after the hashes have been cracked; therefore, you only need (and should not specify more than) these command line arguments:

  • --show (required)
  • the hash type (-m). There is no default mode: leave -m off and hashcat tries to autodetect, which works when exactly one mode fits the hash and refuses when several do. A bare 32 character hex hash matches 12 modes, so for the raw hashes in this example you must give -m
  • the path to the pot file (--potfile-path, optional): specify a specific input .potfile (containing previous cracks)
  • user name (--username, optional): tell *hashcat that the hash file has user names / email addresses in the first field of each and every line
  • the output file (--outfile, -o, optional): file to store the output
  • the output format (--outfile-format, optional): which fields to print, and you can ask for several separated by commas, so --outfile-format=1,2 gives hash then password. See --help for the list
  • quiet mode (--quiet, optional): enables the quiet mode (does not show any extra info)
  • the original hash file (required): this needs to be the unmodified hash list, --remove does modify / delete hashes from the hash file

Example:

$ ./hashcat.bin -m 0 --show -o formatted_output.txt --outfile-format 2 original_MD5_hashes.txt

That gives the passwords alone. For the email:password shape the question asks about you need --username as well, so that hashcat knows the first field of each line is a name, as in the two-step example below.

Note: You do not need, and should not specify, any mask, dictionary, wordlist directory, etc.

An example how this 2-fold process would look like is shown below:

1. crack the hashes:

$ ./hashcat.bin -m 0 --username --potfile-path md5.potfile original_MD5_hashes.txt rockyou.txt

2. output the hashes to a file with --show:

$ ./hashcat.bin -m 0 --username --potfile-path md5.potfile --show -o formatted_output.txt --outfile-format 2 original_MD5_hashes.txt

What is a keyspace?

Keyspace is the term used to refer to the number of possible combinations for a specified attack. In hashcat, it has a special meaning that is not exactly the same as the usual meaning. The output of --keyspace is designed to be used to distribute cracking, i.e. you can use the value from --keyspace and divide it into x chunks (best would be if the chunk size depends on the performance of your individual nodes if they are different) and use the -s/-l parameters for distributed cracking.

To tell devices which candidates to generate on GPU, hashcat keeps track of some of the candidates on the host. To do this, there are two loops: a loop that runs on the host (the “base loop”), and a loop that runs on the device (the “mod(ifier) loop.”)

To work between multiple compute nodes, hashcat must divide up and distribute portions of the base loop. This is where --keyspace, -s, and -l come into play. --keyspace reports the size of the base loop that executes on the host so that we know how to divide up the work. -s and -l control the start/stop positions of the base loop.

In other words, hashcat's --keyspace is specifically designed to optimize distribution of work, and is not a literal representation of the total possible keyspace for a given attack.

What --keyspace reports is the size of the base loop, so the number is usually smaller than the real number of candidates, and rules never multiply it:

attack base loop
-a 0 words in the wordlist
-a 0 with rules words in the wordlist, unchanged. The rules run in the mod loop
-a 1 depends on the kernel, see below
-a 3 the mask positions in the base loop only, so ?d?d?d?d reports 1000 and not 10000
-a 6 words in the wordlist, because the dictionary is the significant side
-a 7 the mask, because the mask is the significant side, so ?d?d with a list reports 100
-a 9 not meaningful, one candidate is tried against one hash

-a 1 is worth spelling out, because it changes with the kernel. With the pure kernels, which is the default, the left wordlist is always the base loop and the right one runs in the mod loop, so the keyspace is the left list's word count whichever list is bigger. With the optimized kernels, under -O or on a mode that has only an optimized kernel, hashcat picks the bigger list as the base instead. So the same two files can report two different numbers depending on -O, and swapping their order changes the answer only in the first case.

The following are in master and not in the 7.1.2 release. See hashcat.net/beta.

attack base loop
-a 4 the grammar's own count, which is large: the shipped ruleset reports 12747516022634
-a 5 words in the wordlist
-a 8 whatever the feed produces, for a wordlist feed the words in it
-a 12 the mask, unless ?w is the first marker, in which case the wordlist

A worked example, with a 3 word list and a 3 rule file:

$ hashcat -m 0 -a 0 words.txt --keyspace
3
$ hashcat -m 0 -a 0 words.txt -r rules.txt --keyspace
3
$ hashcat -m 0 -a 3 ?d?d?d?d --keyspace
1000

These figures describe candidate generation on the device, which is the normal case. With -S (--slow-candidates) the host generates every candidate instead, so rules do multiply the number and a mask reports its whole keyspace. If you are splitting work across nodes, check which of the two you are running before you divide anything up.

Do not try to derive these by hand. Run --keyspace and use what it gives you.

Leave the hash file out of a --keyspace command. It takes the attack, not the hashes, and passing a hash file makes it read that as the wordlist.

See also this forum post.

How to deal with special non-latin characters (chinese, arabic, etc...) ?

Various languages use different character encodings. It may seem overwhelming that there are many different encoding types, many languages, and many different characters that exist. What you need to know when it comes to encoding is that most, if not all, hashing algorithms do not care about encoding at all. Hash algorithms just work with the single bytes a password is composed of. That means if you input a password that contains, for example, a German umlaut, this can result in multiple different hashes of the same unsalted algorithm. To further illustrate this, you will see three different hashes depending on whether you have used ISO-8859-1, utf-8 or utf-16.

hashcat can do the conversion for you. --encoding-from says what your wordlist is in, and --encoding-to says what the algorithm wants. Here is a one word utf-8 list holding the German name “muller” spelled with an umlaut, shown as bytes so you can see what changes:

$ xxd words.txt
00000000: 6dc3 bc6c 6c65 720a                      m..ller.

$ hashcat -a 0 --stdout words.txt | xxd
00000000: 6dc3 bc6c 6c65 720a                      m..ller.

$ hashcat -a 0 --stdout words.txt --encoding-from utf-8 --encoding-to iso-8859-1 | xxd
00000000: 6dfc 6c6c 6572 0a                        m.ller.

$ hashcat -a 0 --stdout words.txt --encoding-from utf-8 --encoding-to utf-16le | xxd
00000000: 6d00 fc00 6c00 6c00 6500 7200 0a         m...l.l.e.r..

With no options the bytes go through untouched: the umlaut stays two bytes, c3 bc. Converted to iso-8859-1 it becomes the single byte fc, and converted to utf-16le every character gains a null byte. Those are three different inputs and they give three different hashes, which is the whole problem in one picture.

--stdout with xxd is the way to check you are feeding the algorithm what you think you are.

If you would rather convert the file up front, iconv does it:

$ iconv -f utf-8 -t iso-8859-1 rockyou.txt > rockyou.iso

For brute force there are ready-made charsets in the charsets folder, organised by language and encoding:

$ ls charsets
base58.hcchr  combined  DES_full.hcchr  DES_special  special  standard

$ ls charsets/special
Castilian  Catalan  French  German  Greek  Italian  ...

Note: hashcat charset files (.hcchr) can be used like any other custom charsets (--custom-charset1 (-1) through --custom-charset8 (-8)).

But note, nowadays a lot of sources use utf-8. This makes things a bit more complicated.

When a charset file does not cover what you need, --hex-charset lets you write the characters as raw bytes, and --hex-salt and --hex-wordlist do the same for salts and wordlists. Every encoding question comes down to bytes in the end, and those options let you say exactly which bytes you mean.

Unfortunately there is no bullet-proofed way to know if a specific hash (or hash list) uses a specific encoding. The most straight-forward way would be to just try and crack some hashes with the encoding you think is most likely. But this could fail of course when you try with a very “different” encoding. To see if hashcat does indeed run the correct password candidates you want it to run, you can just create some example hashes and try to crack them with for instance a Dictionary-Attack or with a mask attack by using .hcchr files or --hex-charset.

Can't I just use rainbow tables?

(Short URL: https://hashcat.net/faq/rainbowtables)

Because of advances in GPU speeds, Rainbow tables have largely been displaced by GPU-based cracking solutions like hashcat in modern times, and are now only effective in a very narrow set of circumstances:

1. The password hash algorithm is unsalted;

2. You know how long the password is, and you know what character sets the password is made up of;

3. The keyspace (total possible combinations) is small enough (the password is short enough - usually no more than 8 or 9 characters) - and the character set is small enough (usually not all 95 printable ASCII) to make it feasible to compute all possible hashes in advance and store them;

4. You only have a few hashes to crack (because you can only crack a few at a time with rainbow tables);

5. The password was randomly generated (instead of human-generated, for which much more efficient and productive GPU attacks are available);

6. The hash is important enough that you need to crack it in a guaranteed shorter amount of time than the equivalent attack on GPU;

7. All of the above is worth eating up terabytes of storage that's usually unused.

In other words, the only remaining rainbow-table use cases - cases like “I am a pentester and I know for a fact that this company's Domain Admin account is 9 chars random upper and lower and numbers, and I need it before tomorrow” - are now extremely rare. And with the same amount of resources, *millions* of passwords can be cracked in the same amount of time, using GPUs and a reasonable amount of skill.

(And to be explicit: hashcat does not use, support, or work with rainbow tables in any way.)

How long will it take to crack my hash?

This is like asking "How long is a piece of string?" 🙂

This 100% depends on three things:

  • how much you know about the password
  • how much the person who decided how to create the password knows about making good passwords
  • how much you know about using hashcat and other tools to efficiently generate candidate passwords that match the way the password was created

At one extreme, if you know nothing at all about your password, then you might crack it instantly … or never.

At the other end of the spectrum, if you know exactly how the password was generated, and you know how much compute power you have available and how fast hashcat will run on that hardware, then you can calculate exactly how long it will take to crack – in the worst case – by exhausting the entire possible keyspace.

Between these two extremes is all of the other possibilities, in which you know *some* things about the password, but other things are not known. If those other things can be quantified, you can predict a maximum time to crack. If they cannot be quantified, then it is impossible to calculate how long it will take.

For example, if I ask you to guess a number between 1 and 100, and I simply say “yes” or “no” when you guess, then in the best case, it will take one guess, and in the worst case, it will take 100 guesses. (This is exactly how password cracking works - you are making guesses).

Notice, however, that there are two factors in play in this scenario: how many possibilities there are (100), and how long it takes you to make each guess (in this case, spoken aloud). If the guessing rate is faster, it will take less time to exhaust. But even if you know the selection strategy, if the total number of possibilities is very high, it may be impossible to exhaust. (If I picked a random number between 1 and a quadrillion, and you had to speak each guess, you could never guess them all!).

But all of this example only applies if you know how the password was created. If you don't know, then the cracking process becomes less about math and more about psychology:

  • If the person who created the password picked “password”, and you have a wordlist that includes this word very early, then you will crack the password almost instantly.
  • But if they picked a harder password, it may be harder, or even impossible, to crack it.
  • Even if they have a simple password, if your attack does not generate that very specific candidate password, then you will not crack the hash.

What do the hash type categories mean?

Attack-Modes

Why should I use a mask attack? I just want to "brute" these hashes!

Read Mask attack. A mask attack is a modern and more advanced form of “brute force”.

It can fully replace brute force, and at the same time mask attacks are more flexible and more capable than traditional brute force attacks.

The general options you should consider/need are:

  1. --increment (optional): specifies that the length of the password candidates shouldn't be fixed, but increase in length
  2. --increment-min (optional): the minimum length for --increment (if --increment is used but --increment-min was not set, it defaults to 1)
  3. --increment-max (optional): the maximum length for --increment (if --increment is used but --increment-max was not set, it defaults to the length specified by the mask, see the mask entry below)
  4. --custom-charset1 (-1), --custom-charset2 (-2), --custom-charset3 (-3), --custom-charset4 (-4) (all optional): you can define custom charsets e.g. all lower letters together with all upper letters, plus all digits: --custom-charset1 ?u?l?d (Attention: this is just the definition of a custom charset, you need to use these custom charset definitions within the mask)
  5. mask (required): specifies the charsets (could be built-in or custom ones) and implicitly also the maximum length of the password candidates. If --increment option is not used, it specifies the fixed length (because min and max length would be set to the length implied directly from the mask length itself)

An example command would therefore look something like this:

$ ./hashcat.bin -m 0 -a 3 --increment --increment-min 4 --increment-max 6 hash.txt ?a?a?a?a?a?a?a?a

Explanation:

  • -m 0: we set the hash type to MD5 (see Example hashes)
  • -a 3: set the attack mode to mask attack (see Mask attack)
  • --increment: enable incremental mode (see #1 above)
  • --increment-min 4: set the minimum length of the password candidates to 4 (in this case)
  • --increment-max 6: set the maximum length of the password candidates to 6 (in this case)
  • ?a?a?a?a?a?a?a?a: the mask is a 8 character long string of the built-in charset ?a (“all”, which includes lower and upper case characters, digits and special characters)

Note that even if the mask is of length 8 in this particular example the passwords candidates are limited by --increment-min and --increment-max and hence are of length 4 to 6.

If --increment-max 6 was not specified, the maximum length would be implicitly set to 8 since the mask itself is of length 8.

I do not know the password length, how can I increment the length of the password candidates?

You can use --increment (or short -i), --increment-min and --increment-max.

Make sure that the mask (which should always be set, is required) is at least the same length of the --increment-max value or the maximum password candidate length you want to try (if --increment-max was not specified).
By the way, the value for --increment-max should also not be greater than the length of the mask, i.e. the main limiting factor is the mask length, after that --increment-max, if specified, will further limit the length of the password candidates.

  • Examples of correct commands:
./hashcat.bin -m 0 -a 3 -1 ?d?l --increment --increment-min 5 md5_hash.txt ?1?1?1?1?1?1?1?1 

Note: the limiting length is set by the mask (?1?1?1?1?1?1?1?1). Therefore you can think of this command as if there was an automatically added --increment-max 8. This means you do not need to specify --increment-max 8 if it can be automatically determinate by the mask length.

./hashcat.bin -m 0 -a 3 -i --increment-min 2 --increment-max 6 md5_hash.txt ?a?a?a?a?a?a?a?a

Note: here --increment-max was indeed set to a value less than the mask length. This makes sense in some cases were you do not want to change the mask itself, i.e. leave the 8 position long mask as it was (?a?a?a?a?a?a?a?a).

./hashcat.bin -m 0 -a 3 -i --increment-min 6 --increment-max 8 md5_hash.txt ?a?a?a?a?a?a?a?a

Note: it is even possible to set the --increment-max value to the same length of the mask even if the --increment-max value would be implied anyway by the mask length.

./hashcat.bin -m 0 -a 3 -i --increment-max 6 md5_hash.txt ?l?l?l?l?l?l?l?l?l?l

Note: --increment-min is optional; without it the increment starts at length 1.

-ii (--increment-inverse) grows the mask from the right instead of the left, which is what you want when the end of the password is the part you know.

  • Examples of incorrect commands and reasons why they are incorrect:

Attention: these are commands that should not be used, they do not work (there only purpose is to show you what is not accepted)

./hashcat.bin -m 0 -a 3 --increment --increment-max 8 md5_hash.txt ?a

Note: this is the most common user error, i.e. the user did not understand that the winning limiting factor is always the mask length (here length 1). Even if --increment-max 8 was specified, the mask is too short and therefore hashcat can't increment that mask. The reason why is simple: mask attack is a per-position attack, each position can have its own charset. There is a strict requirement that the user specifies the charset for each position. If the custom or built-in charset was not specified for the (next) position, hashcat can not know what should be use as a charset and hence stops at the position where it was still clear what charset should be used (in this example it is length 1). The decision to stop and to refrain to imply charsets is made by the developers on purpose because otherwise (if hashcat would silently and magically determine a “next implied charset”) there could be strange errors and unexpected behavior.

./hashcat.bin -m 0 -a 3 --increment --increment-min 2 --increment-max 3 md5_hash.txt ?a

Note: the --increment-min of 2 is what makes this fail, because it is longer than the one-position mask. The --increment-max of 3 would merely have been capped to 1 and ignored.

./hashcat.bin -m 0 -a 3 --increment --increment-min 6 --increment-max 10 md5_hash.txt ?a?a?a?a?a?a?a?a

Note: this one does run, but not as far as you asked. An --increment-max above the mask length is silently capped at the mask length, so this covers lengths 6 to 8 and stops, with no warning that the 9 and 10 you asked for were dropped. Lengthen the mask to ?a?a?a?a?a?a?a?a?a?a if you want them. An --increment-min above the mask length is the one that is rejected outright.

./hashcat.bin -m 0 -a 3 --increment --increment-min 4 --increment-max 3 md5_hash.txt ?a?a?a?a?a?a?a?a

Note: the value of --increment-min must always be less or equal to the value of --increment-max. This is not satisfied here since 4 > 3.

For more details about mask attack see Why should I use a mask attack? I just want to "brute" these hashes!

I want to optimize my Brute-Force attack by ordering letters by frequency in a custom charset. How to do it? Does it make sense?

It is a reasonable idea, but hashcat never walks a custom charset in the order you typed it, so there is nothing to gain by reordering one.

With Markov on, which is the default, the order comes from the statistics in the .hcstat2 file. With --markov-disable the statistics are zeroed and the charset is then walked in ascending byte order. Neither is your order. So -1 531ba gives you 1 b a 3 5 by default and 1 3 5 a b with --markov-disable, and never 5 3 1 b a.

Your order is already the default behaviour in spirit, because that is what the Markov statistics are for: they put the likely characters first, per position, from real password data. Reordering a charset by hand is trying to do the same job with worse data.

If you genuinely have better frequency data than the shipped statistics, the supported way to use it is to build your own .hcstat2 and pass it with --markov-hcstat2. hcstat2gen from hashcat-utils builds one from a wordlist.

I want to use rules, but there are three different parameters. When do I use -r, -j and -k?

-r is the one you want most of the time. It takes one or more rule files, and hashcat applies every rule in them to each word.

Which attack modes accept -r has changed, and this is worth getting straight.

  • In the 7.1.2 release, -r works in -a 0 and -a 9 only. Anywhere else it refuses the run: Use of -r/–rules-file and -g/–rules-generate requires attack mode 0 or 9.
  • On master, -r works in every attack mode: 0, 1, 3, 4, 5, 6, 7, 8, 9 and 12. See hashcat.net/beta.

So on the release, a combinator or hybrid attack cannot take a rule file, and -j and -k are how you apply a rule there. They take a single rule each, applied to one side of the input: -j to the left, -k to the right.

On master you can simply use -r in those modes instead, which removes the whole reason -j and -k existed for most people. They are still useful when you want a rule on one side only, which is the one thing -r cannot express, since it applies to the finished candidate.

-g (--generate-rules) follows exactly the same mode rules as -r.

For example a combinator attack that toggles the first character of every input from the leftside.txt:

$ ./hashcat.bin -a 1 example0.hash leftside.txt rightside.txt -j T0

How do I work with -j or -k? Can I use rules files?

First of all … you cannot use rules files with -j or -k. This is a common source of confusion.

The -j and -k parameters accept only individual rule commands specified directly on the command line, not paths to rules files.

What -j and -k actually do:

  • -j, --rule-left=RULE applies rules to each word from the left (first) wordlist
  • -k, --rule-right=RULE applies rules to each word from the right (second) wordlist

-j and -k are primarily used in combinator attacks (-a 1) and hybrid attacks (-a 6, -a 7), where there are two input sources. In a straight attack (-a 0), -j or -k only apply once to the wordlist.

But what you can do is chain multiple rule functions into the single -j or -k parameters:

$ echo "password" | hashcat --stdout -j 'c $1 $!'
Password1!

Also, remember your shell escaping. Some characters (especially $ and !) have special meaning in shells. Use single quotes to prevent shell interpretation, or escape characters appropriately:

For Linux:

# Correct (single quotes prevent shell expansion):
$ ./hashcat -m 0 -a 1 hash.txt d1.txt d2.txt -j '$1'

# Also correct (escaping the dollar sign):
$ ./hashcat -m 0 -a 1 hash.txt d1.txt d2.txt -j "\$1"

# Wrong (shell interprets $1 as a variable):
$ ./hashcat -m 0 -a 1 hash.txt d1.txt d2.txt -j $1

For Windows Command Prompt (cmd.exe)

# Use double quotes, no $ escaping needed:
C:\hashcat> hashcat.exe -m 0 -a 1 hash.txt d1.txt d2.txt -j "$1"

For Windows PowerShell:

# Escape the $ with backtick, use double quotes:
PS C:\hashcat> .\hashcat.exe -m 0 -a 1 hash.txt d1.txt d2.txt -j "`$1"

Also note that some rules syntax only work -j or -k, not with rules files (-r):

  • -j applies to the left input and -k to the right, and whichever names a side that is not a wordlist is accepted and then silently does nothing. So in -a 0 only -j has an effect, in -a 6 only -j, and in -a 7 only -k. No warning is given.
  • Reject rules only work with -j/-k in hashcat.
  • The 'p' positional parameter (for operating on Nth instance of a character) only works with -j or -k.

For more information, see rule-based attacks.

-j and -k take a single rule, not a file. Hand one a path and hashcat reads the path itself as a rule: sometimes that is refused with Invalid or unsupported rule specified -j/–rule-left, and sometimes the characters in the path happen to form a valid chain, in which case it runs and quietly produces nonsense or nothing at all.

On master none of this is needed, because -r works in the combinator and hybrid modes directly. What follows is for the 7.1.2 release, where it does not.

Workarounds, for when you need multiple rules with combinator or hybrid attacks on the release:

  1. Pre-process dictionaries with rules using --stdout and pipe or save the output
  2. Run hashcat multiple times with different -j/-k rules, in a pipeline
  3. For appending or prepending a mask, you do not need a workaround at all. That is what the hybrid attacks are for: -a 6 puts the mask after the word, -a 7 puts it before. See Hybrid attack.
  4. For a mask in the middle of the word, -a 12 takes one mask with ?w where the word goes. Applies to master, see hashcat.net/beta.

How does one use several rules at once?

Firstly, we need to distinguish 2 different cases:

  1. the rules you want to use should be applied: independently from each other, not chained/concatenated, but applied one after the other
  2. the rules you want to use should be applied: together as if they were (previously) combined with combinator.bin, e.g. all rules from the first .rule file are combined with all rules from the second .rule file

For case number 1 you can just “cat” the individual files

Note: it would be better to use some kind of duplicate removal instead, e.g. sort -u, but note also that sort -u does not necessarily remove all duplicates since the rule syntax allows for extra spaces and furthermore a set of 2 different rules may lead to similar or identical plains in some or all situations because it is possible that combination of different rules could be considered as identical even if they are not identical when comparing the rule “text”/strings.

The following description will deal only with case number 2 (the rules should be chained, applied at the same time).

hashcat allows for rule stacking. This can easily be achieved just by appending more rule files to your attack.

Note: hashcat legacy does not support stacking. Only a single -r parameter is permitted.

$ ./hashcat.bin -a 0 -m 0 -r rules/best66.rule -r rules/toggles2.rule hashlist.txt dict.txt 

Note: depending on the rules themselves, the order of the different -r arguments might be very important. You may need to double-check which -r parameter is the first one on the command line (this will be applied first), which should be the second one (this will be applied next), etc …

OK, there is a hybrid attack for append mask and prepend mask, but what if I want to use both at the same time?

Use attack mode 12. You write one mask for the whole candidate and put ?w where the word goes, so both sides are just part of the mask:

$ hashcat -a 12 -m 0 hash.txt ?d?d?w?d?d wordlist.txt

That is two digits prepended and two appended, and nothing else. ?w can sit anywhere in the mask, and you can type fixed characters straight into it as well.

Applies to master. Attack mode 12 is in hashcat's master branch and is not in the 7.1.2 release, which answers Invalid attack mode if you try it. Build from master, or take a precompiled build from hashcat.net/beta.

The older way, with stacked rules

Before -a 12 existed you had to reach for the rule-stacking feature (How does one use several rules at once?). It still works, and it is still the answer if you want a rule's other effects at the same time:

$ hashcat hash.txt wordlist.txt -r rules/hybrid/append_d.rule -r rules/hybrid/append_d.rule -r rules/hybrid/prepend_d.rule -r rules/hybrid/prepend_d.rule

Such rules exist for all the common charsets.

You can easily create your own hybrid rules using maskprocessor: rules_with_maskprocessor

When I use --increment in hybrid attack how does that work?

Given an attack

$ ./hashcat.bin -a 6 example0.hash example.dict ?a?a?a?a?a --increment

hashcat runs the attack once per mask length, growing the mask each time until it reaches the full length. You can watch it in the status display, which names the two sides of a hybrid attack:

Guess.Base.......: File (example.dict), Left Side
Guess.Mod........: Mask (?a) [1], Right Side

then, for the next pass:

Guess.Base.......: File (example.dict), Left Side
Guess.Mod........: Mask (?a?a) [2], Right Side

and so on through [3], [4] and [5]. With -a 7 the mask is on the left and the dictionary on the right, so the two labels swap.

The number in brackets is the mask length, which is the quickest way to see how far the increment has got.

For more details about mask attack see Why should I use a mask attack? I just want to "brute" these hashes! -t is not accepted in every attack mode. It is refused in the straight, combinator and association attacks, where hashcat says Option –markov-threshold is not allowed in combination with –attack mode 0. Markov ordering applies to mask positions, so it only means something where hashcat is generating a mask.

How to use multiple dictionaries?

If you use hashcat with a Dictionary attack (-a 0) you can specify several dictionaries on the command line like this:

$ ./hashcat.bin -m 0 -a 0 hash.txt dict1.txt dict2.txt dict3.txt

Several wordlists work with -a 0 and also with the hybrid modes -a 6 and -a 7, where every positional argument except the mask is a wordlist. -a 1 is the exception: it takes exactly two wordlists and no directory. Only the files directly in a named directory are read; subdirectories are skipped without a word, so a nested collection needs the files flattened or named individually. Note that this also works with so-called globbing (of shell parameters and in this case paths/file names), since your operating system/the shell expands the command lines to (among others) full file paths:

$ ./hashcat.bin -m 0 -a 0 hash.txt ../my_files/*.dict

Furthermore, if you want to specify a directory directly instead, you could simply specify the path to the directory on the command line:

$ ./hashcat.bin -m 0 -a 0 hash.txt wordlists

Note: sometimes it makes sense to do some preparation of the input you want to use for hashcat (outside of hashcat). For instance, it sometimes makes sense to sort and unique the words across several dictionaries if you think there might be several “duplicates”:

$ sort -u -o dict_sorted_uniqued.txt wordlists/*

hashcat utils might also come handy to do some preparation of your wordlists (for instance the splitlen utility etc)

Why are there 5 different toggle rules in the rules/ folder?

You often hear the following: A great and simple way to make your password harder to crack is to use upper-case characters. This means you flip at least two characters of your password to upper-case. But note: don't flip them all. Try to find some balance between password length and number of upper-case characters.

We can exploit this behavior leading to an extreme optimized version of the original Toggle-case attack by generating only all these password candidates that have two to five characters flipped to upper-case. The real strong passwords have this balance, they will not exceed this rule. So we don't need to check them.

This can be done by specialized rules and since hashcat and hashcat legacy support rule-files, they can do toggle-attacks that way too.

See rules/toggles1.rule through rules/toggles5.rule. The number in the name is the most characters a rule in that file will flip, and the files are cumulative: each one covers every combination of 1 up to N flips across positions 1 to 15, so toggles5.rule already contains everything in toggles1 through toggles4. The counts are 15, 120, 575, 1940 and 4943 rules.

So pick the single file that matches how many flips you want to allow. Passing several with repeated -r does not widen the search, it just makes hashcat try the same candidates more than once.

Two other ways exist now. The Table attack with tables/toggle.table gives you every combination rather than a capped number, and attack mode 12 lets you keep these rules while a mask puts something around the word. Both of those are in hashcat's master branch rather than the 7.1.2 release, see hashcat.net/beta.

When I run an attack with -a 3 and I do not specifying a mask, I see it working but what is it doing?

The reason why there is no (syntax) error shown when you didn't specify any mask, is that hashcat/hashcat legacy have some default values for masks, custom charsets etc. This sometimes comes in very handy since the default values were chosen very wisely and do help some new users to get started very quickly.

On the other hand, sometimes this “feature” of having some default values might confuse some users. For instance, the default mask, for good reasons, isn't set to a mask consisting of the built-in charsets ?a or even ?b which some users might expect, but instead it is an optimized mask which should (in general) crack many hashes without covering a way too large keyspace (see the default values page for the current default mask).

This also implies that when you don't specify a mask explicitly, it could happen (and is very likely) that you do not crack some hashes which you might expect to be cracked immediately/easily (because of the reduced keyspace of the default mask). Therefore, we encourage you that you always should specify a mask explicitly to avoid confusion.

If you still do not know how to do so, please read Why should I use a mask attack? I just want to "brute" these hashes!

How does one use the new prince attack mode with hashcat legacy?

Careful with the attack mode number. hashcat-legacy had PRINCE built in as -a 8. The 7.1.2 release has no -a 8 at all and answers Invalid attack mode. On master the number has been reused for the Generic attack, so an old guide telling you -a 8 means PRINCE is wrong twice over. The Generic attack applies to master, see hashcat.net/beta.

In hashcat you pipe princeprocessor in instead:

$ ./pp64.bin rockyou.txt | hashcat -m 22000 -w 3 test.hc22000

For a fast hash you need an amplifier on the hashcat side to reach full speed, because one host process cannot feed a GPU on its own:

$ ./pp64.bin rockyou.txt | hashcat -m 0 -w 3 test.md5 -r rules/rockyou-30000.rule

I have a half-known password. I know the first 4 letters, can hashcat get the rest of the password?

Yeah that actually works, thanks to the mask attack! To understand how to make use of this information you really need to read and understand the mask-attack basics. So please read this article first: Mask Attack

Now that you've read the Mask Attack article it's easy to explain. For example consider that you know that the first 4 chars of the password are “Pass” and you know that there's like 3 or 4 or 5 more letters following from which you do not know if they are letters, digits or symbols you can do the following mask:

Pass?a?a?a?a?a -i

To understand how this works with the incremental, please also read this article:

I do not know the password length, how can I increment the length of the password candidates?

What is the association attack (-a 9), and when should I use it?

-a 9 pairs a candidate list with a specific hash rather than trying every candidate against every hash. It is the mode for the case people ask about most often: you know something about this particular account and want to try it against that account's hash only.

The hints that work are the obvious ones: the username, an old password from an earlier breach, a password hint field, the local part of an email address.

The hash file carries the hint alongside the hash, and you give one candidate per hash:

$ hashcat -a 9 -m 500 user500.hash 1word.dict -r rules/best66.rule

Rules are what make it work, because a hint is rarely the password but is often one rule away from it. In the 7.1.2 release -a 9 is one of only two modes that take -r, the other being -a 0; on master every mode does.

Since each candidate is tried against one hash instead of all of them, the keyspace is tiny and a run finishes quickly even on a slow hash.

Why are there two different hash-modes for Vbulletin?

There are actually two different hash-modes for Vbulletin. Somewhere between version v3 and v4 they've changed the default salt-length from 3 characters to 30 characters. From a high-level programming language view this has no impact but from our low-level view this is really a difference. That's because of the block-modes used in many hashes, even in that case.

Vbulletin uses a scheme that is simply written like this: md5(md5(pass).salt)

So it first computes the md5 hash of the password itself and then it concatinates it with the salt. Since the software rely on PHP and the md5 function in PHP returns by default a ascii hex repesentation we have a total length in the final md5() transformation of length 32 + 30 = 62.

The problem here is that 62 > 55 and 55 is the maximum buffer for a single md5 transformation call. What we actually need to do now, from low-level perspective, is to compute the hash using the buffer of 62 and then compute another md5 with a buffer nearly empty. That's RFC. That means the boundary is version 3.8.5, not 3 versus 4. Before 3.8.5 the salt is 3 bytes and it is 2 md5 calls, which is -m 2611. From 3.8.5 on the salt is 30 bytes and it is 3 md5 calls, which is -m 2711 while the scheme itself stayed untouched. In other words, from GPU kernel view this is a completely different algorithm and that's why they are two different hash-modes.

What are Markov thresholds for?

The -t value in hashcat refers to the markov threshold. When hashcat starts, it loads the markov data and sorts the character transition tables for fast access, and here's the key point: after sorting, characters are indexed from 1 to N based on frequency where index 1 represents the most likely character in a given position. The -t threshold controls how deep hashcat explores these frequency tables. For example, with -t 5, hashcat will stop generating candidates once it reaches characters at index 6 or higher in any position.

Without a threshold, the entire Markov space is used, all 26 lower-case characters in Markov order:

$ ./hashcat --stdout -a 3 a?l
aa
ao
ae
ai
au
ar
al
ah
an
am
as
ay
at
ac
ap
aw
ad
ab
ak
aj
av
ag
af
az
ax
aq

When a threshold is supplied, the Markov space traversal is reduced to the first N most common elements:

$ ./hashcat --stdout -a 3 a?l -t 5
aa
ao
ae
ai
au

And note that the stats thresholds are per position:

$ ./hashcat --stdout -a 3 bbba?l -t 5
bbban
bbbar
bbbal
bbbas
bbbam

Performance

How much faster is cracking on Linux compared to a Windows operating system?

Not at all. The hashing happens on your GPU and the driver is the same code on both, so use whichever you are comfortable with.

The one practical difference is the packaging, not the speed. On Linux an AMD card wants ROCm, and on Windows it wants the Adrenalin driver plus the AMD HIP SDK. See the driver question.

How can I perform a benchmark?

If you want to find out the maximum performance of your setup under ideal conditions (single hash brute force), you can use the built-in benchmark mode.

$ ./hashcat.bin -m 0 -b
hashcat (v7.1.2) starting in benchmark mode

...
Speed.#*.........: 15904.5 MH/s
...

Underneath, it is a brute-force attack with a mask big enough to keep your GPUs busy, against a single dummy hash that nothing can crack: an all-zero digest carrying the mode's own self-test salt. Nothing is randomised, which is why the equivalent command below uses a hash of 32 zeros. The nearest cracking command is:

$ hashcat -m 0 00000000000000000000000000000000 -w 3 -a 3 -O ?a?a?a?a?a?a?a

The -O is not optional if you want to match the benchmark number. Benchmark mode turns the optimized kernels on for you, and says so:

Benchmarking uses hand-optimized kernel code by default.
You can use it in your cracking session by setting the -O option.
To disable the optimized kernel code in benchmark mode, use the -w option.

Note the asymmetry in that last line: inside benchmark mode -w switches the optimized kernels off, whereas in a normal attack -w and -O are unrelated and you would use both together. The mask also belongs to the mode rather than being fixed, so a slower mode benchmarks with a different one.

Leave -O out and you are measuring the pure kernels, which is a fair number for real work but will not match -b.

Please note the actual cracking performance will vary depending on attack type, number of hashes, number of salts, keyspace, and how frequently hashes are being cracked.

The parameters you should consider when starting a benchmark are:

  • --benchmark (short -b, required): tell hashcat that it should perform a benchmark
  • --hash-type (short -m, default is to benchmark several important algorithms, optional): tell hashcat which hash types should be benchmarked
  • -w (optional): benchmarking uses hand optimized kernels by default, and -w turns that off so you can tune with -u and -n yourself. This replaces the old --benchmark-mode
  • --benchmark-all, --benchmark-min and --benchmark-max (optional): benchmark every hash mode, or a range of them

This means, that for instance a command as simple as this:

$ ./hashcat.bin -b

will give you a list of benchmark results for the most common hash types available in hashcat, using the hand optimized kernels.

Why is my attack slower than the benchmark?

Because they are not running the same kernels. -b uses the optimized kernels at -w 3; a normal attack uses the pure kernels unless you ask otherwise. hashcat points this out at the start of a run:

ATTENTION! Pure (unoptimized) backend kernels selected.
Pure kernels can crack longer passwords, but drastically reduce performance.
If you want to switch to optimized kernels, append -O to your commandline.

Append -O and you get the benchmark's kernels, at the cost of a password length cap, 55 rather than 256 on most modes. See the length question.

Kernels are only the first reason, though. A benchmark is the best case by construction: one hash, no salt, a mask big enough to saturate the device. A real attack is slower whenever it has more salts, too little work to fill the GPU, or hashes being cracked and removed as it goes. If -O does not close most of the gap, the problem is workload rather than kernels, and How to create more work for full speed? is the place to look.

My desktop lags too much, anything I can do to avoid it?

Use a lower workload profile with -w. There are four, and the table below is from --help:

  # | Performance | Runtime | Power Consumption | Desktop Impact
 ===+=============+=========+===================+=================
  1 | Low         |   2 ms  | Low               | Minimal
  2 | Default     |  12 ms  | Economic          | Noticeable
  3 | High        |  96 ms  | High              | Unresponsive
  4 | Nightmare   | 480 ms  | Insane            | Headless

The Runtime column is what matters for lag. It is how long a single kernel invocation runs before the GPU comes back to the driver, so at -w 3 your desktop waits up to 96 ms for every frame. Profile 4 is for machines with nobody sitting at them.

$ hashcat -m 0 -a 3 -w 1 example0.hash ?a?a?a?a?a?a?a?a?a?a

-w 1 costs you speed. If speed matters more than the lag, run at -w 3 (the default is -w 2) and stop using the machine while it works.

On a machine with more than one GPU there is a better answer than trading speed for comfort: the lag comes from the card drawing your desktop, so leave that one out. Run hashcat -I, find the device number of the card that is not driving the display, and select it with -d, for example -d 2. The excluded card keeps your desktop responsive while the others run flat out.

Is the 64 bit version faster than the 32 bit version?

There is no 32 bit version any more. hashcat ships one Linux binary and one Windows binary and both are 64 bit, so there is nothing to choose between.

The question mattered back when both were built. For hashcat-legacy the 64 bit build was faster, because it hashes on the CPU. For hashcat it made no difference to cracking speed, since the work happens on the GPU, though the 64 bit build could address more memory.

What is it that you call "GPU power"?

GPU power is how many base words one GPU works on in parallel per kernel invocation. It is the product of three numbers, with a fourth that changes how they are packed rather than how many there are:

  • S, the number of compute units. hashcat -I reports it as Processor(s)
  • T, threads per unit. hashcat -I reports it as Preferred.Thrd., and it follows the architecture rather than the vendor: 32 on RDNA and on NVIDIA, 64 on the older GCN parts
  • N, the outer loop step size, which is -n and which the workload profile sets for you
  • V, the vector size, which is not another multiplier. The batch is S * T * N base words; a vectorised kernel packs V of them into each work item, so the same batch runs on fewer work items rather than on more words. It is 1 on a GPU unless the optimized kernels are in play

Do not read constants off this page for your own card. Run hashcat -I and use what it tells you. You can override -n, the inner loop with -u, and the thread count with -T, but autotune picks these well and beating it by hand is unusual.

How to create more work for full speed?

(short URL: https://hashcat.net/faq/morework)

This is a really important topic when working with hashcat. Let me explain how hashcat works internally, and why this is so important to understand.

GPUs are not magic superfast compute devices that are thousands of times faster than CPUs. In fact GPUs are quite slow and dumb compared to CPUs. If they weren't, we wouldn't even use CPUs anymore; CPUs would simply be replaced with GPU architectures. What makes GPUs fast is the fact that there are thousands of slow, dumb cores (shaders.) This means that in order to make full use of a GPU, we have to parallelize the workload so that each of those slow, dumb cores have enough work to do. Password cracking is what is known as an “embarrassingly parallel problem” so it is easy to parallelize, but we still have to structure the attack (both internally and externally) to make it amenable to acceleration.

For most hash algorithms (with the exception of very slow hash algorithms), it is not sufficient to simply send the GPU a list of password candidates to hash. Generating candidates on the host computer and transferring them to the GPU for hashing is an order of magnitude slower than just hashing on the host directly, due to PCI-e bandwidth and host-device transfer latency (the PCI-e copy process takes longer than the actual hashing process.) To solve this problem, we need some sort of workload amplifier to ensure there's enough work available for our GPUs. In the case of password cracking, generating password candidates on the GPU provides precisely the sort of amplification we need. In hashcat we accomplish this by splitting attacks up into two loops: a “base loop”, and a “mod(ifier) loop.” The base loop is executed on the host computer and contains the initial password candidates (the “base words.”) The mod loop is executed on the GPU, and generates the final password candidates from the base words on the GPU directly. The mod loop is our amplifier – this is the source of our GPU acceleration.

What happens in the mod loop depends on the attack mode. For brute force, a portion of the mask is calculated in the base loop, while the remaining portion of the mask is calculated in the mod loop. For straight mode, words from the wordlist comprise the base loop, while rules are applied in the mod loop (the on-GPU rule engine that executes in the mod loop is our amplifier.) For hybrid modes, words from the wordlist comprise the base loop, while the brute force mask is processed in the mod loop (generating each mask and appending it to base words is our amplifier.)

Without the amplifier, there is no GPU acceleration for fast hashes. If the base or mod loop keyspace is too small, you will not get full GPU acceleration. So the trick is providing enough work for full GPU acceleration, while not providing too much work that the job will never complete.

More work for fast hashes

As should be clear from the above, supplying more work for fast hashes is about *executing more of what you're doing on the GPUs*. There are a few ways to do this:

* Use wordlist+rules. A few rules can help, but a few thousand can be the sweet spot. Test on your setup to find the combination that is more efficient for your attack. For straight mode against fast hashes, your wordlist should have at least 10 million words and you should supply at least 1000 rules.

* Use masks. Masks execute on GPU, so mask-based attacks (including hybrid attacks) are useful here - but note that, much like rules, using too few can slow down your attack.

More work for slow hashes

Now, we mentioned above that this advice is for most hash algorithms, with the exception of very slow hash algorithms. Slow hash algorithms use some variety of compute-hardening techniques to make the hash computation more resource-intensive and more time-consuming. For slow hash algorithms, we do not need (nor oftentimes do we want) an amplifier to keep the GPU busy, as the GPU will be busy enough with computing the hashes. Using attacks without amplifiers often provide the best efficiency.

Because we are very limited in the number of guesses we can make with slow hashes, you're often working with very small, highly targeted wordlists. However, sometimes this can have an inverse effect and result in a wordlist being too small to create enough parallelism for the GPU. There are two solutions for this:

  • Use -S (--slow-candidates), which is hashcat's own on-host generator and does this in one process instead of two:
    $ hashcat -m 22000 test.hc22000 wordlist.txt -r rules/best66.rule -S

    Unlike a pipe it keeps the keyspace, so you still get a progress percentage and a working restore point.

  • Or feed hashcat the finished candidates through a pipe:
$ hashcat --stdout wordlist.txt -r rules/best66.rule | hashcat -m 22000 test.hc22000
$ pp64.bin wordlist.txt | hashcat -m 22000 test.hc22000
  • Sometimes maskprocessor makes sense, but only for very small keyspaces:
$ mp64.bin test?d?d?d?d?d?d | hashcat -m 22000 test.hc22000

Note: pipes work in Windows the same as they do in Linux.

Those attack modes are usually already built into hashcat, so why should we use a pipe? The reason is, as explained above, masks are split in half internally in hashcat, with one half being processed in the base loop, and the other half processed in the mod loop, in order to make use of the amplification technique. But this reduces the number of base words, and for small keyspaces, reduces our parallelism, thus resulting in reduced performance.

Is piping a wordlist slower than reading from file?

No, piping is usually equally fast. What it costs you is not speed but information: with input arriving on a pipe hashcat has no keyspace, so there is no progress percentage and no estimated time, the interactive prompt gives way to periodic status output, and the restore point cannot advance, so a piped session cannot be resumed. If you only wanted host-side candidate generation, -S does that in one process and keeps all of the above.

However, most candidate generators are not fast enough for hashcat. For fast hashes such as MD5, it is crucial to expand the candidates on the GPU with rules or masks in order to achieve full acceleration. However be aware that different rulesets are not producing constant speeds. Especially big rulesets can lead to a significant speed decrease. The increase from using rules as amplifier can therefor cancel itself out depending how complicated the rules are.

Why is my attack so slow?

  • To find out about what maximum speeds you can expect from your system, run a benchmark How can I perform a benchmark? Note: Benchmarks are a “best case” scenario, i.e. single hash brute force. Real-world speed can vary depending on the number of hashes and attack mode.
  • In most of the cases of “slow speeds” you simply did not create enough work for hashcat. Read How to create more work for full speed?
  • You can add more pressure on the GPU using the -w 3 parameter. Note: this will cause your desktop to lag because the GPU is so busy it can not compute desktop changes like mouse movement.
  • Your GPUs are overheating. The card throttles itself first, which shows up as a falling speed, and then hashcat stops the run: --hwmon-temp-abort defaults to 90 degrees on Linux and Windows, 100 on macOS. So a hot card first gets slow and then aborts. See the overheating question
  • The more hashes are in your hashlist, the slower the speed gets. The biggest difference is between one or more hashes because for single hashes hashcat can use special optimisations which only can be used when cracking just a single hash
  • Some hashes are designed to run slow, like bcrypt, scrypt or bitcoin wallet. Deal with it.

Why does hashcat says it has only 2% GPU utilization?

Not having 100% GPU utilization is usually an indicator for a too-small keyspace (meaning, not enough work to be done).

Read How to create more work for full speed?

How is it possible that hashcat does not utilize all GPUs?

If the number of base-words is so small that it is smaller than the GPU power of a GPU, then there is simply no work left that a second, or a third, or a fourth GPU could handle.

Read How to create more work for full speed?

Why does hashcat sometimes get very slow at the end of an attack?

First, what counts as the end of an attack. hashcat means the point where the number of base words left is less than the sum of the GPU power of all your GPUs. Read What is it that you call "GPU power"?

You know it has happened because hashcat says so:

Approaching final keyspace - workload adjusted.

When it happens, hashcat shares out the base words that are left across the devices in proportion to how much work each one can take, rather than handing every device a full batch. Each device therefore runs with less parallelism than it wants, and less parallelism means a lower rate, so the reported speed falls even though nothing is wrong.

Note that if you have GPUs of different speed it can occur that some GPU finish sooner than others, leading to a situation when some GPU end up in 0 H/s.

Why is hashcat taking so long to report progress?

(short URL: https://hashcat.net/faq/slowprogress)

This is a problem related to (a) how GPU parallelization works in general in combination with (b) an algorithm with a very high iteration count.

When it comes to modern hashing algorithms they are typically designed in a way that they are not parallelizable and that the calculation has to be done in serial. You can not start computing iteration 2 if you have not computed iteration 1 before. They depend on each other. This means for slow algorithms like 7-Zip (if we want to make use of the parallelization power of a gpu) we have to place a single password candidate on a single shader (which a gpu has many) and compute the entire hash on a it. This can take a very long time, depending on the iteration count of the algorithm. We're talking about times up to a minute here for a single hash computation. But what we got for doing it is that we're able to run a few 100k at the same time and make use of the parallelization power of the gpu in that way. That's why it takes so long for hashcat to report any progress, because it actually takes that long to compute a single hash with a high iteration count.

In the past hashcat did not report any speed for such extreme cases, resulting in hashing speed of 0H/s. Some users may remember such cases and wondering “why isn't it doing anything”. From a technical perspective nothing changed. In the past and also today the GPU just need that much time. The only difference is in newer hashcat versions is that it creates an extrapolation based on the current progress of the iterations. For example it knows that the shader processed like 10000 of 10000000 iterations in X time and therefore it can tell how much it will (eventually) take to process the full iteration count and recomputes this into a more or less valid hashing speed, which is in that case not the real one. This is what you are shown in the speed counter.

But that's the theoretical part. When it comes to GPGPU it's actually not enough to feed as many password candidates to the GPU as it has shaders. There's a lot of context switching going on the GPU which we have no control over. To keep all the shaders busy for the entire time we have to feed it with password candidates many times the number of shaders.

(See this forum post for an illustration with examples)

Why am I getting a "bitmap table overflowed" error?

// “Bitmap table overflowed at 18 bits. This typically happens with too many hashes and reduces your performance. You can increase the bitmap table size with –bitmap-max, but this creates a trade-off between L2-cache and bitmap efficiency. It is therefore not guaranteed to restore full performance.” //

If you get this message, you're working with larger lists of hashes than most ordinary users of hashcat - on the order of millions of hashes.

First, why you're seeing it. Hashcat need to work with lists of hashes quickly, and loads them into a memory structure for this. By default, this memory structure is sized to maximize efficient use of hardware, memory, caching, etc for typical hardware and hashlist sizes. But beyond a certain size of number of hashes, the size of this memory structure can become less efficient (sort of like running out of RAM and having to swap to disk, but this is only a very rough analogy).

So by default hashcat sets a maximum size that this structure may be grown to, and only grows it as far as it actually needs. Raising that maximum with --bitmap-max can win back some performance, but it also costs a significant amount of GPU memory, so it is a trade-off rather than a free improvement.

Next, what you can do about it. You can manually increase the bitmap size, but performance may be reduced more than expected. An alternative approach that can preserve attack efficiency is to simply split the target list into smaller lists that fit within the bitmap table size, but you must then run your attack multiple times. For the “middle range” of a few millions of hashes, adjusting the bitmap size may be more efficient. Eventually, you may reach the point where it's more efficient to split your list.

If you're working with large lists like this, it is up to you to test your use case with your hardware to find the performance that works best for you.

This Reddit thread has an interesting overview of what bitmap tables are for in hashcat.

Special features

Can I restore a hashcat session?

The command line switch you are looking for is --restore.

The only parameters allowed when restoring a session are:

  • --restore (required): tell hashcat that it should restore a previous session
  • --session (optional): specify the session name of the previous session that hashcat should restore
  • --restore-file-path (optional): use specific restore file path

Note: if you did use --session when starting the cracking job, you also need to use --session with the same session name to restore it.

A session fed from a pipe cannot be resumed. hashcat never advances the restore point for candidates arriving on stdin, so there is nothing to resume from and a restore would re-read the stream from the beginning. You can see it in the status of a piped run:

Guess.Base.......: Pipe
Progress.........: 3000000
Restore.Point....: 0

Compare the same attack reading the wordlist as a file, where both figures advance and carry a total:

Progress.........: 3000000/3000000 (100.00%)
Restore.Point....: 3000000/3000000 (100.00%)

So if a long job needs to survive an interruption, give hashcat the wordlist as a file rather than piping it, or use -S when you wanted host-side candidate generation, since that keeps the keyspace and the restore point.

Further parameters and switches are currently not allowed, e.g. you can't simply add -w 3 when restoring (i.e. --restore -w 3) because it will be ignored. If you really know what you are doing and want to change some parameters in your .restore file, you might want to use some third-party tool like analyze_hc_restore

Also see restore for more details about the .restore file format.

Can I restart hashcat on a different PC or is it possible to add a new GPU to my system?

Yes! All you need to ensure is that no files have been modified.

The most important file here is the .restore file (the file name depends on the session name used, see --session parameter, so it is $session.restore). You need to copy at least the original hash list and the .restore file to the new computer.

Therefore, if you move to a different PC make sure all the paths are the same and all files exist.

To get more information about which files we mean you can use this utility to find out: https://github.com/philsmd/analyze_hc_restore

How can I distribute the work on different computers / nodes?

If you want to make use of multiple computers on a network, you can use a distributed wrapper.

Hashtopolis is the one in active use. It works over the internet, not just a LAN, and it moved to its own organisation, so older links you find will redirect:

It grew out of Hashtopus, which is still on GitHub at curlyboi/hashtopus but is abandoned by its own README, so treat it as history rather than an option.

Disthc at github.com/unix-ninja/disthc still exists, but nothing has been committed to it since 2014, so treat it as abandoned.

Hashstack from Sagitta was the commercial option. Both sagitta.pw and terahash.com have stopped answering, so there is nothing to point at (gone).

We neither develop nor maintain nor support any of these third-party tools. Ask their authors.

Can hashcat coordinate several machines by itself?

Yes, with the brain. It is not a job scheduler like the wrappers above: it is a shared memory of what has already been tried, so several machines working the same hash list do not repeat each other.

One host runs the server:

$ hashcat --brain-server

and each client joins it with -z:

$ hashcat -z --brain-host 10.0.0.1 --brain-port 13743 --brain-password secret -m 22000 hashes.hc22000 wordlist.txt

-z also switches on -S, because the brain has to see candidates on the host to know what was tried. That means the brain suits slow hashes, where you are making few guesses and each one is expensive, and is a poor fit for fast hashes, where the bookkeeping costs more than the duplicate work it saves.

--brain-client-features chooses what it tracks: the attack positions, the candidates themselves, or both. Related options are --brain-session and --brain-server-timer.

I read somewhere to use VCL for distributed cracking, is this still a thing?

VCL was one of the first tries for distributed hashcat, but there are better alternatives today.

See this: How can I distribute the work on different computers / nodes?

Can hashcat send an email once a hash has been found?

No. In order to achieve this, you will need to wrap your hashcat attack in a script that sends an email when hashcat is finished.

Why is my script unable to communicate with the hashcat / hashcat legacy prompt?

The reason behind is that hashcat and hashcat legacy have this prompt:

[s]tatus [p]ause [b]ypass [c]heckpoint [f]inish [q]uit =>

([p]ause becomes [r]esume once paused; the two never appear together.)

Normally a terminal hands a program a whole line at a time, so pressing “s” would sit in a buffer until you also pressed Enter. That would make the prompt useless.

So hashcat puts the terminal into non-canonical mode and asks for a minimum of one byte, which is what lets a single keypress arrive immediately. In code that is clearing ICANON and setting VMIN to 1.

The side effect is that a script feeding hashcat's stdin through an ordinary pipe does not get that behaviour, because a pipe is not a terminal. You can still drive hashcat from a script, but you have to give it a PTY: use expect, or Python's pty module, or script -c.

I got a hash cracked on a different computer, can I tell hashcat about that while it is running?

The answer is yes - but before we explain how to do it, let's answer the question of why you want to do it. The answer is simple, especially when you're cracking salted hashes.

Imagine that you have a large hashlist with 100 salts. This will reduce your guessing speed by a factor of 100. Once all hashes bound to a given salt are cracked, hashcat notices this and skips over that specific salt. This immediately increases the overall performance, because now the guessing speed is only divided by 99. If you crack another salt, the speed is divided by 98, and so on. That's why it's useful to tell hashcat about cracked hashes while it's still running.

When hashcat starts it creates a $session.outfiles directory, so hashcat.outfiles by default and named after --session otherwise.

Where it appears follows the same rule as the potfile. Running the extracted archive, it is created beside hashcat.bin. For a packaged install it is under the session directory in your home, ~/.local/share/hashcat/sessions unless XDG_DATA_HOME or an existing ~/.hashcat moves it. It only exists while a session is running, so look for it during the run rather than afterwards, and --outfile-check-dir puts it wherever you want.

This directory can be used to tell hashcat that a specific hash was cracked on a different computer/node or with another cracker (such as hashcat-legacy). The expected file format is not just plain (which sometimes confuses people), but instead the full hash[:salt]:plain.

So point another cracker's --outfile at that directory, or copy finished result files into it, and the running hashcat picks them up within --outfile-check-timer seconds.

The parameters that you can use to modify the default settings/behavior are:

--outfile-check-dir        | Dir  | Specify the directory to monitor 3rd party outfiles
--outfile-check-timer      | Num  | Sets seconds between outfile checks to X

hashcat will continuously check this directory for new cracks (and modified/new files). The synchronization between the computers is open for almost any implementation. Most commonly, this will be an NFS export or CIFS share. But in theory it could be also synced via something like rsync, etc.

Note: some users confuse the induction (--induction-dir) and loopback (--loopback) feature with the feature mentioned above, but they are (very) different:

  • outfile check: as described above in detail, this is used when you already exactly know some hash[:salt]:plain combinations, because a subset or all of the hash(es) were already cracked on other computer/nodes or with other crackers
  • induction: in the induction directory you can add some (new) plains that hashcat should load/use after the current dictionary is finished
  • loopback: re-use the plains/passwords that did crack a hash, e.g. apply some rules - after the first run - to the modified and matching plains. This kind of looping will only stop if no more plains match.

How do I extract the hashes from Office (Word, Excel, etc.) documents?

Please use office2john.py from John the Ripper to extract the required information from an office file. The older office2hashcat.py lived in a repository that has since been removed.

After you have extracted the “hashes” with the script linked above, you need to either know the office version number or compare the hashes directly with the example_hashes. Depending on the version number/signature of the hashes you select the corresponding hash mode and start hashcat with the -m value you got.

How do I extract the hashes from PDF documents?

You should use pdf2john.pl from John the Ripper to extract the required information of the .pdf files. The older pdf2hashcat.py lived in a repository that has since been removed. The output “hashes” could have different signatures depending on the pdf version. For some example hashes see: example hashes (-m 10400, -m 10500, -m 10600 or -m 10700).

pdf “hashes” with different hash types (-m values) need to be cracked separately, i.e. you need to have different cracking jobs for each hash type and specify the correct -m value. But if several hashes were generated by the same PDF software version, they can be cracked together and the hash file would look like any other multi-hash file (one hash per line).

How do I extract the hashes from TrueCrypt volumes?

In order to crack TrueCrypt volumes, you will need to feed hashcat with the correct binary data file. Where this data lives depends on the type of volume you are dealing with.

The rules are as follows:

  1. for a TrueCrypt boot volume (i.e. the computer starts with the TrueCrypt Boot Loader) you need to extract 512 bytes starting with offset 31744 (62 * 512 bytes). This is true for TrueCrypt 7.0 or later. For TrueCrypt versions before 7.0 there might be different offsets.

    Explanation for this is that the volume header (which stores the hash info) is located at the last sector of the first track of the system drive. Since a track is usually 63 sectors long (1 sector is 512 bytes), the volume header is at sector 63 - 1 (62).

  2. if TrueCrypt uses a hidden partition or volume, you need to skip the first 64K bytes (65536) and extract the next 512 bytes.
    dd if=hashcat_ripemd160_AES_hidden.raw of=hashcat_ripemd160_AES_hidden.tc bs=1 skip=65536 count=512
  3. in all other cases (files, non-booting partitions) you need the first 512 Bytes of the file or partition.

You do not have to do any of that by hand. hashcat ships the converter, in tools:

$ python3 tools/truecrypt2hashcat.py /dev/sda > hash.txt
$ hashcat -m 29311 hash.txt wordlist.txt

It does the seek for you, so --offset replaces the arithmetic above:

the volume is pass
a file, or a partition that does not boot nothing, offset 0 is the default
a boot volume --offset bootable
a hidden volume --offset hidden
a hidden volume on a boot drive --offset bootable+hidden

tools holds 22 of these converters, so it is worth a look before writing a pipeline: veracrypt2hashcat.py, luks2hashcat.py, bitlocker2hashcat.py, metamask2hashcat.py and more.

If you would rather do the seek by hand, these are the three cases as dd commands:

$ dd if=/dev/sda   of=header.bin bs=512 skip=62    count=1     # boot volume, offset 31744
$ dd if=volume.tc  of=header.bin bs=1   skip=65536 count=512   # hidden volume
$ dd if=volume.tc  of=header.bin bs=512            count=1     # anything else

Watch the units: the boot case skips 62 blocks of 512 bytes, the hidden case skips 65536 single bytes. Mix them up and you get 512 bytes of the wrong place, which parses as a hash and then never cracks.

Given a 512 byte header in a file, the hash line is $truecrypt$ or $veracrypt$, then the first 64 bytes as hex, then $, then the remaining 448 bytes as hex:

$ xxd -p -c 512 header.bin | sed -E 's/^(.{128})(.*)$/$truecrypt$\1$\2/' > hash.txt

Picking the mode. The last two digits, written XY here, say which hash and which key size, and boot mode is its own X per hash rather than a flag you add, so do not try to derive one mode from another. For TrueCrypt, -m 293XY:

X hash
1 RIPEMD160
2 SHA512
3 Whirlpool
4 RIPEMD160, boot mode

Only RIPEMD160 has a boot variant here. Y is 1, 2 or 3 for XTS 512, 1024 or 1536 bit. So -m 29311 is RIPEMD160 with XTS 512 bit and -m 29341 is the same volume in boot mode.

If you do not know which, do not work through twelve slow modes by hand. Run --identify on the hash line and it will narrow the list for you:

$ hashcat --identify hash.txt

The older -m 62XY and -m 137XY modes are marked (legacy) in --help. They take the raw 512 byte file directly instead of a hash line, and they still work, but new material should use the current modes.

The example hashes page lists both. As always the password for an example hash is “hashcat”.

How do I extract the hashes from VeraCrypt volumes?

Use the converter hashcat ships, exactly as for TrueCrypt, with the same --offset choices:

$ python3 tools/veracrypt2hashcat.py /dev/sda > hash.txt
$ hashcat -m 29411 hash.txt wordlist.txt

VeraCrypt's modes are not TrueCrypt's with a 4 in front. It supports more hashes, and the boot variants sit at their own numbers, so -m 294XY has its own table:

X hash
1 RIPEMD160
2 SHA512
3 Whirlpool
4 RIPEMD160, boot mode
5 SHA256
6 SHA256, boot mode
7 Streebog-512
8 Streebog-512, boot mode

Y is 1, 2 or 3 for XTS 512, 1024 or 1536 bit. Note that SHA512 and Whirlpool have no boot variant at all, so there is no mode for a SHA512 boot volume: if you are looking for one, the volume is using a different hash than you think.

If the volume boots and the password was typed on a non-US keyboard, you need one more option. A pre-boot password is entered against the bootloader's own US scancode map, so the bytes stored are not the ones your layout produces. Pass the matching file from layouts with --keyboard-layout-mapping:

$ hashcat -m 29461 hash.txt wordlist.txt --keyboard-layout-mapping layouts/de.hckmap

Eight layouts ship: ch_de, ch_fr, da, de, it, ru, se and us. Without the right one the attack runs to exhaustion and finds nothing even when the password is in your wordlist, which is a miserable way to spend a week.

VeraCrypt also supports a personal iterations multiplier. If the volume was made with one, hashcat needs to know, and --veracrypt-pim-start and --veracrypt-pim-stop let you search a range of them. Keyfiles go in with --veracrypt-keyfiles.

How can I crack passwords from htpasswd?

The format of Apache htpasswd password files does support several hashing algorithms, for instance Apache MD5 (“$apr1”), raw sha1 (“{SHA}”), DEScrypt, etc

Depending on the signature, you need to select the correct hash type (-m value). See example hashes for some examples.

The format of htpasswd lines is:

user:hash

You do not need to remove the username at all, you can just simply use the --username switch.

Which one you meet depends on the flag the file was made with. htpasswd has defaulted to MD5 since Apache 2.2.18, so $apr1$ is still the common case, and everything else has to be asked for:

htpasswd flag signature hashcat
none, or -m $apr1$ -m 1600
-B $2y$ -m 3200
-2 $5$ -m 7400
-5 $6$ -m 1800
-s {SHA} -m 101
-d no prefix -m 1500

DEScrypt, -m 1500, turns up in genuinely old files and truncates the password at 8 characters:

admin:48c/R8JAv757A

(the password here is “hashcat”)

How can I crack SL3?

Start by going somewhere else. We don't care where you go from there.

The story behind this: https://hashcat.net/forum/thread-1887.html

How can I crack multiple WPA handshakes at once?

Use -m 22000, and it is easy, because 22000 is a text format with one handshake per line. Put the lines in one file and hashcat cracks them all in the same run.

hcxpcapngtool already does this for you. Point it at a capture and it writes every handshake it found into a single file:

$ hcxpcapngtool -o all.hc22000 capture.pcapng

To join files you converted separately, just concatenate them:

$ cat single/*.hc22000 > all.hc22000

On Windows:

C:\> copy /b single\*.hc22000 all.hc22000

The networks do not have to come from the same capture. See Cracking WPA/WPA2 for getting the captures in the first place.

Expect the speed to drop as you add networks, because each one is a different salt and hashcat has to work on all of them. That is normal and it is still far quicker than running one attack per network. Use --status to watch progress, and hashcat writes each network to the potfile as it falls.

Older guides tell you to concatenate .hccapx files instead. That worked for -m 2500, and 7.1.2 will not run that mode at all: it prints the deprecation notice and stops without cracking anything. --deprecated-check-disable forces it, but that is the wrong answer here. Convert the capture with hcxpcapngtool and use 22000. The old material is on the hccapx page in the archive.

What means "rejected" in the status view?

There are 2 possible reasons why some password candidates are being rejected:

  • the algorithm itself has some limitations: minimum and/or maximum password length
  • hashcat has some upper limits of password length depending on the attack mode (-a value)

Some hashing algorithms, like -m 1500 = DEScrypt, do have some limits. In case of DEScrypt the limit is: any password can not be longer than 8. hashcat and hashcat legacy do know these password length restrictions and will automatically filter the password candidates accordingly, i.e. they will be ignored and the number of rejected password candidates will be increased.

This can also be seen in the status screen:

...
Rejected.........: 1/4 (25.00%)
...

In this particular case 1 out of 4 password candidates (25%) were rejected by hashcat.

Also entire masks can be rejected by hashcat (e.g. if you have several of them in a .hcmask file, but it is not limited to .hcmask files). You will see a warning like this one:

WARNING: skipping mask '?l?l?l?l?l?l?l?l?l' because it is larger than the maximum password length

It is possible to use some rules to avoid that password candidates will be rejected, for instance see I don't want hashcat to reject words from my wordlist if they are too long, can it truncate them instead?.

This also brings up an important point, if we apply some rules (-j/-k/-r) or combine several words (-a 1), it is not always possible to reject password candidates immediately by the host (CPU). Therefore, it is possible that the password candidates or words already “reached” the GPU (they were copied to the GPU) but can't and won't be rejected by the host and be counted as rejected, since only the GPU can decide if they should be rejected. This is because hashcat uses a rule engine directly on GPU and can combine plains on your graphics cards too.

If you want to avoid this behavior, you can just pipe the password candidates to hashcat (and thus avoid that -a 1 or rules are used by hashcat at all). If this pipe method is used and thus hashcat uses a “Dictionary-Attack” -a 0, all password candidates will be rejected as soon as possible because the built-in filter can already reject the plains that do not match the limitation on the host (CPU). It depends from case to case which method is faster, i.e. either using -a 1 (or -r) on GPU or use the piping method to filter some plains as soon as possible.

What is the maximum supported password length?

(short URL: https://hashcat.net/faq/lengths)

256 bytes, for the pure kernels, which is what hashcat uses by default. 430 of the 582 hash modes in 7.1.2 allow the full 256.

With -O you get the optimized kernels instead, and those stop at 55. Some modes only have an optimized kernel, 44 of them, so those are limited to 55 whether you ask for -O or not.

A minority of modes are limited by the algorithm rather than by hashcat, and no kernel choice changes that. LM cannot hold more than 7 characters, descrypt more than 8. Those are properties of the hash.

Do not guess, and do not trust a list on a wiki page. Ask hashcat. It prints the limits for the mode you chose on every run:

$ hashcat -m 0 -a 3 hash.txt ?l?l?l
Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 256
...
Kernel.Feature...: Pure Kernel (password length 0-256 bytes)

$ hashcat -m 0 -a 3 hash.txt ?l?l?l -O
Maximum password length supported by kernel: 55
...
Kernel.Feature...: Optimized Kernel (password length 0-55 bytes)

To look a mode up without running an attack, ask for its details:

$ hashcat -m 500 <nowiki>--example-hashes --machine-readable</nowiki>
{ "500": { "name": "md5crypt, MD5 (Unix), Cisco-IOS $1$ (MD5)", ...
  "password_len_min": 0, "password_len_max": 256,
  "salt_len_min": 0, "salt_len_max": 256,
  "kernel_type": [ "pure", "optimized" ], ... } }

That is generated from the module, so it will not drift the way a hand-written table does. One caveat: it reports the pure kernel's figure. For the 44 modes that have only an optimized kernel it can say 256 while the run itself enforces 55 or less.

So when the number matters, take it from the run rather than from the table. Every run prints it:

Minimum password length supported by kernel: 0
Maximum password length supported by kernel: 55
...
Kernel.Feature...: Optimized Kernel (password length 0-55 bytes)

What is the maximum supported salt length?

256 bytes for the pure kernels, and 472 of the salted modes allow the full 256. With -O the limit is 51.

As with passwords, some modes set a shorter salt length because the application that produced the hash does. hashcat reports the number for your mode on every run, when the mode has a generic salt:

$ hashcat -m 10 -a 3 hash.txt ?l?l?l -O
Maximum password length supported by kernel: 55
Minimum salt length supported by kernel: 0
Maximum salt length supported by kernel: 51

What is the maximum supported password length for optimized kernels?

55. The reason it is not simply 256 is performance, and it is not a small difference: allowing long passwords costs somewhere between nothing and a factor of three, depending on the algorithm. Four things cause that.

  • Zero-based optimizations. Many algorithms can be simplified when whole words of the input are known to be zero. With a short limit, positions above the limit were guaranteed zero, and dozens of operations could be dropped from every step. See the Passwords13 presentation: js-ocohaaaa.pdf
  • Register pressure. A password of 15 characters or less fits in four 32-bit registers. Longer ones need more, and once the kernel needs more registers than the hardware has, the compiler spills to global memory and everything slows down.
  • Wordlist caching. hashcat sorts words by length before sending them, because many algorithms are faster when every input in a batch is the same length. That sorting needs host memory in proportion to the maximum length, and raising the maximum raises the requirement by the same factor.
  • Branching. Most algorithms process input in fixed-size blocks, 64 bytes for MD5, feeding each digest into the next block. Supporting more blocks means branching, and GPUs are bad at branching.

Some limits come from the algorithm and are not hashcat's choice at all:

  • -m 3000 LM, 7
  • -m 1500 descrypt, 8
  • -m 8500 RACF, 8
  • -m 9710, -m 9810, -m 10410 the collider modes, 5

For fast hashes the attack mode matters too. In a combinator attack neither word may exceed 31 characters, but the two together may, so a 24 character word on the left and a 28 character word on the right is fine and gives a 52 character candidate.

Algorithms that hash UTF-16 halve what you can reach from a plaintext point of view, because each character costs two bytes. 27 characters is 54 bytes.

This page used to carry a table of per-mode limits. It is gone, because 14 of its 17 entries had become wrong: the pure kernels raised most of those modes to 256 while the table still claimed 16 or 40. Use --example-hashes --machine-readable for the mode you care about, as shown above.

What is the maximum supported salt length for optimized kernels?

51 for the generic hash types such as md5($pass.$salt) or HMAC-SHA256. hashcat prints it on every run, so you never have to take a wiki page's word for it:

Maximum salt length supported by kernel: 51

The named hash types are different. For something like Drupal7 the salt length follows the specification of the application that created the hash, so the question does not really arise: you are not choosing the salt, the application did.

You cannot raise this limit. What you can do is ask for a new named hash type with its own limits, which makes sense when the application is prominent enough to deserve one. See I want to request some new algorithms or features, how can I accomplish this?

I do not want hashcat to reject words from my wordlist if they are too long, can it truncate them instead?

That's indeed possible and very simple. For example, if you're going to crack DEScrypt hashes, they have a maximum length of 8. If you run a typical wordlist on it, for example “rockyou.txt” there are many password of length 9 and more.

That means hashcat will reject them.

There's a simple way to avoid this. If you truncate all words from the wordlist to length 8 it will not skip them. This can be done on-the-fly using the -j rule.

'8

The ' rule means truncate. This has some negative effects, too. For example imagine your wordlist contains something like this:

password1
password1234
password1337

Truncating them at position 8 means that all of them will result in simply “password”. This will create unneccesary double checks.

How can I perform a combinator attack with three wordlists (triple combinator, 3-way combinator)?

hashcat-utils ships a command line utility called combinator3. This tool allows one to specify 3 (different or identical) wordlists as command line parameters and it will combine each word within the first wordlist, with each word from the second one and each word from the third wordlist.

$ ./combinator3.bin dict1.txt dict2.txt dict3.txt

Note: the total number of resulting password candidates will be determined by words_in_dict1 * words_in_dict2 * word_in_dict3. From this formula it should be clear, that this total number of combinations and resulting words will be very high depending on the number of lines of the 3 files.

In some (rare) cases it could make more sense to use -a 1 (combinator attack) with -j / -k rules to prepend/append a static plain or pipe combinator2 to hashcat and apply some rules with the -r argument. It depends from case to case which method is faster and/or easier.

Can I load multiple hashlists at once?

This is not supported.

If all the hashes in your hashlists are of the same hash-type it is safe to copy them all into a single hashlist.

If they are not all the same type you can still put them in one file, but be careful with --remove. It rewrites the hash file to hold the uncracked hashes it was able to parse for the -m you gave, which means anything it could not parse for that mode is dropped as well. Mixing types and using --remove therefore loses the hashes belonging to the other types. Keep a copy of the original before you start.

I want to skip password candidates that have repeating characters. Is this possible?

Well, it's not supported built-in. But maskprocessor supports this feature through it's -q option. You could simply pipe the output of maskprocessor to hashcat (or use fifos with hashcat legacy).

That looks like the following:

$ mp64.bin -q 3 ?d?d?d?d?d?d?d?d | hashcat -m 22000 test.hc22000

maskprocessor has a second, different limit, which counts a character's occurrences anywhere in the candidate rather than only in a run:

$ mp64.bin -r 3 ?d?d?d?d?d?d?d?d | hashcat -m 22000 test.hc22000

Do not confuse the two. -q limits identical characters that sit next to each other, -r limits how many times a character may appear in the whole string. See maskprocessor for what the numbers mean.

Pipes behave the same on Windows as on Linux, so this works there too.

LM consists of two hashes but are split for use with hashcat. How to get them back into one piece?

This question is kind of outdated. Current hashcat versions have native support for this.

  • If the hashes are 16 chars long, --show will show the hash (part1) and plain if cracked, and --left will show the hash parts which were not cracked

ELSE if the hash is 32 chars long (“both parts” of the hash in one line):

  • The output will contain [notfound] within the password part of the output that was not cracked, e.g. [notfound]abc means that the second part was cracked while the first one was not, hashcat[notfound] means that the second part was not found
  • hashcat checks if the 2nd part is the empty string hash (weak hash) and if this is the case it will be automatically marked as cracked (regardless if in .potfile or not)
  • If both parts were found (2nd part could be weak hash too), there will be no [notfound] in the output line
  • --left will only show the parts that were not cracked or the whole hash (2 parts) if both parts were not found

1 the reasons behind this “parts” is that LM hashes can consist of a password length of maximum 14 characters. But the important detail is that the hashes can be splitted into 2 individual hashes (which hashcat of course does to optimize the attack, i.e. hashcat could also crack the easier part of the 14 char password separately, and the user could attack the second part by doing educated guesses with the information given), each of the parts have a maximum password length of 7

Btw. also the --username switch and the --outfile-format command line argument work with this --show feature for LM hashes

IOW, to make use of it, you need to use the --show parameter. To understand how to use --show correctly, refer to this article:

How can I show previously cracked passwords, and output them in a specific format (e.g. email:password)?

Here's an example:

$ cat hash
ec97b64dce94d891299bd128c1101fd6
$ ./hashcat.bin -m 3000 -a 3 -w 3 -o cracked.txt --quiet hash ?u?u?u?u?u?u?u

Here's the “normal” outfile, one hash per line:

$ cat cracked.txt
ec97b64dce94d891:AMAZING
299bd128c1101fd6:HASHCAT

But now let's put them back into one piece:

$ ./hashcat.bin -m 3000 --show --quiet hash
ec97b64dce94d891299bd128c1101fd6:AMAZINGHASHCAT

PS: You can also use -o to write to an outfile

What is "Integer overflow detected in keyspace of wordlist"?

To prevent errors, hashcat checks at the start of each new attack that the product of the base word count and the amplifier count does not overflow an unsigned 64-bit integer. In some cases this check is delayed, such as when using mask files, increment mode, or folders with wordlists.

The solution is usually to reduce the total number of possibilities in the attack.

Hardware

How can I make sure that my GPU is supported?

  • For NVidia GPUs see: supported NVidia (cuda) GPUs
  • For AMD GPUs: developer.amd.com/tools-and-sdks/opencl-zone/amd-accelerated-parallel-processing-app-sdk/system-requirements-driver-compatibility (gone, AMD retired the APP SDK pages)

In practice the question answers itself through the driver. hashcat needs a current driver and its compiler package, and those stopped supporting old cards long before hashcat did, so if the vendor's current driver installs and sees your card, hashcat will too. See the driver question.

hashcat refuses a runtime that is too old and tells you which one. In 7.1.2 the floors are CUDA 9.0 for both the driver and NVRTC, and HIP 6.2.0 on Linux or 4.04 on Windows. An old CUDA ends the run; an old HIP falls back to OpenCL. --force does not lift either. See How does one install the correct driver for the GPU(s)?

The quickest check is simply to run hashcat -I and see whether your card is listed. Two things in that output look like faults and are not: the same card appears once per backend that can reach it, cross-referenced by an (Alias: #N) line, and a CPU is listed under whichever vendor's OpenCL runtime drives it, which may not be the CPU's own vendor. See hashcat -I lists my GPU more than once.

What is the best GPU for hashcat for "total speed", "speed by watt" and "speed by price"?

Due to the nature of this subject changing continuously there is no definitive answer, and any card named here would be wrong within a year. The old advice here was to buy a high end dual GPU card for speed by watt. Nobody has made one of those since the Radeon Pro Duo and the Titan Z, so it no longer applies. For more details on “total speed” and “speed by price” see Is there a general benchmark table for all GPU?

Is it worth renting cloud GPUs rather than buying them?

It depends on how busy the cards would be, and the break-even is easier to work out than people expect.

Renting wins when you crack occasionally. You pay nothing between jobs, you skip the up-front cost, and the power, cooling, noise and depreciation are somebody else's problem. You can also take a much bigger machine than you would ever buy, for the few hours you need it.

Buying wins when the cards would run most of the time. Rented compute is priced to cover the hardware plus a margin, so past a certain duty cycle you are paying for the card several times over.

Things worth knowing before you start:

  • Benchmark first. Rent the smallest instance of the type you are considering, run hashcat -b for your hash mode, and work out the cost per hash from real numbers rather than from the instance name.
  • Spot and preemptible instances are much cheaper, and can be taken away mid-run. That is survivable if you plan for it: use --session, and keep the session files and the potfile on storage that outlives the instance. A replacement instance is a different machine, so the relevant answer is Can I restart hashcat on a different PC? rather than the plain restore one: the paths have to match.
  • Check the terms of service. Several providers restrict or forbid password cracking on their infrastructure, including against hashes you own. Read the policy rather than assuming, because having an account closed mid-engagement is expensive.
  • You are putting the hashes on somebody else's computer. For client work that may not be permitted at all, whatever the provider allows.
  • Watch the incidental costs. Egress and storage for large wordlists can be a surprising share of a short job.

Is there a general benchmark table for all GPU?

No, and there has not been a maintained one for years. Every attempt has gone stale, including the one this page used to link, which was made for hashcat v1.30 in 2014 and is no use for judging a card you can buy today.

Two things work better:

  • Run it yourself. hashcat -b takes a few minutes and gives you numbers for your own card, your own driver and the current version, which is what you actually want to compare.
  • Search the forum for the card you are considering. People post -b output there, and a result from someone running a recent version is worth more than any table.

When you compare numbers from somewhere else, check which hashcat version and which hash mode they used. A speed without both of those is not a measurement.

Does the PCI-Express speed have any influence on cracking speed?

Actually, yes. But in reality, no. If you go for pure Brute-Force it has absolutely no effect.

If you go for wordlist based attacks, the only difference is how long it takes for your host system to copy new wordlist data to your GPU. While it copies the data, the GPU is busy and can not compute. For example with PCI-E v2.0 x1 we can do 4 Gbit/s and with x16 we can do 64 Gbit/s. This sounds like alot, but it's not. First this number is bits not bytes and more important this is the speed per second. We also meassure guessing speed in X per second, that means if we take a full second to transfer a specific amount of data the guessing speed is 0. That means, to not influence with guessing speed we need to be able to transfer our wordlist data in less than a percent of a second.

Here is the shape of it. hashcat sends one batch of base words per kernel invocation, and the batch is as large as the device's parallelism, the S * T * N figure from GPU power. The words are packed for the trip, a compressed buffer plus an index, rather than each getting a fixed-width slot, so the cost per word is close to the length of the word itself and a full batch is a few megabytes rather than tens.

Two things follow, and they are what actually matter:

  • A link is 16 times narrower at x1 than at x16 for the same generation, so if transfer ever limits you, that is the size of the effect.
  • An amplifier divides the cost away. Add 5000 rules and the same batch is reused 5000 times on the device before the next one is needed, so whatever the transfer cost was, it is now that divided by 5000.

So: pure brute force is unaffected, because the candidates are made on the device and nothing is sent. A wordlist attack with a decent amplifier is effectively unaffected for the same reason. A wordlist attack with no amplifier against a fast hash is the one case where the link can show up, and there you have a much bigger problem than PCI-Express, described in How to create more work for full speed?

If you want a number for your own setup rather than a rule of thumb, measure it: run the same attack at -w 1 and -w 3 and see whether the speed scales with the batch size. If it does, you are not transfer bound.

Should I attach Crossfire (AMD) / SLI (NVidia) bridges?

Mostly a moot question now, since neither vendor ships those bridges for current consumer cards. If you have them on older hardware, do not use them for cracking.

The reason is that such a bridge exists to make several GPUs look like one to software that cannot handle more than one, which is a games problem. hashcat handles multiple GPUs natively, so the bridge adds overhead and takes away the per-device control that -d gives you.

My GPU overheats sometimes. Can hashcat automatically pause in case of overheating or with a script?

hashcat will not pause and resume, but it will stop: --hwmon-temp-abort takes a temperature in Celsius and aborts the run when a device goes above it, so the default of 90 stops at 91. Only OpenCL GPU devices are watched, not CPU devices. It is on by default, at 90 degrees on Linux and Windows and 100 on macOS, so a normal cracking run stops before a card cooks itself.

The watchdog does not cover every run. -b, --speed-only and --progress-only set the abort temperature to 0, so those run with no thermal limit. Do not use a benchmark to find out whether marginal cooling holds up: run a real attack for that.

$ hashcat -m 0 -a 3 hash.txt ?a?a?a?a --hwmon-temp-abort=85

Pausing is deliberately not offered, because a card that is too hot at full load will be too hot again the moment it resumes, so you would get a loop rather than a fix. Better to run cooler on purpose: -w 1 asks for the low workload profile, and --kernel-loops (-u) and --kernel-accel (-n) let you turn the pressure down by hand.

The lever most people miss is the one outside hashcat: a power limit. Capping the card's board power with the vendor's own tool, nvidia-smi -pl on NVIDIA or the ROCm equivalent on AMD, drops temperature far more than it drops cracking speed, because the top of the clock range costs disproportionate power. It is usually a better trade than -w 1.

Do not reach for --hwmon-disable here. It does not just quieten the readings: it sets the temperature abort to 0 as well, so it removes the automatic stop described above and leaves the card with no protection for that run. It is for a machine whose sensors hashcat cannot read, not for a machine that runs hot. If you use it, set your fans to full yourself and watch the card another way.

The best way to fix the problem is to invest some time investigating in how to improve the cooling and if you finally have found some ways to do so, invest some money in better cooling hardware (more/better high pressure fans) or improved air flow.

Why does the temperature reported on the status screen not match the temperature in Afterburner?

A modern GPU has more than one temperature sensor, and the two programs are not reading the same one.

hashcat asks the vendor's monitoring library for the edge temperature, which is the sensor on the outside of the die. Afterburner and similar tools often show the hotspot, also called junction, which is the hottest point inside the die. The hotspot always reads higher, and a gap of 15 to 25 degrees under load is normal rather than a fault.

Neither number is wrong. If you are setting --hwmon-temp-abort, set it against the figure hashcat itself reports, because that is the one it compares against.

How many GPU can hashcat handle?

There is a limit, and it is 256. hashcat keeps up to 256 backend device entries and refuses to start beyond that with Illegal use of the –backend-devices parameter because too many backend devices were found. The catch is that entries are not cards: a GPU reachable by two backends takes two entries, so a machine can hit 256 with rather fewer than 256 cards. The remedy is the one hashcat suggests, to select what you want with -d or to switch a backend off with --backend-ignore-opencl and friends.

The limits come from what is underneath it. CUDA and OpenCL impose no count that we know of, but drivers historically have, and AMD's were once capped at 8 devices. Dual-GPU cards, which is where that cap used to bite hardest, are no longer made.

On Linux a headless machine needs no X session for CUDA or ROCm, so the old warnings about X11 sitting in the middle no longer apply.

Generally it's a better idea to use multiple computers with only a few GPUs per system. For example, if you use a distributed solution (How can I distribute the work on different computers / nodes?) then there's really no limit to how many systems you attach to your cluster.

How do I choose which devices hashcat uses?

Start from hashcat -I, because the numbers you need are the Backend Device IDs it prints.

  • -d takes those IDs, comma separated: -d 1 or -d 1,3. This is the usual answer, and it is how you exclude the card that drives your display.
  • -D selects device types rather than individual devices: 1 CPU, 2 GPU, 3 FPGA/DSP/co-processor. A CPU device is not used unless you ask for it, so -D 1 or -D 1,2 is how you bring one in.
  • --backend-ignore-cuda, --backend-ignore-hip, --backend-ignore-metal and --backend-ignore-opencl switch a whole backend off. That is the clean way to deal with a card listed twice when you want the OpenCL entry rather than the CUDA or HIP one, or to cut the device count on a large rig.

Remember that the IDs come from the enumeration, so adding or removing a card, or switching a backend off, can renumber them. Check -I again after any hardware or driver change rather than reusing an old -d line.

I was doing bitcoin and litecoin mining, can I use my FPGA or ASIC for hashcat?

Not the mining hardware, no. But the answer for FPGAs has changed, because hashcat 7 ships the assimilation bridge, which lets a plugin put the expensive inner part of an algorithm on something other than a GPU while hashcat keeps doing the candidate generation, the rules and the hash comparison. That removes the old objection, which was that too much would have to move to the host. Writing such a bridge is real work, and there is no ready-made FPGA bridge in the release, but it is no longer architecturally out of reach. See docs/hashcat-assimilation-bridge.md in the release.

Mining FPGA bitstreams are still useless for it: they implement one algorithm with no candidate generation, which is the part that matters.

The problem with ASIC is that they are, by definition, application-specific. Bitcoin ASIC will only work for bitcoin, and nothing else. Well, you could attempt to use them for password cracking, but you would only be able to crack passwords that were exactly 80 bytes long and hashed as double SHA256. So, virtually worthless for anything but bitcoin.

By the same token, building ASIC specifically for password cracking would be a huge waste of time and money. And to make an ASIC that was flexible enough to handle multiple hashes, multiple algorithms, and multiple attack modes, you'd essentially just end up with a GPU. They really are the sweet spot. cheap, fast, flexible, easy to program.

Can I use Intel GPUs, they support OpenCL?

Yes. This answer used to say Intel GPUs did not work on Linux, and that has not been true for years.

Install the Intel Graphics Compute Runtime, known as NEO, and hashcat sees the GPU through OpenCL. hashcat enforces no minimum version for it, so it uses it on a best-effort basis: if it misbehaves, check the version yourself, because hashcat cannot judge it for you. Mesa's rusticl is a second option with real caveats, described under the driver question.

On speed, set expectations by the hardware rather than by the vendor. An integrated Intel GPU has very little raw compute, and a modern CPU with AVX2 may well beat it. A discrete Intel card is a different proposition and worth benchmarking. Either way, run hashcat -b and compare the number rather than guessing.

Note that the GPU runtime is a different package from the CPU one. For Intel CPUs you want the Intel CPU Runtime for OpenCL, or PoCL. See the driver question.

Why does hashcat show the wrong GPU memory when I start it?

hashcat reports what the runtime tells it, and the runtime reports three different things that are easy to confuse:

  Memory.Total...: 16304 MB (limited to 13858 MB allocatable in one block)
  Memory.Free....: 13160 MB

Total is the card's memory. Free is what is unallocated right now, which is less than total because your desktop, your browser and anything else on the card are already using some. The figure in brackets is the largest single allocation the runtime will grant, which is a runtime property and not a hashcat one.

That last number is the one that surprises people, because it can be far below total. OpenCL only guarantees a quarter of total memory in one block, and runtimes differ widely above that: on one machine here the same question is answered 25 percent, 42 percent, 85 percent, and a flat 4096 MB, depending on which runtime is asked. Not every device reports it at all, and where it is missing hashcat prints no bracket.

None of this is hashcat misreporting. If an allocation fails because of it, see the clCreateBuffer error.

Common errors

I created a hash with "echo test | md5sum" but hashcat fails to crack it

The error in here is that the echo command adds a newline character (\n). To avoid this you need to use the -n parameter.

$ echo test | md5sum  
d8e8fca2dc0f896fd7cb4cb0031ba249  -   
$ echo -n test | md5sum   
098f6bcd4621d373cade4e832627b4f6  - 

Line-length exception, wait what?

This error (and the similar “token length exception”) may have different reasons, which will all be mentioned shortly, but it means in general that the hash file (or it could be also the hash specified on command line in case of hashcat) could not be parsed successfully and therefore the hash could not be loaded.

In practice the message you see most is “Token length exception”, which means the same thing: the line did not parse. There are two shapes of it.

The file exists but a line in it did not parse, and hashcat names the line and shows it:

$ hashcat -m 0 md5_hashes.txt dict.txt
Hashfile 'md5_hashes.txt' on line 1 (010203invalidhash): Token length exception
* Token length exception: 1/1 hashes
No hashes loaded.

The file does not exist, so hashcat took the name as a hash and tried to parse that:

$ hashcat -m 0 non_existing_file.txt dict.txt
Hash 'non_existing_file.txt': Token length exception
* Token length exception: 1/1 hashes
No hashes loaded.

The second one is worth recognising, because the real problem is a wrong path, not a wrong hash. If hashcat quotes your filename back at you as though it were a hash, check the path first.

Now that we know the different type of error messages that will be shown, we will investigate also the most common reasons for these error messages:

  1. incorrect hash type: make sure that you always specify the correct hash type (--hash-type command line option or short -m)
  2. whitespace: spaces, tabs etc around the hash (in most cases at the end of a line within the hash file) won't be accepted and therefore must be removed.
    The reason why hashcat does not automatically remove the white spaces for the user (if it detects a line-length exception) is that (silently) removing parts of the characters in the hash line (hash or salt) is in most of the cases not what the user expects hashcat/hashcat legacy to do and in some cases (for instance salted hashes and the salt contains a space at the end) even something that could lead to problems and unexpected results.
  3. username: if the lines within the hash file are formatted as user:hash (and not hash alone), you need to specify the --username switch
  4. hash file was not found: if the path does not exist, hashcat falls back to treating the argument as a hash itself, which is the second example above. If you meant to pass a file, check the path.

If hashcat quoted your filename back at you as though it were a hash, the path is the problem, not the hash. If it quoted a line from the file, that line is the problem.

If you left -m off, the same failure reads differently, because autodetect reports it: No hash-mode matches the structure of the input hash. The causes are the same as the list above. See I left out -m and hashcat printed a list of hash modes and stopped.

To make sure that the hash follows the hash formats, visit this example hashes wiki page.

Do I need to remove duplicate hashes from my hashlist?

No. hashcat removes duplicates itself when it loads the list, so the same hash appearing twice costs you nothing and --remove behaves correctly.

This question exists because the retired hashcat-legacy did not deduplicate. It cracked only the first copy, so --remove could leave a hash in the file that had in fact been cracked. If you are following an old guide that tells you to deduplicate first, that is where the advice comes from and you can skip it.

Should you want to anyway, on a list large enough that the file size matters:

$ LC_ALL=C sort -u hashlist.txt > hashlist.new && mv hashlist.new hashlist.txt

hashcat says "kernel self-test failed" and aborts. What now?

Before it starts guessing, hashcat cracks a known hash on each device to check the device gives the right answer. If that fails it stops:

* Device #1: ATTENTION! HIP kernel self-test failed.
Aborting session due to kernel self-test failure.
You can use --self-test-disable to override, but do not report related errors.

The backend named changes with the device, so you may see CUDA, OpenCL or Metal instead.

This is not about your hash or your command. The test uses hashcat's own hash, so a failure means the device computed the wrong result. In practice that is the runtime or the driver, and the order to work through is:

  1. Clear the kernel cache, in case a stale compile is being reused. See Where does hashcat keep its compiled kernels?
  2. Check the compiler package matches the driver, see the driver question. A mismatched pair is the usual cause.
  3. If only one device of several fails, exclude it with -d and see whether the rest are fine. That tells you it is the device or its runtime rather than your install.
  4. If it fails on one mode only, say so when you report it, because that points at a plugin rather than the driver.

--self-test-disable makes it run anyway. That is useful for narrowing the problem down, but a device that fails the self-test can return wrong results, so do not trust cracks from it and do not report bugs found that way.

I am getting an "Incompatible self-test configuration detected" error.

As the message says: you must either disable the self-test functionality, or recompile the plugin with a matching self-test hash. To disable the self-test, use the –self-test-disable option.

Background: for the scrypt family hashcat compiles the kernel to match the hash's own N, r and p parameters, which buys a little speed. That is what ties a built kernel to one specific configuration. The modes concerned are -m 8900, 9300, 15700, 22700, 24000, 27700, 28200 and 29800, plus the bridged 70100 and 70200. Argon2 does not raise this error, despite also being parameterised.

This happens when the hash you are cracking has a different configuration from the plugin's built-in self-test hash. The self-test would fail against a kernel built for your parameters, so hashcat stops rather than proceeding on a kernel it cannot verify.

I am getting a "Mixed configuration detected" error.

The same mechanism, one step further along. The kernel is built for one set of scrypt parameters, so every hash in the session has to share them. If your list mixes, say, two different N values, hashcat refuses the run and shows you the two hashes that disagree:

ERROR: Mixed configuration detected.
The specified target hash:
  -> ...
does not match the configuration of another target hash:
  -> ...

There is no option that makes one kernel serve both. Split the list by parameters and run each group as its own session. The modes this applies to are the scrypt family listed above.

hashcat says "Already an instance ... running on pid". What now?

Already an instance '/path/to/hashcat.bin' running on pid 12345

hashcat writes a pid file named after the session, and the session is called hashcat unless you say otherwise. So starting a second attack while the first is running collides, because both want the same name.

Give each run its own name:

$ hashcat --session=job2 -m 0 -a 3 hash.txt ?d?d?d?d

If no hashcat is actually running, the pid file was left behind by one that was killed. Check with ps first, and only then delete the <session>.pid file from the session directory, which is beside the binary for the extracted release. Do not delete it while a run is live.

My error message is not here

A batch of driver error messages used to be answered on this page and are now in the archived FAQ. They belong to fglrx, Catalyst, ADL and ForceWare, none of which exist any more, so the answers were doing more harm than good. They are kept there because the messages are still findable in old forum threads.

If your error is not on either page, ask on the forum or open a GitHub issue, and include the output of hashcat -I along with the exact command you ran.

Compatibility

Why does hashcat not work with my Kali operating system?

It does work on Kali. Start with hashcat -I and read what came up, then work down this list.

  • Kali is in a virtual machine. This is by far the most common answer, because Kali is usually run as a guest. A desktop hypervisor gives the guest no GPU, so there is nothing for hashcat to use. See Can I use hashcat in a virtual machine?
  • No compiler package. The driver alone is not enough on NVIDIA or AMD. See the driver question.
  • The packaged hashcat is older than the release. Kali's package can lag. Compare against the download page and use the archive if it is behind.

The old answer here was about a glibc mismatch between Kali and the build host. That is long closed: the 7.1.2 Linux binary needs nothing newer than glibc 2.29, which is Debian 11 and Ubuntu 20.04 vintage, and Kali rolling is far newer than that.

Can I use hashcat in a virtual machine?

You can run it, but it will only see the devices the hypervisor hands the guest, and a desktop hypervisor hands it no GPU. So VirtualBox, VMware Workstation and Hyper-V normally give you either nothing usable or a CPU device only.

With no runtime reachable at all you get:

ATTENTION! No OpenCL, HIP or CUDA compatible platform found.
You are probably missing the OpenCL, CUDA or HIP runtime installation.

which reads like a missing driver, and inside a guest usually is not: there is no GPU there to have a driver for.

This is the most common reason a Kali user reports that hashcat does not work, because Kali is usually run as a guest.

What to do, in order of how well it works:

  • Run hashcat on the host. It needs no install, so extracting the archive on the host and running it there is the shortest path. Your wordlists and hashes are just files.
  • Give the guest a real GPU with PCI passthrough, which needs a hypervisor that supports it and a second GPU for the host. That is a hypervisor configuration job, not a hashcat one.
  • Accept CPU-only speed by installing a CPU OpenCL runtime in the guest, which is fine for learning and for slow hashes and hopeless for fast ones.

Can I use JtR rules with hashcat?

Individual functions, mostly yes: where the two share a letter it usually does the same thing, and the rule syntax documentation marks the differences.

A JtR rule file, usually no. Three things get in the way, and all three are ordinary in a real john.conf:

  • Section headers. [List.Rules:Wordlist] and the like are not rules, and hashcat has no concept of them.
  • Reject operators. <, >, _, ! and the rest do not work in a rule file at all. hashcat accepts them only with -j and -k. JtR rulesets use them constantly.
  • The preprocessor. See below, and it is the dangerous one.

Note also that the memory functions such as M go the other way round from what you might assume: hashcat-legacy implemented them and hashcat does not. The rule table marks those with a +.

A rule hashcat cannot parse is skipped with a warning naming the file and line. Note that it drops the whole rule line, not just the offending function, so a line that was mostly fine contributes nothing. The rest of the file still runs:

Skipping invalid or unsupported rule in file my.rule on line 12: ...

The one to watch for is JtR's preprocessor, because it does not fail, it misfires. In JtR, l[cu] expands to two rules, lc and lu. In hashcat [ and ] are its own truncate-left and truncate-right functions, so that line parses cleanly as five ordinary rules and quietly produces something else:

$ hashcat --stdout -r r.rule w.txt     # r.rule holds  l[cu]
ASSWOR

password became ASSWOR: lowercase, delete the first character, capitalise, uppercase, delete the last. No warning, exit 0, because nothing was invalid. hashcat cannot detect this for you.

So expand a preprocessor rule file before you use it, and check any rule containing [ or ] by eye. maskprocessor is the tool, and Using maskprocessor to generate rules is the how-to.

There is no such thing as a WPA wordlist. A wordlist is a wordlist, and nothing about it is specific to a hash type.

The thing people have in mind is the 8 character minimum. In a plain dictionary attack hashcat handles it for you: it knows each mode's limits and drops words that cannot fit as it reads them, counting them as rejected.

Once you add rules it stops working the way you would hope. With -r, hashcat judges the wordlist line against the minimum before the rules run, because the rules run on the GPU. So a 6 character word is discarded even if your rules would have appended two characters and made it valid. If you want short base words to survive into 8 character candidates, do the lengthening before hashcat sees them, by piping --stdout into the real run.

Two smaller cases worth knowing. In a combinator attack only the maximum is checked on each half, since the halves are still to be joined. And a mask shorter than the mode's minimum is refused rather than filtered, because every candidate it makes would be too short.

Organizational

I want to request some new algorithms or features, how can I accomplish this?

First, pick the right place. The project draws the line in its own issue templates: GitHub is for bugs and features, not for support. So:

  • a question about how to use hashcat, or a setup that will not work, goes to the forum
  • a reproducible defect, or a request for an algorithm or a feature, goes to GitHub issues

Opening an issue gives you a template for the kind you chose. Fill it in rather than replacing it, and search first, because the template asks you to.

Please make sure that the feature or problem was not already reported by using the search function.

A short reminder about the important information a github issue needs:

  • Problem/bug:
    • detailed description what exactly does not work, e.g. give a clear description of the problem
    • description when exactly the problem occurs (and when it doesn't)
    • full command (but reduced to the bare minimum - of parameters etc - needed)
    • example input (if needed also word lists / hash lists)
    • further details when you first saw this problem (e.g. which hashcat version was the first to have this bug)
    • tell us if it can be reliably reproduce or it is kind of random
    • if possible test with different operating systems / setups (or at least mention the details of your system)
  • New feature/algorithm:
    • name of the algorithm/feature
    • mention where the algorithm is currently being used (software, web app etc) or why the feature should be added
    • source code or source code link
    • mention any restrictions/limits or default lengths (maximum salt length, password length, …)
    • several full example hash/plain pairs in case of a hashing algorithm

How do I report a security vulnerability?

Not as a public issue. The project asks for these privately, so that a fix exists before the details are public.

Use the Security tab on the hashcat repository and choose Report a vulnerability. That opens a private draft advisory visible only to you and the maintainers. If you cannot use GitHub, email security@hashcat.net instead, bearing in mind that plain email is not encrypted.

Include enough for someone to reproduce it: the hashcat version or commit, the exact command line, the input that triggers it, what happens, and what you expected.

The full policy is in SECURITY.md in the repository.

Where can I download the source code?

hashcat is released under the MIT license, and the source is at github.com/hashcat/hashcat.

The retired CPU-only program is still archived at github.com/hashcat/hashcat-legacy, under the same licence. You do not want it for new work, see hashcat-legacy.

You can help improve hashcat and hashcat-utils with problem reports and feature requests through their GitHub issue trackers. The retired hashcat-legacy repository has issues switched off and takes no more reports.

Where can I get help, and which channel should I use?

Roughly in the order that gets you an answer fastest:

  1. Search this wiki and the forum first. Most questions have been asked, and the forum search is good.
  2. Ask on the forum for anything about using hashcat: a setup that will not work, an attack that is slower than you expect, which mode a hash is.
  3. Discord, at hashcat.net/discord, when you want to talk to a person rather than write a post.
  4. GitHub issues only for a reproducible defect or a feature request. The issue templates say it plainly: GitHub is for bugs and features, not for support.
  5. Privately, for anything you think is a security vulnerability. See How do I report a security vulnerability?

Whichever you pick, include the output of hashcat -I, your exact command line, and the hashcat version. Nearly every unanswered question is missing one of those three.

What is Team Hashcat?

Team Hashcat is a team of hand selected enthusiasts who devoted themselves to represent the name hashcat in cracking contests.

The team has competed in every major cracking competition for over fifteen years, including Korelogic's “Crack Me If You Can” at DEF CON, “Hash Runner” at Positive Hack Days, CracktheCon at Cyphercon and Jabbercracky. CMIYC is the most prestigious of them and the team has won it many times.

Everything the team publishes lives in one place: the team-hashcat repository on GitHub. That is where the running record of results is, along with the writeups and the tools and rule files built during each contest. This page used to carry copies of both tables and they drifted, so the repository is now the single source and this answer does not duplicate it.

Note: there was no CMIYC in 2016, and in 2017 it was held at DerbyCon rather than DEF CON.

Except where otherwise noted, content on this wiki is licensed under the following license: Public Domain