Skip to content

Finding Pwned Passwords in Active Directory

Finding pwned passwords in Active Directory doesn’t need to be taxing. Choosing the right approach can save time and mitigate instability risk. This complete guide walks through each approach, pros and cons and some quicker alternatives.

Weak and pwned passwords accounted for 73% of breaches in the last year, as reported by Verizon and Rapid7. Do you know how many of your users are using a blacklisted password?

If you test user passwords, you’ll know Microsoft has never made it easy. There are always tricks to export password hashes but each method has its pros and cons.

Table of Contents

Before We Begin

If you find this post useful you’re going to love our weekly newsletter. Every monday we send the best 5 Active Directory security links we’ve read each week. Stuck on something? Just search your inbox for our newsletter plus your term and you’ll usually find an answer.

Get the best Active Directory security news, tips and tweaks every Monday.

Why Find Pwned Passwords?

The New NIST Password Guidelines make sensible new recommendations. The current climate of data breaches is at the heart of one of its major changes. That is: check a user password against a corpus of breached data.

A password audit is a very effective way of demonstrating this area of weakness. Two of the most prevalent attacks today: Password Spraying and Credential Stuffing.

How To Find Pwned Passwords?

This is a two-step process. Dump the hashes from a DC first, and then compare the hashes to a list of breached passwords/hashes (we’re going to be using Troy Hunt’s Have I Been Pwned database). Various ways to grab the hashes exist, each carrying some risk as it’s an unsupported process. Techniques for obtaining the hashes from a Windows Domain Controller boil down to:

  • Local Security Authority Subsystem Service (LSASS) injection
  • Shadow Copy replication with Microsoft Vssadmin
  • (Ab)Using the Domain Replication Service

Local Security Authority Subsystem Service (LSASS) Injection

Dumping the LSASS (Local Security Authority Subsystem) process space is the oldest method. This is the historical way of extracting domain hashes within a Windows eco-system. Several tools and techniques exist to do that, one of the most common and reliable is Mimikatz.

Start mimikatz.exe and type the following commands:

privilege::debug
log mimikatz-output.txt
lsadump::lsa /inject /patch

The first command takes care of granting the privileges required. The second sets a log file for the output. The final command instructs the tool on which technique to use (LSASS Injection).

Once this is complete, the log file created should look like this:

mimikatz output

But it needs to be in a pwdump format and to look like this:

user:hash

Note: this is not the full pwdump format but it’s all that’s needed here.

A few lines of awk (after stripping out the header/footer of the log file) will suffice:

# cat mimi.awk
BEGIN { RS = "" ; FS = "\n" ; ORS =""; OFS=""}
{ sub(/User : /,""); print $2 ","}
{ sub(/NTLM : /,""); print $4}
{ print "\n"}

Problems with this technique:

  • Risks crashing / blue screening the server
  • Very likely to trigger an AV
  • Slow and cumbersome (takes a long time to parse the memory space)
  • It’s not secure (hashes will need to be scrubbed).

Using The Windows Tools

A safer way is to rely on the Windows built-in Vssadmin (Volume Shadow Copy) utility. Vssadmin can take a copy of the c:\Windows\NTDS\NTDS.dit file (this file is locked as it’s used by LSASS).

This method is less disruptive, much less likely to get caught by AV and unlocks the password history too. It can take up a lot of space, as the NTDS.dit can grow pretty large. It also might increase the risk of detection and network disruption as a result.

To create a shadow copy and copy the required files (NTDS.dit, SYSTEM, SAM), the commands are as follows:

Create Shadow Copy

vssadmin create shadow /for=C:
vssadmin shadowcopy

Copy NTDS.dit, SYSTEM and SAM

copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\system32\ntds\ntds.dit c:\temp
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\system32\config\system c:\temp
copy \\?\GLOBALROOT\Device\HarddiskVolumeShadowCopy1\Windows\system32\config\sam c:\temp
copy system sam

Clean-Up

vssadmin List shadows
vssadmin Delete Shadows /shadow={Shadow Copy ID}
delete shadow copy

The DSInternals Powershell Module will convert it into a suitable format for cracking:

$key = Get-BootKey -SystemHiveFilePath 'c:\temp\system'
Get-ADDBAccount -All -DBPath 'c:\temp\ntds.dit' -Bootkey $key | Format-Custom -View HashcatNT | Out-File shadow-hashes.txt -Encoding ASCII

The above will process a copy of the NTDS.dit file, extract user and hash information, format it in a hashcat-compatible output and write it to a file.

shadow hashes

(Ab)Using the Domain Replication Service

The safest method of obtaining domain hashes is to (ab)use the ‘Domain Replication Service’. This works by temporarily spawning up a new Domain Controller on the network and syncing up the credential storage to it.

The steps to perform this are as follows:

  1. Install the DS-Internals Powershell Module
  2. Set the credentials
  3. Export the Hashes from AD
  4. Run the script.

The DSInternals package needs to be installed, as follows:

Install-Module -Name DSInternals
dsinternals install

Enter credentials by running the following powershell command:

$credentials = Get-Credential

The following will dump those pesky hashes:

Get-ADReplAccount -all -NamingContext “DC=Example,DC=org” -Server DC1 -Credential $mycredentials | Format-Custom -View HashcatNT | Out-File c:\temp\hashes.txt -Encoding ASCII

Note: Ensure you change the domain and DC according to your environment (here Example, org, and DC1).

The above will produce a hashcat-compatible ASCII plain-text file to compare against the HIBP hashes.

This is how hashes.txt will look like:

Identifying Vulnerable User Accounts

So which users on the network are vulnerable? Let’s explore a couple of ways of doing this.

Using Wordlists

A good wordlist of compromised passwords is needed. There are various lists of cracked passwords over at hashes.org, such as:

John the Ripper and Hashcat are amongst the most respected crackers out there. Usage for these is as follows:

Using JtR (John the Ripper)

john --format=nt hashes.hashcat --wordlist=hashes.org-2019.txt

Using Hashcat

hashcat -m 1000 -a 0 --username hashes.hashcat hashes.org-2019.txt

On a very modest system, it takes less than a couple of minutes to run through the dictionary file which results in the output below:

Viewing the results

$ john --show --format=nt hashes.hashcat|tail
ex468260:budlight
ex360998:passw0rd
ex458554:Mother21
ex997924:Number44
ex591208:Welcome14
ex480187:Lauren24
ex305134:Claire1987
ex956673:abcd1234

323 password hashes cracked, 329 left

----

$ hashcat --username --show -m 1000 hashes.hashcat |tail
ex665602:a4e7a61a102b34f0e0a15e4cc1e8ab77:Liverpool123
ex999378:d59287f790dcbcf24f1bbd8c4703bd54:Password17
ex295780:d59287f790dcbcf24f1bbd8c4703bd54:Password17
ex939490:c5ab70617cae17f46f60a2f175bb5386:Champs02
ex499827:37184b08e38ae6f5057b94141722fa65:M0nday30
ex178773:cab8e82c0ea675f7e3744c808cf3209b:Butterfly29
ex852117:cab8e82c0ea675f7e3744c808cf3209b:Butterfly29
ex472603:cab8e82c0ea675f7e3744c808cf3209b:Butterfly29
ex453529:2fa2b0486ca0fff77ba6ce64d640d864:Central02
ex808769:4b21ab52ba9834f8cd167effc7ec087e:Christmas12

Using HIBP NTLM

To perform this check offline, download a copy of the Have I Been Pwned database, in NTLM format (ordered by hash). It’s not a good idea to perform the password check online.

hibp

Extracting it (with 7zip) can take a while:

7zip

The final step is to compare the Have I Been Pwned (HIBP) database containing the NTLM hashes (sorted by hash) in c:\temp\ with the extracted hashes in the same folder.

This script will make it easy:

powershell -Executionpolicy bypass
Import-Module .\Match-ADHashes

The comparison of the hashes is done using the Match-ADHashes function.

$list = Match-ADHashes -ADNTHashes C:\temp\hashes.txt -HashDictionary C:\temp\hibp.txt

The above command will populate the $list list variable with the results (Note: this might take a while). The results can be exported into a more useful format and write it to disk:

$list | select Hash,Frequency,@{Name=’user’;Expression={[string]::join(“;”, ($_.user))}} | Export-Csv -Path c:\temp\pwned-users-report.csv -Delimiter ‘;’ -NoTypeInformation

Note: Frequency is the number of times that password(hash) has been seen collectively within the Have I Been Pwned leaked database.

The above will pipe the contents of $list into a CSV file with the matching hash, a count and the list of pwned users.

Finding Pwned Passwords in Active Directory

Password Analysis

Pipal

Pipal is a useful utility written by Robin Wood to perform an analysis of user passwords. You have to have access to the plain-text of the password in order to gather any useful information.

Usage of the tool is pretty simple, no external library is needed, just Ruby installed.

Running Pipal on the results obtained yields the following output:

$ ./pipal.rb found.txt
Generating stats, hit CTRL-C to finish early and dump stats on words already processed.
Please wait...
Processing:    100% |oooooooooooooooooooooooooooooooooooooooooo| Time: 00:00:00


Basic Results

Total entries = 346
Total unique entries = 285

Top 10 passwords
Butterfly29 = 3 (0.87%)
Password2 = 3 (0.87%)
Reind33r = 3 (0.87%)
Tanzania3 = 3 (0.87%)
Password284 = 3 (0.87%)
Tilling7 = 3 (0.87%)
Christian7 = 3 (0.87%)
Babybrain3 = 3 (0.87%)
1111111111 = 2 (0.58%)
Molly154 = 2 (0.58%)

Top 10 base words
password = 28 (8.09%)
welcome = 5 (1.45%)
london = 5 (1.45%)
victoria = 4 (1.16%)
tilling = 3 (0.87%)
tanzania = 3 (0.87%)
christmas = 3 (0.87%)
jessica = 3 (0.87%)
april = 3 (0.87%)
liverpool = 3 (0.87%)

Password length (length ordered)
8 = 155 (44.8%)
9 = 85 (24.57%)
10 = 57 (16.47%)
11 = 34 (9.83%)
12 = 14 (4.05%)
14 = 1 (0.29%)

Password length (count ordered)
8 = 155 (44.8%)
9 = 85 (24.57%)
10 = 57 (16.47%)
11 = 34 (9.83%)
12 = 14 (4.05%)
14 = 1 (0.29%)

<--output stripped for brevity-->

Pipal can be used to get a good insight into what common passwords are being used on the Active Directory Domain being tested. This knowledge can be used to create relevant exclusion wordlists to prevent users from setting common, easy-to-guess passwords.

A Different/Better Approach

It’s easy to check how many Windows domain users are using compromised passwords. It’s also rather convoluted and error-prone as well as very time-consuming.

What if there were an automated way of checking this that:

  • Gives instant results (a few minutes vs hours/days)
  • Is comprehensive, repeatable and deterministic
  • Is secure (doesn’t leave a trace of the domain hashes anywhere)
  • Doesn’t require software installation
  • Is user-friendly (not just for ubergeeks)
  • Doesn’t need Domain Admin privileges
  • Has a low footprint and doesn’t require a 30GB+ download of Have I Been Pwned

The efficiency of this process can be significantly improved. Comparison times can be optimized down to milliseconds.

Running Pwncheck

Pwncheck is the most optimal way of getting a list of pwned users. No installation is needed, nor Domain Admin privileges.

The 3 privileges that pwncheck needs can be granted like so:

#Just substitute the pwncheck account below with the account you want to assign replication privileges with

$Account = "pwncheck"

$RootDSE = [ADSI]"LDAP://RootDSE"
$DefaultNamingContext = $RootDse.defaultNamingContext

$cmd = "dsacls '$DefaultNamingContext' /G '`"$Account`":CA;`"Replicating Directory Changes`";'"
Invoke-Expression $cmd
$cmd = "dsacls '$DefaultNamingContext' /G '`"$Account`":CA;`"Replicating Directory Changes All`";'"
Invoke-Expression $cmd
$cmd = "dsacls '$DefaultNamingContext' /G '`"$Account`":CA;`"Replicating Directory Changes In Filtered Set`";'"
Invoke-Expression $cmd

Running pwncheck is a simple three-step process:

  1. Start the pwncheck executable
  2. Wait for it to download/load the DB
  3. Enter your credentials and click Go
safepass.me pwncheck password auditor

After a few seconds, the pwncheck GUI will:

  • Write the report to disk
  • Securely scrub the process memory space and close its main window
  • Open up the report folder to reveal the report data.

The README.html file containing the password audit results can then be viewed for the full report:

safepass.me pwncheck report folder

The pwncheck report dashboard

pwncheck report 1
pwncheck report 2
pwncheck report 3

The Pwncheck report dashboard gives you an at-a-glance overview of compromised, reused and blank passwords across your infrastructure. The free version contains a summary, while the full version can be unlocked at a low cost.

Visit our product page to find out more about pwncheck, or if you’d like to try the full version for yourself at no cost, fill in the form below and we’ll send you details on how to claim a free Pwncheck voucher.

Test Drive Pwncheck

The best way to find out if pwncheck is right for you is to try it out. Use the download button below to try Pwncheck's free version with absolutely zero strings attached, no form entry required.

If you'd like to test drive the full version fill in the form and we'll send you a single-use evaluation licence (normally $150, €120 or £100).