Maximum Password Length Reached!

A recent article by @mubix resurfaced the largely unknown fact that because password candidates (plain/mangled dictionary words and generated plain texts) are stored in GPU registers, there aren’t actually enough registers to store password candidates over certain lengths. As a result, our password cracking tools have been limited to these lengths (differing per algorithm). This limit could be exceeded, however doing so would double the amount of processing time required, so the trade-off for the speeds we’ve come to expect with our hardware are in fact stopping us from breaking a password of X length, even if it’s in our dictionary.

In this post, NotSoSecure’s Will Hunt will cover some examples in hashcat and John The Ripper. We’ll cover a couple of algorithms below, followed by a more complete breakdown of algorithm limits at the end of this post, as well as options to increase these limits (to a limit!).

Hashcat

Back in 2013, oclHashcat-plus v0.15 was released and one of the major updates was support for increased password lengths. The limit rose from a maximum of 15 characters to 55 (with some exceptions). These exceptions are shown in the table below, figures from which have been taken from hashcat’s FAQ.

 

Inherent Limitations from Hash Itself
Algorithm Hashcat Mode Max. Length
CRC32 1500 8
LM 3000 7
MS Office <= 2003 $0/$1, MD5 + RC4, collider #1 9710 5
MS Office <= 2003 $3/$4, SHA1 + RC4, collider #1 9810 5
PDF 1.1 - 1.3 (Acrobat 2 - 4), collider #1 10410 5
Slow Hashes
phpass, phpBB3 (MD5), Joomla >= 2.5.18 (MD5), WordPress (MD5) 400 40
Cisco-IOS $1$ (MD5) 500 16
Apache $apr1$ MD5, md5apr1, MD5 (APR) 1600 16
sha512crypt $6$, SHA512 (Unix) 1800 16
Domain Cached Credentials 2 (DCC2), MS Cache 2 2100 16
Password Safe v3 5200 24
IKE-PSK MD5 5300 16
Samsung Android Password/PIN 5800 16
AIX {smd5} 6300 16
sha256crypt $5$, SHA256 (Unix) 7400 16
Drupal7 7900 48
RACF 8500 8
Lotus Notes/Domino 5 8600 16
SAP CODVN H (PWDSALTEDHASH) iSSHA-1 10300 40
PDF 1.4 - 1.6 (Acrobat 5 - 8) 10500 40
PDF 1.7 Level 8 (Acrobat 10 - 11) 10700 16
Bitcoin/Litecoin wallet.dat 11300 40

There are also attack-mode factors that affect password lengths in hashcat. Information on this is also in the FAQ but is out of scope for this post. Windows passwords are another exception and that’s what we’ll look at first.

As almost all Windows hashing is based on UTF-16LE which uses 16 bits (2 bytes) per character, each character of a password candidate is twice the length, halving the limit from 55 to 27 (clearly 27.5 isn’t a password length!). This will apply to any UTF-16 based hash. Let’s start with a hashcat test using a dictionary containing just our password.


Great. Now let’s add a character to our password and replace it in the dictionary…

Password: NowThePwIsTwentyEightLetters


Oh dear.  Now whilst 27 character passwords aren’t exactly common in the wild, they’re not out of the realm of possibility, especially as people start using memorable phrases. Another algorithm we’re likely to see is SHA512crypt which are the $6$ hashes found in /etc/shadow files and is also one of the exceptions noted earlier. These are limited to only 16 characters (!) which is a reasonably plausible length to expect these days, albeit maybe not very often.


Let’s make it 17 characters and see if we still have a winner.

Password: Weak SHA512crypt!


17 doesn’t cut it! *Runs to Ubuntu box and makes password 17 characters*

Now let’s explore some examples using John.

John the Ripper

By using the --list=format-all-details and --list=format-details switches, John dumps out various algorithm format info including details about length (screenshots are truncated).


Even though John shows us a max limit of 81, the actual max length of accepted NT passwords is the same as hashcat’s…27. This is because getting 27 Unicode characters may need up to 81 bytes of UTF-8 (up to 3 bytes per character). John does actually state bytes and not characters, look above if you don’t believe me ;-)

You can get john to reveal the 27 limit by adding an –enc:raw to the command, however the latest version of jumbo has reworked the output to help us, shown below.


Nice. By default we’re now shown our max limits and notice now John states max length, not bytes. In MD5’s case we’ve also got some helpful info about worst case scenarios where a password contains characters that all use 3 bytes of UTF-8, heavily bringing down the MD5 limit from 55 to 18. Typically we wouldn’t see worst case scenarios during tests, unless maybe you were testing foreign language passwords. For example, most Chinese, Korean and Japanese characters use 3 bytes of UTF-8.

Ok, let’s give john a crack at an MD5 hash (pun fully intended) of a 55 character password. Below we can see our wordlist containing our password, the character length of our password, it’s hash and the results.


Bingo. Let’s up the length by one.


John can’t break it. Lastly, let’s have a look at a higher limit SHA-384 hash. John shows this supports a maximum of 111 characters.


The below two screenshots show the tests, the first with a 111 character password, the second with a 112 characters.


So 111 cracks but 112 doesn’t. Clearly we’re defining very high upper limits here that you’re really not likely to see often in the wild, but it’s still important we understand the limitations of our tools.

NIST have also recently published new guidelines regarding passwords including the allowance for at least 64 characters. This is to provide greater flexibility for creating memorable passphrases instead of passwords.

You mentioned something earlier about possibly increasing these limits?

We did indeed and we found this via the originally referenced article so we won’t re-link everything here. John can be custom compiled to get a few more characters, however the performance hit you’ll take on cracking speed will be significant. You need to ask yourselves are you likely going to be encountering passwords above the corresponding limits and then make a decision based on time and resources. The article also notes a branch of hashcat that supports higher limits but it doesn’t currently support NTLM.

That’s cool! I could really use a cheat sheet for the max lengths on all algorithms…

It’s funny you should say that, we thought the same thing! We therefore created the below cheat sheet based from John’s output, covering both worst case UTF-8 scenarios as well as max lengths. If you ever stumble upon some of the lesser known/encountered hashes and want to know the construction format, the --list=format-all-details --format=<insert alg> info provides an example hash at the bottom. Also, please note that limits in John may differ from limits in hashcat.

Happy cracking everyone!

 

Worst Case Max Length Algorithm(s)
2 8 tripcode, net-ah, PST, RACF
3 10 as400-des
4 12 dynamic_20, asa-md5
5 15 md5crypt, md5crypt-opencl, phpass-opencl
5 16 dynamic_19, dynamic_39, WoWSRP, Clipperz, lotus5, net-md5, pix-md5, lotus5-opencl, BitLocker-opencl
6 20 dynamic_40, net-sha1, Raw-SHA512-free-opencl, XSHA512-free-opencl
7 LM, nethalflm, LM-opencl
7 23 dynamic_1, dynamic_8, dynamic_1011, dynamic_1012, dynamic_1013, dynamic_1034, dynamic_1401, dynamic_1506, dynamic_1550, dynamic_1551, saph, sha512crypt-opencl
8 descrypt, sapb, VNC, descrypt-opencl
8 24 sha256crypt-opencl
9 28 agilekeychain-opencl, enpass-opencl, iwork-opencl
10 30 oracle11
10 31 dynamic_4, dynamic_5, dynamic_31, dynamic_32, dynamic_1015, BKS, CRC32, ipb2, osc, PKZIP, Raw-SHA1-ng
10 32 dynamic_10, dynamic_11, chap, cq, dmd5, Fortigate, hdaa, IKE, krb4, krb5, lotus85, MongoDB, mysqlna, mysql-sha1,  mysql, nk, o10logon, o3logon, o5logon, PDF, postgres, PuTTY, RAR5, SIP, skey, SSH-ng, OpenVMS, wbb3, keystore-opencl, o5logon-opencl
11 35 sha256crypt
13 39 dynamic_1008, dynamic_1009, phpass, Salted-SHA1, salted-sha1-opencl
13 40 dynamic_2009
14 netlm
15 46 dynamic_1588, Citrix_NS10
15 47 Drupal7, keyring-opencl
16 48 BestCrypt, pfx, qnx
17 51 xsha
17 53 dynamic_1350
18 55 dynamic_0, dynamic_2, dynamic_3, dynamic_6, dynamic_9, dynamic_14, dynamic_22, dynamic_23, dynamic_30, dynamic_34, dynamic_1001, dynamic_1002, dynamic_1004, dynamic_1005, dynamic_1006, dynamic_1007, dynamic_1017, dynamic_1018, dynamic_1019, dynamic_1020, dynamic_1021, dynamic_1022, dynamic_1024, dynamic_1025, dynamic_1300, dynamic=md5($p), hsrp, MediaWiki, PHPS, PHPS2, Raw-MD4, Raw-MD5, Raw-SHA1, Raw-SHA1-AxCrypt, Raw-SHA1-Linkedin, Raw-SHA224, Raw-SHA256, Raw-SHA256-ng, Lastpass, vtp, RAR5-opencl, FVDE-opencl, mysql-sha1-opencl, PBKDF2-HMAC-SHA256-opencl, Raw-MD4-opencl, Raw-MD5-opencl, Raw-SHA1-opencl, Raw-SHA256-opencl, Raw-SHA512-opencl, XSHA512-opencl
19 EPiServer, oldoffice-opencl
21 63 AFS, Stribog-256, Stribog-512, ODF-AES-opencl, RAKP-opencl
21 64 dynamic_1560, dominosec, dominosec8, fde, krb5-18, po, Sybase-PROP, tc_aes_xts, tc_ripemd160, tc_sha512, tc_whirlpool, sha1crypt-opencl, PBKDF2-HMAC-MD4-opencl, PBKDF2-HMAC-MD5-opencl, PBKDF2-HMAC-SHA1-opencl, truecrypt-opencl, blockchain-opencl, dmg-opencl, encfs-opencl, keychain-opencl, krb5pa-sha1-opencl, ODF-opencl, strip-opencl, sxc-opencl, zip-opencl
22 rar-opencl
23 7z-opencl
23 70 dynamic_1592
24 72 bcrypt, bfegg, bcrypt-opencl, crypt
25 mssql, mssql05
26 rar
26 79 sha512crypt, leet
26 80 tcp-md5
27 dynamic_29, dynamic_33, mscash, MSCHAPv2, netntlm, NT, Raw-MD5u, krb5pa-md5-opencl, mscash-opencl, nt-opencl, ntlmv2-opencl, NT-old
27 81 eigrp
28 7Z
29 87 pwsafe-opencl
31 95 SSHA512, dummy
32 dynamic_1600
33 99 dynamic_1010, RAdmin
33 100 argon2
35 107 xsha512
36 110 dynamic_12, dynamic_13, dynamic_15, dynamic_16, dynamic_18, dynamic_24, dynamic_25, dynamic_26, dynamic_35, dynamic_36, dynamic_37, dynamic_38, dynamic_50, dynamic_60, dynamic_61, dynamic_70, dynamic_80, dynamic_90, dynamic_100, dynamic_110, dynamic_120, dynamic_130, dynamic_140, dynamic_150, dynamic_160, dynamic_170, dynamic_180, dynamic_190, dynamic_200, dynamic_210, dynamic_220, dynamic_230, dynamic_240, dynamic_250, dynamic_260, dynamic_270, dynamic_280, dynamic_290, dynamic_300, dynamic_310, dynamic_320, dynamic_330, dynamic_340, dynamic_350, dynamic_360, dynamic_370, dynamic_380, dynamic_390, dynamic_400, dynamic_410, dynamic_420, dynamic_1003, dynamic_1014, dynamic_1016, dynamic_1023, dynamic_1026, dynamic_1027, dynamic_1028, dynamic_1029, dynamic_1030, dynamic_1031, dynamic_1501, dynamic_1502, dynamic_1503, dynamic_1504, dynamic_1505, dynamic_1552, dynamic_2000, dynamic_2001, dynamic_2002, dynamic_2003, dynamic_2004, dynamic_2005, dynamic_2006, dynamic_2008, dynamic_2010, dynamic_2011, dynamic_2014, FormSpring, hMailServer, md5ns, PBKDF2-HMAC-SHA512-opencl
37 111 cloudkeychain, Raw-SHA512, Raw-SHA384, Raw-SHA512-ng
40 sapg
40 120 oracle, SunMD5
41 47 office-opencl
41 53 mssql12
41 55 dynamic_1400
41 64 oldoffice, SybaseASE
41 90 dynamic_1590
41 110 dynamic_1032, dynamic_1507
41 125 scrypt, agilekeychain, aix-ssha1, aix-ssha256, aix-ssha512, as400-ssha1, axcrypt, AzureAD, Bitcoin, BitLocker, Blackberry-ES10, Blockchain, sha1crypt, dahua, Django, django-scrypt, dmg, DPAPImk, dragonfly3-32, dragonfly3-64, dragonfly4-32, dragonfly4-64, eCryptfs, electrum, EncFS, enpass, EPI, ethereum, FVDE, geli, gost, gpg, HAVAL-128-4, HAVAL-256-3, HMAC-MD5, HMAC-SHA1, HMAC-SHA224, HMAC-SHA256, HMAC-SHA384, HMAC-SHA512, itunes-backup, iwork, KeePass, keychain, keyring, keystore, known_hosts, krb5pa-sha1, krb5tgs, kwallet, lp, LUKS, MD2, mdc2, scram, Mozilla, mscash2, mschapv2-naive, krb5pa-md5, multibit, netlmv2, netntlmv2, netntlm-naive, nsec3, ODF, Office, OpenBSD-SoftRAID, openssl-enc, Oracle12C, Padlock, Palshop, Panama, PBKDF2-HMAC-MD4, PBKDF2-HMAC-MD5, PBKDF2-HMAC-SHA1, PBKDF2-HMAC-SHA256, PBKDF2-HMAC-SHA512, PEM, pomelo, pwsafe, RAKP, Raw-Blake2, Raw-Keccak, Raw-Keccak-256, Raw-SHA3, ripemd-128, ripemd-160, rsvp, Siemens-S7, skein-256, skein-512, aix-smd5, Snefru-128, Snefru-256, SNMP, STRIP, sxc, Tiger, vdi, whirlpool, whirlpool0, whirlpool1, xmpp-scram, ZIP, ZipMonster, plaintext, has-160, gpg-opencl, mscash2-opencl
63 wpapsk, wpapsk-opencl
64 bsdicrypt