Skip to content
Security Notes

Hashcat: rule-based attacks and why complexity rules fail

By Elias Lankinen10 min read

I have solid research and four verified, relevant images. Writing the post now.

The password that obeys every rule and protects nothing

P@ssw0rd1 is a good password, if you ask a corporate login policy. It has an uppercase letter, a lowercase letter, a number, a special character, and it clears the eight-character minimum with room to spare. A user forced to invent it can feel virtuous. An IT auditor can tick the compliance box. And a graphics card running the open-source tool Hashcat will recover it from its stored hash in a fraction of a second, because that exact string is one of the first few hundred thousand things the software tries. That gap between what looks strong and what actually resists guessing is the whole subject here. Password-cracking stopped being a matter of grinding through every possible combination more than a decade ago. The modern approach starts from passwords real people actually chose, then mutates them with a compact set of instructions called rules. Those rules are tuned, almost surgically, to reproduce the very habits that composition requirements create. The uppercase-number-symbol policy meant to add strength is, in practice, a recipe the attacker already has.

Source: Wikimedia Commons
Source: Wikimedia Commons

First, what cracking a password even means

When you set a password on a well-built system, the server does not store the password itself. It stores a hash: the output of a one-way function that turns your text into a fixed-length string of gibberish. Feed the same input in and you always get the same hash out, but there is no arithmetic that runs the process backwards. When you log in, the server hashes what you typed and compares it to the stored value. So an attacker who steals a database of hashes cannot read the passwords. What they can do is guess. Take a candidate word, hash it with the same function, and check whether the result matches any hash in the stolen file. If it does, that password is recovered. Everything in password cracking is a strategy for choosing which candidates to hash, and in what order, because the number of possible strings is astronomically larger than anything you could ever test. The naive strategy, brute force, tries every combination in sequence: aaaaaaaa, aaaaaaab, and so on. It is guaranteed to work eventually and eventually can mean longer than the age of the universe. An eight-character password drawn from the roughly 95 typeable characters has about 95⁸, or 6.6 quadrillion, possibilities. The smarter strategy is to stop pretending passwords are random, because they are not.

The dictionary, and then the rules

The first improvement over brute force is the dictionary attack: instead of every combination, try a list of likely words. The canonical list is rockyou.txt, roughly 14 million unique passwords that ship pre-installed on the security-testing distribution Kali Linux. But a raw word list only ever tries words exactly as they appear. It contains password but not Password1, princess but not Pr1nc3ss!. Users, prodded by policies, add those decorations constantly. This is where rules enter. A rule-based attack applies small transformations to each dictionary word on the fly, generating variants in memory rather than storing them in an ever-larger file. The Hashcat documentation describes its rule engine as "a programming language designed for password candidate generation", and that is the right way to think about it. Each rule is a string of single-character function codes, applied left to right, that edit the word before it gets hashed. A handful of the functions give the flavour:

$X   append character X to the end        so password -> password1 with $1
^X   prepend character X to the front      so password -> 1password with ^1
c    capitalise the first letter           so password -> Password
u    uppercase the whole word              so password -> PASSWORD
r    reverse the word                      so password -> drowssap
sXY  replace every X with Y                so password -> passw0rd with so0

Functions chain on one line. The rule c so0 sa@ $1 reads: capitalise the first letter, swap every o for 0, swap every a for @, append 1. Feed it the dictionary word password and it emits P@ssw0rd1. That is not a coincidence. Someone studied how people mangle words to satisfy a policy and wrote the mangling down. Hashcat ships with pre-built rule files, the most famous being best64, a compact set of the empirically most productive transformations. Its rule syntax is deliberately compatible with the older cracker John the Ripper, so rule sets circulate freely between tools and communities. Point Hashcat at rockyou.txt with best64 applied and 14 million words become close to a billion candidates, each one a plausible thing a human might actually have typed.

Why this is so much faster than it sounds

The reason rules dominate is that generating and hashing candidates is now absurdly cheap. Modern cracking runs on graphics processing units, whose thousands of small cores hash enormous batches in parallel. Hashcat's own design goal, stated in its documentation, is to keep the GPU fed with "1,000,000,000 (or more) fresh password candidates in less than 10 ms", because a stalled GPU is a wasted GPU. The throughput depends heavily on the hash function, and this distinction matters enormously. Against a fast, general-purpose hash like MD5 or SHA-1, a single high-end consumer card such as an NVIDIA RTX 4090 tests on the order of tens to hundreds of billions of candidates per second. At those speeds a full pass through rockyou.txt finishes faster than you can blink, and running it with a large rule set attached still completes in seconds to minutes. A word list plus a rule file is not a slower option than a bigger word list; it is a faster one, because the transformations happen at hashing speed and the file never has to touch disk. There is an important caveat, and it is also the most common misconception about cracking: not every password falls in seconds. Purpose-built password hashes like bcrypt, scrypt, and Argon2 are deliberately slow and memory-hungry, dropping throughput from billions per second to thousands or even hundreds. A site that stores passwords in bcrypt with a high work factor makes rule-based cracking genuinely expensive. The catastrophic speeds you read about apply to systems that used a fast hash, no per-user salt, or, as in the incident that started this whole ecosystem, no hashing at all.

The passwords are real, and so are the rules

The rules are effective because they are reverse-engineered from reality, and the reality came from breaches. rockyou.txt is named after RockYou, a company that made widgets for MySpace and Facebook. In December 2009 an attacker used a SQL injection flaw to extract its user database, exposing more than 32 million passwords, all of them stored in plain text with no hashing whatsoever. The security firm Imperva analysed the haul and reported that the three most common passwords were 123456, 12345, and 123456789. That single dump became the training corpus for a generation of cracking tools. Every breach since has fed the same loop. Crackers run their rules against a new set of hashes, log which rules succeed and how often, and fold the winners back into better rule files. The 2019 project One Rule to Rule Them All, by the consultancy NotSoSecure, made the method explicit: the authors ran fourteen popular rule sets against a real breach of 4.3 million hashes, used Hashcat's debug mode to record which individual rules cracked passwords, kept the top-performing quarter of each set, and de-duplicated the result into a single file of 51,998 rules. The payoff was stark. Against that dataset, best64 generated about 1.1 billion candidates and cracked 32.4 percent of the hashes. The combined rule generated 746 billion candidates and cracked 68.4 percent, more than double the recovery rate. Rules are not a static trick. They are a feedback system that gets sharper every time a password database leaks, which is to say constantly.

Source: Wikimedia Commons
Source: Wikimedia Commons

Where complexity rules actively backfire

Now the crux. A composition rule, requiring an uppercase letter, a digit, and a symbol, is meant to enlarge the space of possible passwords. In theory it does. In practice it narrows the space of chosen passwords, because it prescribes behaviour that people satisfy in a small number of predictable ways. The evidence is old and consistent. In a 2010 paper presented at the ACM Conference on Computer and Communications Security, Matt Weir and colleagues attacked large sets of real leaked passwords and showed that the entropy metric NIST then used, borrowed from Shannon's information theory, was not a meaningful predictor of how hard a password was to guess. The number a policy optimised for and the number an attacker cared about were different numbers. The behavioural mechanism is the giveaway. Told to add a capital, most people capitalise the first letter. Told to add a digit, most append a 1, or a birth year, at the end. Told to add a symbol, most reach for !. Told to make it "complex," they turn a into @, o into 0, e into 3, a substitution scheme so universal it has a name, leetspeak, and a dedicated rule file in every cracker. Security researchers point out that these substitutions add no meaningful randomness precisely because the mapping is fixed and public; p@ssw0rd occupies the same tiny neighbourhood of guesses as password. The policy did not send users into the vast 95-character space. It funnelled them down a well-worn path, and the path is exactly what the rules encode. Carnegie Mellon researchers who have studied this for years reached the same place from the usability side. Their work found that complex composition policies can lower average password entropy and that a long password with no character-class requirements often provided more real strength than a short one loaded with mandated symbols. Length expands the search space multiplicatively and in ways an attacker cannot shortcut; a mandated symbol in a predictable position expands it by almost nothing.

What the standards actually say now

The official guidance has caught up with the research, and it is more decisive than most login screens suggest. The U.S. National Institute of Standards and Technology sets the reference for federal digital identity, and its Digital Identity Guidelines began the shift in 2017. The current revision of SP 800-63B is blunt: verifiers SHALL NOT impose composition rules such as requiring mixtures of character types, and SHALL NOT require users to change passwords periodically unless there is evidence of compromise. Instead, the document tells systems to require a minimum length, permit long passwords up to at least 64 characters, and screen every new password against a blocklist of known-common and previously-breached values. When NIST first dropped the complexity and forced-reset mandates, it was widely reported as a reversal, but it was really the standard conceding what attackers had demonstrated for years. The blocklist recommendation is the direct counter to everything above. If the defence checks new passwords against the same breach corpora that feed the crackers, then P@ssw0rd1 gets rejected at the moment of creation, no matter how many character classes it satisfies. You fight a data-driven attack with the same data.

The passphrase, and what to watch

The constructive half of the story is the one Randall Munroe drew in 2011. His xkcd comic 936 contrasted Tr0ub4dor&3, a short password tortured into compliance, with correct horse battery staple, four random common words. The comic's arithmetic put the passphrase at around 44 bits of entropy against the tortured password's 28, and made the point that the passphrase is both far harder to guess and far easier to remember. The reason maps onto everything a rule-based attack exploits: the mangled password lives inside a rule engine's reach, while four genuinely random words chosen from a large list live in a space that rules cannot shrink, because there is no human habit to encode.

Source: xkcd, by Randall Munroe
Source: xkcd, by Randall Munroe

The important qualifier is random. A passphrase you compose yourself from a memorable sentence is subject to its own habits, and crackers already run rules and grammars against common phrases. The strength comes from words drawn at random by a machine, which is exactly what a password manager does when it generates one for you. Which points at where this is going. The most credible answer to the whole rule-based arms race is to stop having a shared secret for the attacker to crack at all. Passkeys, built on public-key cryptography, leave nothing on the server that can be guessed offline; there is no hash to steal and mangle. As they spread across consumer platforms, the question worth watching is not whether complexity rules will finally disappear from corporate policies, though they should, but whether the password itself, and the entire economy of leaked lists and tuned rules built on top of it, is on a slow path to becoming a legacy technology. The rules will keep getting better right up until there is nothing left for them to guess.


Sources

  1. Hashcat. Rule-based attack (Hashcat wiki). Accessed 2026.
  2. National Institute of Standards and Technology. SP 800-63B, Digital Identity Guidelines: Authentication and Authenticator Management. Accessed 2026.
  3. Weir, Aggarwal, Collins, Stern. Testing Metrics for Password Creation Policies by Attacking Large Sets of Revealed Passwords (ACM CCS '10). 2010.
  4. NotSoSecure. One Rule to Rule Them All. 2019.
  5. SC Media. RockYou hack compromises 32 million passwords. 2009.
  6. Shay, Komanduri, et al. (Carnegie Mellon CyLab). Designing Password Policies for Strength and Usability (ACM TISSEC). 2016.
  7. Specops Software. Leetspeak Passwords: Predictable and Easily Crackable. Accessed 2026.
  8. Dark Reading. NIST Drops Password Complexity, Mandatory Reset Rules. 2024.
  9. Munroe, Randall. xkcd 936: Password Strength. 2011.