The PCFG attack (-a 4) guesses passwords in order of how likely they are. PCFG stands for Probabilistic Context-Free Grammar, which is a long name for a fairly simple idea.
Real passwords have shapes people keep reusing. monkey12, nicole2010, soccer! and Daniel99 are all the same idea with different parts filled in. A PCFG splits a password into two questions:
monkey12 is a six letter word followed by two digits.monkey and the digits are 12.
A trained ruleset answers both questions with probabilities. It has learned that “six letters then two digits” is a common shape, that monkey is a common six letter word, and that 12 is a common pair of digits. Multiply the three numbers together and you have the probability of monkey12.
A wordlist does not tell hashcat which line is worth trying first. It just hands over lines in whatever order they happen to sit in the file. A PCFG does know, so the good guesses come out at the front.
You can see it straight away. This is the real start of a default -a 4 run:
$ hashcat -a 4 --stdout 123456 1234567 123123 12345 123456789 123321 password 12345678 5201314 7777777 1234 1234567890 112233 159753 111111 654321 000000 123654 666666 qwerty
Nobody sorted that list by hand. The grammar worked it out.
hashcat ships a ruleset trained on passwords and uses it when you name none, so the short form is all you need to get going:
$ hashcat -m 0 -a 4 example0.hash
To use a ruleset of your own, name it after the hash file:
$ hashcat -m 0 -a 4 example0.hash /path/to/ruleset
Rules work too, and apply to the candidates the grammar produces:
$ hashcat -m 0 -a 4 example0.hash -r rules/best66.rule
A ruleset is just a directory of plain text files. Each line is a value, a tab, and a probability.
$ ls ruleset Alpha Capitalization Context Digits Grammar Keyboard Omen Other Years
Grammar/grammar.txt holds the shapes, most likely first:
M 0.40004227816694393 D6 0.051105353916786035 A6D2 0.037839499289255306 A6 0.037156138225371546 A7 0.025911933402529241
D6 means six digits. A6 means six letters. A6D2 means six letters then two digits, which is the shape of monkey12. The letter says which directory the parts come from, and the number is both a length and a file name, so A6 means Alpha/6.txt:
| letter | directory | what it holds |
|---|---|---|
A | Alpha | words, always stored lowercase |
C | Capitalization | which letters of the word before it are uppercase |
D | Digits | runs of digits |
O | Other | runs of symbols |
K | Keyboard | keyboard walks like qwerty or 1qaz2wsx |
X | Context | things that do not fit the others |
Y | Years | four digit years |
Case is handled off to the side. Words in Alpha are always lowercase, and every A token carries a matching C token that says which letters to upper-case afterwards. LLLLLL leaves the word alone, ULLLLL capitalises the first letter. That is why monkey and Monkey are one entry and not two.
Token M is the other half of the model, a Markov chain rather than a grammar shape.
Name several rulesets and hashcat merges them, splitting the run evenly between them by default:
$ hashcat -m 0 -a 4 example0.hash default-passwords my-russian
An even split will not always suit your target. weights= changes the share each one gets:
$ hashcat -m 0 -a 4 example0.hash default-passwords my-russian weights=2:1
Merging is worth doing because two rulesets trained on different material can reach candidates that neither reaches alone. It also costs you if you get the weights wrong, because half the run goes on candidates that were never likely.
hashcat does not train rulesets. That is a separate job, done with pcfg_cracker, and hashcat reads its ruleset format directly.
hashcat also does not ship a ruleset trained on ordinary language, because the text you would train it on carries a licence of its own. If you want one, train it yourself from material you are allowed to use.
The full reference is docs/hashcat-pcfg.md in the hashcat source. It covers the settings, how hashcat's version differs from the original PCFG tool, and what merging does in detail.