Audit your Active Directory user passwords against haveibeenpwned.com safely using PowerShell

Audit your Active Directory user passwords against haveibeenpwned.com safely using PowerShell

You will be surprised how many of your users are on the list :)

ยท

4 min read

In this article, I will show you, how to easily and securely check, whether some of your users are using leaked passwords. All of this by running one PowerShell function ๐Ÿ‘.

Why you should care you may ask? Leaked passwords shouldn't be used, because attackers will with high probability try to use them in their brute force attacks (like in last Colonial Pipeline attack). Plus attackers are in general exploiting human laziness i.e. usage of the same password across different services.

What does it mean securely? There are free tools or builtin paid one that do quite the same thing as my solution. But when dealing with AD passwords (or generally anything that needs Domain Admin rights) I am very cautious. Therefore I do all sensitive actions in VM without a network connection, use secure delete, plus data never leaves high tier servers. So no sensitive information can leak.


Disclaimer

What is safe in my environment can be unsafe in yours, so think this through before implementing!


Table of Contents


Prerequisites:


Break down of the PowerShell function

Function Invoke-ADPasswordsAudit will:

  • Check if there is a newer version of haveibeenpwnd database
  • Export ntds.dit and syskey on random DC
  • Creates VM on Hyper-V cluster node (without network connection)
  • To cluster node, where VM will be hosted copy
    • exported ntds and syskey
    • DSInternals and haveibeenpwnd database
  • Delete ntds.dit and syskey on DC
  • From cluster node to VM copy
    • exported ntds and syskey
    • DSInternals and haveibeenpwnd database
  • Delete this copied data on the cluster node
    • ntds.dit and syskey
    • deprecated haveibeenpwnd databases
  • Run DSInternals function Test-PasswordQuality inside the VM, to test AD passwords
  • Get the results
  • Remove VM

Interesting parts of the function

1. Extracting Active Directory passwords

"Exporting NTDS and syskey on $DC"

# where the exported data will be stored on DC
$IFMPath = "C:\Windows\whatever"
# pick DC with PDCEmulator role (it doesn't matter, but why not)
$DC = ((Get-ADDomain | Select-Object -exp PDCEmulator) -split "\.")[0] 

Invoke-Command -ComputerName $DC {
    param ($IFMPath)

    if (Test-Path $IFMPath -ea SilentlyContinue) { Remove-Item $IFMPath -Recurse -Force }

    $IFM = ntdsutil "activate instance ntds" ifm "create full `"$IFMPath`"" q q

    if (!($IFM -like "*IFM media created successfully*")) {
        Remove-Item $IFMPath -Recurse -Force # just for sure
        throw "Export failed`n`n$IFM"
    }
} -ArgumentList $IFMPath

2. Running DSInternals with haveibeenpwned database against extracted passwords

Just for sure, on VM without network connection run:

"Getting leaked passwords used in your Active Directory domain"

Import-Module "DSinternals" -ErrorAction Stop

#region important variables
# path to downloaded ntlm ordered database of passwords from https://haveibeenpwned.com/Passwords
$pwnedPasswords = "C:\whatever\pwned-passwords-ntlm-ordered-by-hash.txt" 

# path to txt file with manually entered passwords you want to check too (one password at a line)
$weakPasswords = "C:\whatever\weakPasswordsFile.txt"

# path to exported SYSTEM registry that you've got on DC by running ntdsutil command in previous step
$key = Get-BootKey -SystemHivePath 'C:\whatever\registry\SYSTEM'
if (!$key) { throw "Couldn't get syskey" }

# path to exported ntds.dit password database that you've got on DC by running ntdsutil command in previous step
$ntds = 'C:\whatever\Active Directory\ntds.dit'
#endregion important variables

# parameters for Test-PasswordQuality
$params = @{
    WeakPasswordHashesSortedFile = $pwnedPasswords
}
if ($weakPasswords) {
    $params.WeakPasswordsFile = $weakPasswords
}

# run passwords audit
$result = Get-ADDBAccount -All -DatabasePath $ntds -BootKey $key | Test-PasswordQuality @params

# to get nice human readable output
return ($result | Out-String)

OK so how to use it?

  1. To C:\ADAudit download:
  2. Check the content of both scripts to know, what they are doing
  3. Test & modify the New-VMFromTemplate function to work in your environment
  4. In PowerShell console that runs under Domain Admin
    • Dot source both scripts to load defined functions
    • Run
      Invoke-ADPasswordsAudit -pwnedPasswordsNTLMOrdered "C:\ADAudit\pwned-passwords-ntlm-ordered-by-hash-v7.txt" -DSInternals "C:\ADAudit\DSInternals"
      
  5. Wait :)
    • It can take dozens of minutes to finish because a new VM has to be created, 20GB passwords file has to be copied to node cluster and then to VM itself, and of course, your AD hashes has to be compared with it...

Summary

It's good practice to run this function on regular basis, because passwords of your users are going to change, so as leaked password database :)

Enjoy! ๐Ÿ‘

Did you find this article valuable?

Support Ondrej Sebela by becoming a sponsor. Any amount is appreciated!

ย