Table of Contents

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


Table Attack

Description

The table attack takes each word from your dictionary, looks at every character in turn, and tries every replacement you listed for that character. It is the attack to reach for when you want leetspeak, or mixed upper and lower case, or both at once.

The Table attack is not to be confused with rainbow tables.

Note: this attack was -a 5 in hashcat-legacy. It was dropped in hashcat 3.00 because it was thought to be a bad fit for a GPU. It is back in hashcat as -a 5 and it does run on the GPU now. The table file format changed at the same time, so an old table has to be converted. See What changed since hashcat-legacy at the bottom.

How a table works

A table is a plain text file. Each line is a character, one tab, and what that character may become:

s	$
s	5

Take the word password. It has two s characters, and each one may stay s, become $, or become 5. Each position decides for itself, so you get all 3 x 3 = 9 spellings:

$ hashcat -a 5 --stdout words.txt s.table
password
pas$word
pas5word
pa$sword
pa$$word
pa$5word
pa5sword
pa5$word
pa55word

That independence is the whole point of the attack. A rule cannot do it. The rule ss$ changes every s at once and gives you pa$$word. The rule ss5 gives you pa55word. No rule gives you pa$5word, because a rule has no way to say “this s and not that one”.

Running it

The wordlist comes first, then one or more tables:

$ hashcat -m 0 -a 5 hashes.txt rockyou.txt tables/leetspeak-common.table tables/toggle.table

Every argument after the wordlist is a table, and hashcat merges them all into one attack. The line above is leetspeak and case in a single run, not two runs.

Tables that ship with hashcat

Look in the tables/ folder:

table what it does
tables/leetspeak-common.table the substitutions people actually make, start here
tables/leetspeak-extended.table seen regularly, well behind the common set
tables/toggle.table case, both directions, Latin, Greek and Cyrillic
tables/emoji.table whole words as emoji
tables/sports.table one sport swapped for another, use with identity=0 template=1
tables/layouts/de.table and friends that keyboard layout to US, one file per layout, use with identity=0
tables/layouts/de-reverse.table and friends US to that keyboard layout, use with identity=0

Settings

Settings are written on the command line as name=value, in among the tables:

setting default what it does
identity 1 whether “leave this character alone” is one of the choices. identity=0 makes the table convert instead of offering variants
template 0 template=1 never hands back a word unchanged, which reads your wordlist as a set of patterns
single 0 single=1 puts one substitution in a candidate instead of every combination
maxperm 1048576 how many candidates one word may produce on the host, 0 for no limit
cap 0 how many replacements one character may have, 0 for no limit

Why maxperm exists

A long word can produce an absurd number of candidates. With the common leetspeak and toggle tables together, the words in rockyou that are 16 bytes or shorter already come to over 2 trillion candidates, and the single widest word on its own needs more than a 64-bit counter can hold. Without a limit, a run can spend effectively all of its time on the first few long words. maxperm is what stops that.

Changing maxperm changes the order candidates come out in, so a --restore point taken before the change will not be valid after it.

Typed on the wrong keyboard layout

Somebody types their Russian password while the US layout is active, so what actually reaches the login box is the US characters sitting on those keys. A Russian wordlist cannot match that until it is converted. The layout tables do the conversion, and identity=0 is what makes it a conversion rather than a pile of half-converted variants:

$ cat words.txt
пароль
$ hashcat -a 5 --stdout words.txt tables/layouts/ru.table identity=0
gfhjkm

The reverse table goes the other way, from what was typed back to what was meant:

$ hashcat -a 5 --stdout typed.txt tables/layouts/ru-reverse.table identity=0
пароль

Leave identity at its default and you get 2^6 candidates for a six letter word instead of one, with gfhjkm among them. That is the right attack for a password where the layout got switched partway through, and the wrong one when the whole word was typed on the wrong layout.

This is also what --keyboard-layout-mapping was added for. That option only works for 30 TrueCrypt and VeraCrypt modes. The same files used as a table work for every hash mode.

Ideas for your own tables

Leetspeak. These are the first lines of the shipped tables/leetspeak-common.table, so you can see the shape of a real one:

a	4
a	@
e	3
g	9
i	1
i	!
l	1
o	0
s	$
s	5
t	7

Case, which fully replaces the old Toggle-case attack. The shipped tables/toggle.table does this in both directions for 618 characters, covering Latin, Greek and Cyrillic:

A	a
B	b
C	c
D	d

Filling holes in a dictionary. If your dictionary has pass0 through pass3 and pass5, it is missing pass4, pass6 and the rest. One character's worth of table lines fills them all in:

0	1
0	2
0	3
0	4
0	5
0	6
0	7
0	8
0	9

Hint: to avoid duplicates, replace all digits with 0 first and then unique what is left.

$ sed -e 's/[0123456789]/0/g' < passes.dict | sort -u > passes_table_optimized.dict

The wordlist as a set of patterns

People build passwords around something they care about, and the thing in the middle changes while the pattern around it does not. rockyou holds football1, ilovefootball, football! and Football2010. Somebody who follows a different sport may well use those same patterns with a different word in the middle. A table that maps each sport to every other sport reaches all of them:

$ hashcat -m 0 -a 5 hashes.txt rockyou.txt tables/sports.table identity=0 template=1

What changed since hashcat-legacy

If you are following an old guide, these are the differences:

See also