John the ripper explained: an essential password cracker for your hacker toolkit

How to set up John the Ripper

John the Ripper has a settings file with a lot of options. This file is called john.conf and is located in the same folder as the john executable.

Provide good cooling; watch the temperature. If the OpenCL runtime supports this, the GPU temperature will be monitored and displayed in the status bars, and there is a user-configurable limit in john.conf that will shutdown at 95 ° C.

This setting is set by the directive:

AbortTemperature = 95

The temperature is indicated in degrees Celsius — °C.

Instead of interrupting, you can stop the program for this number of seconds to cool down the GPU when the temperature reaches the AbortTemperature value, then the program will re-check the temperature and either continue or pause. Set to to just quit.

If SleepOnTemperature = 1 (one second) is specified, then no pause/resume messages will be displayed, since such a short value is interpreted as a desire to keep the temperature of the video card near the extreme value. Default directive value:

SleepOnTemperature = 1

How to crack GPG password

There are .key files in the ~/.gnupg/private-keys-v1.d/ folder, but if it is possible to extract keys and passwords from them, I don’t know.

The gpg password can be cracked from the private key file obtained from the export command:

gpg --export-secret-key -a "NAME SURNAME" > private.key

After export, from this private key file, you need to extract the hash to crack the password:

gpg2john private.key > gpg.hash

Brute force on a central processor

Now, to launch a dictionary attack using the CPU, run a command like:

john --wordlist=/PATH/TO/DICTIONARY --fork=CORES /PATH/TO/gpg.hash

To iterate over all passwords consisting only of numbers and length from 1 to 10 characters and perform calculations on the CPU, run a command like this:

john --fork=CORES --mask='?d' --min-length=1 --max-length=10 /PATH/TO/gpg.hash

To iterate over all passwords consisting of numbers, as well as uppercase and lowercase letters, from 1 to 8 characters long and perform calculations on the CPU, run a command like this:

john --fork=CORES -1=?l?u?d --mask='?1' --min-length=1 --max-length=8 /PATH/TO/gpg.hash

How to crack gpg passwords on a video card

To launch a dictionary attack using GPU, run a command like this:

john --format=gpg-opencl --wordlist=/PATH/TO/DICTIONARY /PATH/TO/gpg.hash

To iterate over all passwords consisting only of numbers and length from 1 to 10 characters and perform calculations on a video card, run a command of the form:

john --format=gpg-opencl -mask='?d' --min-length=1 --max-length=10 /PATH/TO/gpg.hash

To iterate over all passwords consisting of numbers, as well as uppercase and lowercase letters, 1 to 8 characters long and perform calculations on a video card, run a command like this:

john --format=gpg-opencl -1=?l?u?d --mask='?1' --min-length=1 --max-length=8 /PATH/TO/gpg.hash

«Incremental» mode.

This is the most powerful cracking mode, it can try all possible
character combinations as passwords. However, it is assumed that
cracking with this mode will never terminate because of the number of
combinations being too large (actually, it will terminate if you set a
low password length limit or make it use a small charset), and you’ll
have to interrupt it earlier.

That’s one reason why this mode deals with trigraph frequencies,
separately for each character position and for each password length,
to crack as many passwords as possible within a limited time.

To use the mode you need a specific definition for the mode’s
parameters, including password length limits and the charset to use.
These parameters are defined in the configuration file sections called
, where MODE is any name that you assign to the mode
(it’s the name that you will need to specify on John’s command line).
You can either use a pre-defined incremental mode definition or define a
custom one.

As of version 1.8.0, pre-defined incremental modes are «ASCII» (all 95
printable ASCII characters), «LM_ASCII» (for use on LM hashes), «Alnum»
(all 62 alphanumeric characters), «Alpha» (all 52 letters), «LowerNum»
(lowercase letters plus digits, for 36 total), «UpperNum» (uppercase
letters plus digits, for 36 total), «LowerSpace» (lowercase letters plus
space, for 27 total), «Lower» (lowercase letters), «Upper» (uppercase
letters), and «Digits» (digits only). The supplied .chr files include
data for lengths up to 13 for all of these modes except for «LM_ASCII»
(where password portions input to the LM hash halves are assumed to be
truncated at length 7) and «Digits» (where the supplied .chr file and
pre-defined incremental mode work for lengths up to 20). Some of the
many .chr files needed by these pre-defined incremental modes might not
be bundled with every version of John the Ripper, being available as a
separate download.

See CONFIG and EXAMPLES for information on defining custom modes.

How to use John The Ripper to Recover Passwords

Generally John expects to receive password hashes in the form user:hash in a plain text file. When run against a file in this format John The Ripper does a pretty good job at identifying the hash type and beginning to try and break it.

user@test:~/john/run/$./john mypasswordfile.txt

It is literally as simple as that, this uses the default password recovery mode as well as the default word list or dictionary.

Of course there are many more options available when running JTR, here is the command line help:

John the Ripper password cracker, version 1.8.0-jumbo-1_omp 
Copyright (c) 1996-2014 by Solar Designer and others
Homepage: http://www.openwall.com/john/

Usage: john  
--single        "single crack" mode
--wordlist --stdin wordlist mode, read words from FILE or stdin
                  --pipe  like --stdin, but bulk reads, and allows rules
--loopback         like --wordlist, but fetch words from a .pot file
--dupe-suppression        suppress all dupes in wordlist (and force preload)
--encoding=NAME           input encoding (eg. UTF-8, ISO-8859-1). See also
                          doc/ENCODING and --list=hidden-options.
--rules         enable word mangling rules for wordlist modes
--incremental      "incremental" mode 
--mask=MASK               mask mode using MASK
--markov        "Markov" mode (see doc/MARKOV)
--external=MODE           external mode or word filter
--stdout         just output candidate passwords 
--restore          restore an interrupted session 
--session=NAME            give a new session the NAME
--status           print status of a session 
--make-charset=utf-8       make a charset file. It will be overwritten
--show             show cracked passwords 
--test             run tests and benchmarks for TIME seconds each
--users=LOGIN|UID  load this (these) user(s) only
--groups=GID      load users  of this (these) group(s) only
--shells=SHELL    load users with this (these) shell(s) only
--salts=COUNT    load salts with COUNT  hashes
--save-memory=LEVEL       enable memory saving, at LEVEL 1..3
--node=MIN/TOTAL    this node's number range out of TOTAL count
--fork=N                  fork N processes
--pot=NAME                pot file to use
--list=WHAT               list capabilities, see --list=help or doc/OPTIONS
--format=NAME             force hash type NAME: 7z AFS agilekeychain aix-smd5
                          aix-ssha1 aix-ssha256 aix-ssha512 asa-md5 bcrypt
                          bfegg Bitcoin blackberry-es10 Blockchain bsdicrypt
                          chap Citrix_NS10 Clipperz cloudkeychain cq CRC32
                          crypt dahua descrypt Django django-scrypt dmd5 dmg
                          dominosec dragonfly3-32 dragonfly3-64 dragonfly4-32
                          dragonfly4-64 Drupal7 dummy dynamic_n eCryptfs EFS
                          eigrp EncFS EPI EPiServer fde FormSpring Fortigate
                          gost gpg HAVAL-128-4 HAVAL-256-3 hdaa HMAC-MD5
                          HMAC-SHA1 HMAC-SHA224 HMAC-SHA256 HMAC-SHA384
                          HMAC-SHA512 hMailServer hsrp IKE ipb2 KeePass
                          keychain keyring keystore known_hosts krb4 krb5
                          krb5-18 krb5pa-md5 krb5pa-sha1 kwallet LastPass LM
                          lotus5 lotus85 LUKS MD2 md4-gen md5crypt md5ns mdc2
                          MediaWiki MongoDB Mozilla mscash mscash2 MSCHAPv2
                          mschapv2-naive mssql mssql05 mssql12 mysql mysql-sha1
                          mysqlna net-md5 net-sha1 nethalflm netlm netlmv2
                          netntlm netntlm-naive netntlmv2 nk nsldap NT nt2
                          o5logon ODF Office oldoffice OpenBSD-SoftRAID
                          openssl-enc OpenVMS oracle oracle11 osc Panama
                          PBKDF2-HMAC-SHA1 PBKDF2-HMAC-SHA256
                          PBKDF2-HMAC-SHA512 PDF PFX phpass PHPS pix-md5 PKZIP
                          po postgres PST PuTTY pwsafe RACF RAdmin RAKP rar
                          RAR5 Raw-Blake2 Raw-Keccak Raw-Keccak-256 Raw-MD4
                          Raw-MD5 Raw-MD5u Raw-SHA Raw-SHA1 Raw-SHA1-Linkedin
                          Raw-SHA1-ng Raw-SHA224 Raw-SHA256 Raw-SHA256-ng
                          Raw-SHA384 Raw-SHA512 Raw-SHA512-ng ripemd-128
                          ripemd-160 rsvp Salted-SHA1 sapb sapg scrypt sha1-gen
                          sha1crypt sha256crypt sha512crypt Siemens-S7 SIP
                          skein-256 skein-512 skey Snefru-128 Snefru-256 SSH
                          SSH-ng SSHA512 STRIP SunMD5 sxc Sybase-PROP sybasease
                          tc_aes_xts tc_ripemd160 tc_sha512 tc_whirlpool
                          tcp-md5 Tiger tripcode VNC vtp wbb3 whirlpool
                          whirlpool0 whirlpool1 WoWSRP wpapsk xsha xsha512 ZIP

In this command line help, we can see there are a large number of hash types that JTR is able to have a go at cracking. This help is from the Jumbo Patch version of John the Ripper hence the large number of available hash types.

Configuration file.

Please refer to CONFIG for general information on the configuration file
and its possible locations.

1. Let’s assume that you notice that in some password file a lot of
users have their passwords set to login names with «?!» appended. Then
you just make a new «single crack» mode rule (see RULES for information
on the syntax) and place it somewhere near the beginning:

	
	Az"?!"

Hint: if you want to temporarily disable all of the default rules, you
can simply rename the section to something John doesn’t use and define
a new one with the section’s old name, but be sure to leave the «List.»
prefix of the name intact to maintain correct configuration file syntax.

All the same applies to wordlist mode rules as well.

2. If you generate a custom charset file (described above) you will also
need to define a configuration file section with the «incremental» mode
parameters. In the simplest case it will be like this (where «Custom»
can be replaced with any name you like):

	
	File = custom.chr

This way, John will only use characters from passwords used to generate
the charset file only. To make John try some more characters, add:

	Extra = !@#$%

These extra characters will then be added, but still considered the
least probable. If you want to make sure that, with your extra
characters, John will try 95 different characters, you can add:

	CharCount = 95

This will make John print a warning if it only has fewer than 95
characters in its charset.

You can also use CharCount to limit the number of different characters
that John tries, even if the charset file has more:

	CharCount = 20

If you didn’t use any filters when generating the charset file, setting
CharCount this low will make John never attempt rare characters and
character combinations, not even for really short passwords, spending
the time on simple longer candidate passwords instead. However, the
default length switching is usually smart enough so that you shouldn’t
need this trick.

To make John try passwords of certain lengths only, use the following
lines:

	MinLen = 6
	MaxLen = 8

Setting «MinLen» high, as in the example above, is reasonable if shorter
passwords weren’t allowed to set on the machine you got the password file
from (however, note that root can usually set any password for any user
and there are often loopholes in operating systems’ password policy
enforcement capabilities).

On the contrary, you may want to set «MaxLen» low if you think there are
a lot of short passwords.

3. Another example: a lot of users at some site use short duplicated
words as their passwords, such as «fredfred». As the number of such
potential passwords is fairly low, it makes sense to code a new external
cracking mode that tries them all, up to some length.

You can find the actual implementation of such a cracking mode with lots
of comments in the default configuration file supplied with John.
Please refer to EXTERNAL for information on the programming language
used.

$Owl: Owl/packages/john/john/doc/EXAMPLES,v 1.11 2019/05/19 15:10:04 solar Exp $

A note on moving binaries between systems.

With the «generic» make target, certain machine hardware performance
parameters are detected at compile time. Additionally, some OS-specific
make targets tell the C compiler to generate and optimize code for the
machine’s specific CPU type (this currently applies to C compilers other
than gcc only). If you then move the binary executable to a different
machine, you might not get the best performance or the program might
not run at all if the CPU lacks features that the C compiler assumed it
would have. Thus, it is recommended to recompile John on each system if
you use one of these make targets.

Since Linux and *BSD distributions’ packages of John typically use make
targets other than «generic» and since they typically use gcc, they are
usually not affected by this potential problem.

$Owl: Owl/packages/john/john/doc/INSTALL,v 1.5 2010/05/27 13:37:48 solar Exp $

How to crack KeePass and KeePassXC Password

To extract the hash, run a command like this:

keepass2john FILE > keepass.hash

The FILE must be a .kdbx password database.

Or if you have a key file, then run a command like this::

keepass2john -k <KEY FILE> <DATABASE .kdbx>

You can see the message:

! Passwords.kdbx : File version '40000' is currently not supported!

It means that the Passwords.kdbx FILE uses the KDBX version 4.0 database, and the keepass2john program only supports the KDBX version of KDBX 3.1. That is, it is currently not possible to crack a KeePass password with a KDBX version 4.0 database in John the Ripper.

Brute force on a central processor

Now, to launch a dictionary attack using the CPU, run a command like:

john --wordlist=/PATH/TO/DICTIONARY --fork=CORES /PATH/TO/keepass.hash

To iterate over all passwords consisting only of numbers and length from 1 to 10 characters and perform calculations on the CPU, run a command like this:

john --fork=CORES --mask='?d' --min-length=1 --max-length=10 /PATH/TO/keepass.hash

To iterate over all passwords consisting of numbers, as well as uppercase and lowercase letters, from 1 to 8 characters long and perform calculations on the CPU, run a command like this:

john --fork=CORES -1=?l?u?d --mask='?1' --min-length=1 --max-length=8 /PATH/TO/keepass.hash

How to Crack KeePass Passwords on GPU

To launch a dictionary attack using a video card, run a command like this:

john --format=KeePass-opencl --wordlist=/PATH/TO/DICTIONARY /PATH/TO/keepass.hash

To iterate over all passwords consisting only of numbers and length from 1 to 10 characters and perform calculations on a video card, run a command of the form:

john --format=KeePass-opencl -mask='?d' --min-length=1 --max-length=10 /PATH/TO/keepass.hash

To iterate over all passwords consisting of numbers, as well as uppercase and lowercase letters, 1 to 8 characters long and perform calculations on a video card, run a command like this:

john --format=KeePass-opencl -1=?l?u?d --mask='?1' --min-length=1 --max-length=8 /PATH/TO/keepass.hash

John the Ripper Hashcat Compatible Rules

The following features are 100% Hashcat compatible (excluding WN).

Name Function Description Example Rule Input Word Output Word
Nothing Do nothing (passthrough) p@ssW0rd p@ssW0rd
Lowercase l Lowercase all letters l p@ssW0rd p@ssw0rd
Uppercase u Uppercase all letters u p@ssW0rd P@SSW0RD
Capitalize c Capitalize the first letter and lower the rest c p@ssW0rd P@ssw0rd
Invert Capitalize C Lowercase first found character, uppercase the rest C p@ssW0rd p@SSW0RD
Toggle Case t Toggle the case of all characters in word. t p@ssW0rd P@SSw0RD
Toggle @ TN Toggle the case of characters at position N T3 p@ssW0rd p@sSW0rd
As SHIFT WN Toggle character at position N as SHIFT key does W1 p@ssW0rd p2ssW0rd
Reverse r Reverse the entire word r p@ssW0rd dr0Wss@p
Duplicate d Duplicate entire word d p@ssW0rd p@ssW0rdp@ssW0rd
Duplicate N pN Append duplicated word N times p2 p@ssW0rd p@ssW0rdp@ssW0rdp@ssW0rd
Reflect f Duplicate word reversed f p@ssW0rd p@ssW0rddr0Wss@p
Rotate Left { Rotate the word left. { p@ssW0rd @ssW0rdp
Rotate Right } Rotate the word right } p@ssW0rd dp@ssW0r
Append Character $X Append character X to end $1 p@ssW0rd p@ssW0rd1
Prepend Character ^X Prepend character X to front ^1 p@ssW0rd 1p@ssW0rd
Truncate left Delete first character p@ssW0rd @ssW0rd
Trucate right Delete last character p@ssW0rd p@assW0r
Delete @ N DN Delete character at position N D3 p@ssW0rd p@sW0rd
Extract range xNM Extract M characters, starting at position N x04 p@ssW0rd p@ss
Omit range ONM Delete M characters, starting at position N O12 p@ssW0rd psW0rd
Insert @ N iNX Insert character X at position N i4! p@ssW0rd p@ss!W0rd
Overwrite @ N oNX Overwrite character at position N with X o3$ p@ssW0rd p@s$W0rd
Truncate @ N ‘N Truncate word at position N ‘6 p@ssW0rd p@ssW0
Replace sXY Replace all instances of X with Y ss$ p@ssW0rd p@$$W0rd
Purge @X Purge all instances of X @s p@ssW0rd p@W0rd
Duplicate first N zN Duplicate first character N times z2 p@ssW0rd ppp@ssW0rd
Duplicate last N ZN Duplicate last character N times Z2 p@ssW0rd p@ssW0rddd
Duplicate all q Duplicate every character q p@ssW0rd pp@@ssssWW00rrdd
Extract memory XNMI Insert substring of length M starting from position N of word saved to memory at position I lMX428 p@ssW0rd p@ssw0rdw0
Append memory 4 Append the word saved to memory to current word uMl4 p@ssW0rd p@ssw0rdP@SSW0RD
Prepend memory 6 Prepend the word saved to memory to current word rMr6 p@ssW0rd dr0Wss@pp@ssW0rd
Memorize M Memorize current word lMuX084 p@ssW0rd P@SSp@ssw0rdW0RD

WN is a superset of TN. Whereas TN only switches the case of letters of the alphabet, for example. «A» «A», the WN command will also toggle with Shift. This is similar to using Shift (or disabling it) on a US keyboard, for example. «1» «!».

They all support encoding. For example, if the rules engine is running CP737, it will also correctly recognize Greek letters and upper/lowercase letters.

Configuration file.

Please refer to CONFIG for general information on the configuration file and its possible locations.

1. Let’s assume that you notice that in some password file a lot of users have their passwords set to login names with “?!” appended. Then you just make a new “single crack” mode rule (seeRULES for information on the syntax) and place it somewhere near the beginning:

	
	Az"?!"

Hint: if you want to temporarily disable all of the default rules, you can simply rename the section to something John doesn’t use and define a new one with the section’s old name, but be sure to leave the “List.” prefix of the name intact to maintain correct configuration file syntax.

All the same applies to wordlist mode rules as well.

2. If you generate a custom charset file (described above) you will also need to define a configuration file section with the “incremental” mode parameters. In the simplest case it will be like this (where “Custom” can be replaced with any name you like):

	
	File = custom.chr

This way, John will only use characters from passwords used to generate the charset file only. To make John try some more characters, add:

	Extra = !@#$%

These extra characters will then be added, but still considered the least probable. If you want to make sure that, with your extra characters, John will try 95 different characters, you can add:

	CharCount = 95

This will make John print a warning if it only has fewer than 95 characters in its charset.

You can also use CharCount to limit the number of different characters that John tries, even if the charset file has more:

	CharCount = 20

If you didn’t use any filters when generating the charset file, setting CharCount this low will make John never attempt rare characters and character combinations, not even for really short passwords, spending the time on simple longer candidate passwords instead. However, the default length switching is usually smart enough so that you shouldn’t need this trick.

To make John try passwords of certain lengths only, use the following lines:

	MinLen = 6
	MaxLen = 8

Setting “MinLen” high, as in the example above, is reasonable if shorter passwords weren’t allowed to set on the machine you got the password file from (however, note that root can usually set any password for any user and there are often loopholes in operating systems’ password policy enforcement capabilities).

On the contrary, you may want to set “MaxLen” low if you think there are a lot of short passwords.

3. Another example: a lot of users at some site use short duplicated words as their passwords, such as “fredfred”. As the number of such potential passwords is fairly low, it makes sense to code a new external cracking mode that tries them all, up to some length.

You can find the actual implementation of such a cracking mode with lots of comments in the default configuration file supplied with John. Please refer to EXTERNAL for information on the programming language used.

Cracking process with John the Ripper

At this point we just need a dictionary file and get on with cracking. John comes with it’s own small password file and it can be located in /usr/share/john/password.lst. I’ve showed the size of that file using the following command.

root@kali:~# ls -ltrah /usr/share/john/password.lst

You can use your own password lists too or download a large one from Internet (there’s lots of dictionary file in terabyte size).

root@kali:~# john --wordlist=/usr/share/john/password.lst /root/johns_passwd 
Created directory: /root/.john
Warning: detected hash type "sha512crypt", but the string is also recognized as "crypt"
Use the "--format=crypt" option to force loading these as that type instead
Using default input encoding: UTF-8
Loaded 2 password hashes with 2 different salts (sha512crypt, crypt(3) $6$ [SHA512 128/128 SSE2 2x])
Will run 2 OpenMP threads
Press 'q' or Ctrl-C to abort, almost any other key for status
password         (john)
1g 0:00:00:06 DONE (2015-11-06 13:30) 0.1610g/s 571.0p/s 735.9c/s 735.9C/s modem..sss
Use the "--show" option to display all of the cracked passwords reliably
Session completed
root@kali:~#

Looks like it worked. So we can now use john –show  option to list cracked passwords. Note that it’s a simple password that existed in the dictionary so it worked. If it wasn’t a simple password, then you would need a much bigger dictionary and lot longer to to crack it.

root@kali:~# john --show /root/johns_passwd 
john:password:1000:1001::/home/john:/bin/bash

1 password hash cracked, 1 left
root@kali:~#

How to crack ZIP archive password

To extract the hash, run a command like this:

zip2john FILE > zip.hash

For example, the path to the file /mnt/disk_d/Share/test/file.zip, then the command is as follows:

zip2john /mnt/disk_d/Share/test/file.zip > zip.hash

Brute force on a central processor

Now, to launch a dictionary attack using the CPU, run a command like this:

john --wordlist=/PATH/TO/DICTIONARY --fork=CORES /PATH/TO/zip.hash

For example, my dictionary is located in the same folder as the executable file john and has the name rockyou.txt, and on my computer there are 12 cores, and zip.hash is in the user’s home folder, then the command is as follows:

./john --wordlist=rockyou.txt --fork=12 ~/zip.hash

To iterate over all passwords consisting only of numbers and length from 1 to 10 characters and perform calculations on the CPU, run a command like this:

john --fork=CORES --mask='?d' --min-length=1 --max-length=10 /PATH/TO/zip.hash

To iterate over all passwords consisting of numbers, as well as uppercase and lowercase letters, from 1 to 8 characters long and perform calculations on the CPU, run a command like this:

john --fork=CORES -1=?l?u?d --mask='?1' --min-length=1 --max-length=8 /PATH/TO/zip.hash

How to crack passwords of ZIP archives on a video card

John the Ripper supports two algorithms for cracking ZIP archives on the CPU:

  • PKZIP
  • ZIP

And only one archive for cracking on video cards:

ZIP-opencl

In the previous commands, we did not specify the hash type, since it is uniquely indicated in the hash itself. To use a video card, you must use the —format=HASH option. But it will only work for ZIP format. Therefore, you need to open the file where the hash is saved and look at the beginning of the hash.

If you see something like this there:

file2.zip/file.docx:$zip2$*0*3*0*3eca0462af8ea24……………….

This means that this hash can be cracked with commands like:

john --format=ZIP-opencl --wordlist=/PATH/TO/DICTIONARY /PATH/TO/zip.hash
john --format=ZIP-opencl -mask='?d' --min-length=1 --max-length=10 /PATH/TO/zip.hash
john --format=ZIP-opencl -1=?l?u?d --mask='?1' --min-length=1 --max-length=8 /PATH/TO/zip.hash

If there is a hash with the “pkzip” string:

file.zip/Отчёт.docx:$pkzip2$1*1*2*0*b274*c3db*7c823487*0*28*8*b……………….

This means that cracking of this format on the video card is currently not supported.

Sources

Johnny is hosted at Github: https://github.com/openwall/johnny

For building from source instructions, see INSTALL.

Getting started is as easy as:

Official version 2.2 source:

Via direct-download: https://github.com/openwall/johnny/archive/v2.2.zip

Via git:

  1) git clone https://github.com/openwall/johnny.git && cd johnny
  2) git checkout v2.2
  

Development source (might not be stable — not recommended):

Via direct-download:https://github.com/openwall/johnny/archive/master.zip

Via git:

  1) git clone https://github.com/openwall/johnny.git && cd johnny
  

$more README # For getting your feet wet

Numeric constants and variables.

Numeric constants may be specified and variables referred to with the
following characters:

0...9	for 0...9
A...Z	for 10...35
*	for max_length
-	for (max_length - 1)
+	for (max_length + 1)
a...k	user-defined numeric variables (with the "v" command)
l	initial or updated word's length (updated whenever "v" is used)
m	initial or memorized word's last character position
p	position of the character last found with the "/" or "%" commands
z	"infinite" position or length (beyond end of word)

Here max_length is the maximum plaintext length supported for the
current hash type.

These may be used to specify character positions, substring lengths, and
other numeric parameters to rule commands as appropriate for a given
command. Character positions are numbered starting with 0. Thus, for
example, the initial value of «m» (last character position) is one less
than that of «l» (length).