Getting Password Hashes from Domain Controller

August 9, 2016

There are two ways to get hashes from a remote server:

  • You can inject some malicious code into lsass.exe process and then go through process memory to get hashes;
  • You can get the database with which lsass.exe syncs and get hashes from it.

This post is about the second option.

User current password hashes as well as old password hashes are stored in ntds.dit file. This file is located at C:\Windows\NTDS by default (sometimes not).

File ntds.dit is a database file. A part of it (the most frequently used) is in the memory. lsass.exe can request this file if it needs to. If there are some changes, for example a password changed, lsass.exe pushes the changes into a log file, and then this file is copied into ntds.dit.

File ntds.dit consists of three tables and stores information about domain users. The file is locked by the operating system. To access it, we need to create a shadow copy of C: volume first. To do so we can use a standard windows utility — Volume Shadow Copy Service or VSS that is used for backups:

vssadmin.exe create shadow /for=C:

It will create a copy of volume C:. It is not locked so we can access files on it. Then we need to copy two files:

copy \\?\GLOBALROOT\Device\Harddisk...Copy1\Windows\NTDS\ntds.dit C:\
copy \\?\GLOBALROOT\Device\Harddisk...Copy1\Windows\system32\config\system

In order to decrypt hashes from ntds.dit we need to do the following:

  1. Decrypt the PEK with bootkey (RC4);
  2. First round of hash decryption (with PEK and RC4);
  3. Second round of hash decryption (DES)

PEK is used to encrypt data in ntds.dit. This key is the same within a whole domain so it's the same on every domain controller. PEK is stored in ntds.dit and encrypted by bootkey. bootkey can be collected from SYSTEM registry hive and it is different on all domain controllers.

I used secretdump.py, which is a part of impacket, to extract hashes automatically:

secretsdump.py -system system -ntds ntds.dit LOCAL -outputfile dump

If you want to dump password history use -history flag.

It is slow in the beginning, but eventually we will get three dump files: the files with plain text passwords, the file with NT/LM hashes and the file with Kerberos hashes.

aad3b435b51404eeaad3b435b51404ee in a column of the NTLM file indicates that there's no LM hash and there's only NTLM hash.