2004-12-07

msh meets nolmhash

Every Windows system has a backdoor, a security shortcut tantamount to putting a screen door at the back entrance of the gold depository at Fort Knox and then wedging it slightly ajar with half a brick found outside.

It's called the Local Area Network Manager hash, or LanMan Hash, or LMhash for short. It's preserved for backwards compatibility and it sucks. Rather than storing your password on disk, which is dangerous, Windows hashes it when you first create it: it does some bit-twiddling magic to create a string which is nothing like your password, and thus safe to store on disk. Furthermore, the method by which this string is constructed is reproducible. Every time Windows asks you for your password, it hashes whatever you type, and if the string it creates matches the string it's stored as your password, it assumes you have correctly entered your password.

The LanMan hash does the exact same thing, only before hashing your password, it converts it to uppercase, effectively slashing the message space by not-quite half. NT-based systems consider "password", "Password", and "PAssWOrd" to all be different strings, and they are all given different password hashes. The LanMan hash for each of them is the same. Thus, if an attacker successfully guesses the LanMan hash of your password, he now knows the exact characters in your password, as well as their order. At this point, he needs only to go through each letter and test it as both upper and lower case; the problem space is much, much smaller.

So having a LanMan hash for your password in this day in age is dangerous, dumb, and unnecessary. Wonder why Microsoft still uses 'em? Me too. You should probably turn them off. I turned mine off a long time ago. So long, in fact, that I forgot if I had or not in my most-recent XP install.

Uh-oh. Better check. In XP, you edit the Windows registry.

  Key: HKLM\SYSTEM\CurrentControlSet\Control\Lsa
 Type: DWORD
 Name: "nolmhash"
Value: 0x1

Ordinarily, you'd have to open regedit.exe, manually click through the tree, and verify if it's there or not.

Enter MSH:

MSH>$key = HKLM:\SYSTEM\CurrentControlSet\Control\Lsa
MSH>get-item $key | get-property -Property nolmhash

nolmhash   : 1
Path       : Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
ParentPath : Registry::HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
ChildName  : Lsa
Provider   : System.Management.Automation.ProviderInfo

MSH>

Let's say that value didn't exist and we wanted to add it. No problem. First, I really will remove it, just because I can.

MSH>get-item $key | remove-property -Property nolmhash

Did it work? Let's check

MSH>get-item $key | get-property -Property nolmhash
MSH>

An empty response means it did. Now let's put it back.

MSH>get-item $key | add-propertyvalue -Property nolmhash
MSH>get-item $key | set-property -Property nolmhash -Value 1

I hope that the MSH team gets this procedure streamlined in future releases, but for right now, this clunky kind of beta still gets the job done: we checked, removed, and added a registry value from the command line. Sweet.

Update: Adding registry keys can be done exclusively with the "new-property" cmdlet:

MSH> new-property HKLM:\SYSTEM\CurrentControlSet\Control\Lsa -Property 
nolmhash -Type dword -Value 1

No comments: