Hacking the Local Passwords on a Windows System

While sitting my hotel room one night, bored, I started thinking. I wonder if I could make changes to the local users from a live windows system like the Linux boot disks do. Normally the SAM registry hive is not accessible by a user but if you start regedit.exe as the System user it is visible and hackable. Then the light went on. I can do this. So I started regedit.exe as system an sure enough the SAM was accessible.

Next I had to figure out the data structure of the SAM. The Linux password reset programs do this so I looked at the source code of the linux utility chntpw found at http://pogostick.net/~pnh/ntpasswd/. I found the structure information I needed.

Windows keeps the local user information in a portion of the registry known as the SAM. \\hklm\SAM\SAM If you don't know what this is and how to access it, you probably should stop reading now. You can seriously mess up your system.

Now for the technical stuff. The SAM hive on my computer (Windows 7 x64) looks like this.

Clicking on any of the entries under Names displays the RID of that user. Thus clicking on the Administrator Account reveals this in the right pane:

The RID of the Administrator is 0x1f4 (The built-in Administrator Account always has this RID).
Looking in the Left pane you can locate the user key with that RID.

Opening up this key reveals two sub-keys, Sometimes 3 - There might also be a UserPasswordHint key, but we are not concerned about it.

Here is where it gets a little more complicated. The F key contains account type and state information in binary format.

The F data structure is a as follows (values in HEX):
Offset Length Data Type Explanation
0x00 0x08 Char Unknown
0x08 0x08 Date/Time Time of Lockout
0x10 0x08 Char Unknown
0x18 0x08 Date/Time Time of Account Creation
0x20 0x08 Char Unknown
0x28 0x08 Date/Time Time of Last Login
0x30 0x04 Int32 RID
0x34 0x04 Int? Unknown
0x38 0x02 Unsigned Short ACB_Bits (see below)
0x3A 0x06 Char? Unknown
0x40 0x02 Unsigned Short Count of failed logins
0x42 0x02 Unsigned Short Total Logins since creation
0x44 0x0c Char? Unknown

The ACB Bits are:
Flag Value Explanation
ACB_DISABLED 0x0001 Act disabled
ACB_HOMDIRREQ 0x0002 Home directory required
ACB_PWNOTREQ 0x0004 User password not req
ACB_TEMPDUP 0x0008 Temporary duplicate account??
ACB_NORMAL 0x0010 Normal user account
ACB_MNS 0x0020 MNS logon user account
ACB_DOMTRUST 0x0040 Interdomain trust account
ACB_WSTRUST 0x0080 Workstation trust account
ACB_SVRTRUST 0x0100 Server trust account
ACB_PWNOEXP 0x0200 User password does not expire
ACB_AUTOLOCK 0x0400 Account auto locked

The V data Structure: The first 0xcc bytes are a pointers and length table, the rest is the data. String data is Unicode.
Offset Length Data Type Explanation
0x00 0x04 Int Unknown
0x04 0x04 Int Points to Username
0x08 0x04 Int Unknown - always 0x02 0x00 0x01 0x00
0x0c 0x04 Int User Name offset
0x10 0x04 Int User Name length
0x14 0x04 Int Unknown
0x18 0x04 Int Full Name offset
0x1c 0x04 Int Full Name Length
0x20 0x04 Int Unknown
0x24 0x04 Int Comment Offset
0x28 0x04 Int Comment Length
0x2c 0x1c ?? Unknown
0x48 0x04 Int Home Dir offset
0x4c 0x04 Int Home Dir Length
0x50 0x04 Int Unknown
0x54 0x04 Int Drive Letter for Home Dir offset
0x58 0x04 Int Drive Letter for Home Dir length
0x5c 0x04 Int Unknown
0x60 0x04 Int Logon Script Path offset
0x64 0x04 Int Logon Script Path length
0x68 0x04 Int Unknown
0x6c 0x04 Int Profile Path string offset
0x70 0x04 Int Profile Path String length
0x74 0x28 ?? Unknown
0x9c 0x04 Int LanMan Password hash offset
0xa0 0x04 Int LanMan Password Hash length
0xa4 0x04 Int Unknown
0xa8 0x04 Int NT Password Hash Offset
0xac 0x04 Int NT Password Hash Length
0xb0 0x1c ?? Unknown
0xcc 0xeb Various Data Section

The offsets in the V data structure all point to the data section at 0xcc, so to find something in the data section, you add the offset to 0xcc and that is the place in the v key the data is located. The length of that data is kept in the corresponding length int. If you donít understand all of the above, you might want to reconsider doing what I outline below.

The first thing I wanted to do was to set the password on an account to nothing.

There is a setting in the registry that prevents blank passwords. HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa is a setting called LimitBlankPasswordUse. But since this hack bypasses the normal password setting routines it is ignored.

If you look in the V data structure you see at 0xac the length of the NT Password hash. By default this is set to 0x14. With a little experimentation and studying the code I determined that setting this to 0x04 would fool Windows into thinking there was no password, while leaving the password hash intact.

By default the Administrator account (this is what I was working on) is disabled on Windows 7. The next task was to enable an account. The F key ACB_bits holds the answer. The ACB is a 16 bit integer with each bit a flag. By luck, the first bit is the Account disabled flag. So if you look at the ACB flag and the value is odd then the account is disabled. Just mask out the 1 bit and that is the value to put back in the ACB entry to enable the account.

A little note about the regedit binary value editor: If you open up the V key it will look something like this:

The editor does not work like a normal hex editor. If I wanted to change the value at 0x24 in the example above from 0xc4 to 0xc0, I would have to place my cursor after the value (example circled above in red) and press backspace once. It would delete the entire C4 byte and move all the other bytes up one. Then I could type C0 and it would insert the value I wanted and move all the following bytes down on where there were.

I did a little investigation. Since the password hash was never removed from the data area, I was able to change byte 0xac back to 0x14 and restore the password and access to Protected Storage. My suspicion, however, is that if you made any changes to the account like renaming it, changing Home Dir (anything kept in the data area) all bets are off because the old password hash might be overwritten. I only tested this with the older PStore service which is depreciated since Vista and totally absent in Windows 8.

After the investigation I created a little program that will make just these edits to the registry. This allows you to clear and restore the admin password on both local and remote machines. At the request of a client I also made a version that clears the password and enables the administrator account and then restores the password and disables the account. My quest was complete.

I have give my program to several law enforcement investigators and a few fellow security personnel, but I will not put it up for download here. If you have a legitimate need for it, contact me and we will talk.