Password Magic Numbers


LanManager passwords (“LM”) is a very old and well known password hashing function. Used way back in OS/2 Warp and MS-Net (networking for MS-DOS). It was great in it’s day, however how it worked was not sustainable. The hashing was performed only haver uppercasing and splitting the password into two 7 character chunks. This meant that even if your password was 14 characters long, it was still technically only two 7 character passwords, that could be cracked separately.

NTLM, it’s big brother came along with Windows NT (Windows 95 and Windows 98 did not have NTLM, and we don’t speak about Windows ME). Windows to this day stores both the LM and NTLM versions of passwords. This meant that if your password was under 15 characters it would still be stored in that LM crackable format (unless storage of LM is being prevented, which has become default).

This is where the first “magic number” for passwords comes from. In many pentests I recommended in my reports that all sensitive passwords have a minimum of 15 characters. By doing this, no matter what the setting was for the storage of their passwords on whatever system they might be stored on, it would never be stored in LM. I even recommended it for normal users, but obviously that recommendation never stuck.

Recently I discovered a new “magic number” for passwords: 28.

Before I get into this, all of this information came from Atom (Hashcat primary developer) Solar Designer (John the Ripper) and Magnum (John the Ripper). I’m just putting it together because I had no idea this existed and I’ve been cracking passwords using both of these tools for ages. Huge thanks to them for all their help and patience.

It turns out, that password cracking tools have maximum character lengths for passwords. This boggled my mind for a while but it makes total sense once Atom explained that it has to do with how the tools store the password candidates (dictionary words or generated clear texts to be used in the hash comparison attempt). They are stored in GPU registers, and unfortunately the speed of storing it there comes at a price. That price is that there isn’t enough registers to store candidates over certain lengths. The maximum lengths are specific to how each hashing function works so some maximum lengths are longer than others. The general rule of thumb at least in the world of Hashcat is 55 characters.


The primary reason behind these specific length limits is that exceeding them doubles the amount of processing. The register pressure is a secondary aspect, and mostly limited to GPUs. (On CPUs, the candidate passwords themselves are not in registers.)

– Solar Designer

In the world of Windows however, passwords are stored using UTF16-LE. This means that password candidates are automatically double the character length as most other hashing functions, halving the possible maximum down to 27 characters. This means that lets say your password is a very well known quote like:

You can’t handle the truth!

who’s NTLM hash is E478B144E719CFF85A5F2028F0DF1808 you wouldn’t be able to crack it, even if it was in your dictionary, because it’s 28 characters. This limitation extends to any UTF16 based hash (which almost all Windows based hashing is)

How do you know what the limits are? Well John the Ripper has a handy dandy argument that tells you specifics of each format:

root@crackingbox:/opt/jtr/run# ./john --list=format-details --format=nt
NT      81      24      24      0002000f        43      MD4 256/256 AVX2 8x3  

As you can see in the second column it says “81”. This is the maximum number of UTF8 characters that it can fit for that format type, but because John the Ripper supports up to the full standard of 3 bytes in UTF16, the maximum again, is 27 characters.

You can read more here:

If you read through the openwall posts then you saw there is a way to compile John (jumbo) to squeeze out a few more characters:

(This will slow down cracking considerably)

root@crackingbox:/opt/bigjohn/src/#./configure --disable-native-tests CFLAGS='-O2 -mno-sse2 -mno-mmx -U__SSE__'

Lets see what this gets us:

root@crackingbox:/opt/bigjohn/run/# ./john --list=format-details --format=nt
NT      125     1       1       0002000f        43      MD4 32/64

We now have 125 total characters total (not just 41 - thanks Solar Designer for the update). And as you can probably guess, it cracks the password just fine now:

root@crackingbox:/opt/bigjohn/run/# ./john /tmp/hashtest.txt --format=nt --wordlist=/tmp/list.txt
Using default input encoding: UTF-8
Loaded 2 password hashes with no different salts (NT [MD4 32/64])
Remaining 1 password hash
Press 'q' or Ctrl-C to abort, almost any other key for status
You can't handle the truth! (Martha)
1g 0:00:00:00 DONE (2017-05-07 00:58) 33.33g/s 133.3p/s 133.3c/s 133.3C/s You can't handle the truth!
Use the "--show" option to display all of the cracked passwords reliably
Session completed

Hashcat also has a branch that supports longer passwords, but currently doesn’t support NTLM:

So now my recommendations for passwords, at least in the Windows world is 28 characters or more makes it so that without tweaking, your 28 character Jack Nicholson quote based password is safer (I mean, Mimikatz still works, and keyloggers, and so on and so forth…)

28 characters is a bit tough to force on standard users, but making sure that at least your service, admin and “high risk” accounts are > 28 is a good step.

Solar Designer also pointed me at the Openwall product called passwdqc which is much more affordable than other password products I’ve seen for enterprises. Here is a direct link to the Windows version that allows 30 day trial:

I definitely could get things wrong in this post, it’s very new to me and I’m still digging. Please hit me up with any corrections via comments below, Facbook, Twitter, IRC, Google Hangouts, Wire, Signal, AIM, Slack, LinkedIn, Mastadon, WhatsApp, Skype, smoke signals… however you wish, I’ll update this post as needed. Thanks!

– mubix