How to do a Password Audit of your Active Directory passwords using DSInternals?

Would you like to

  • detect if service accounts or admins are re-using same passwords in Active Directory
  • detect if any accounts are using company standard passwords, based on a dictionary (TXT-file you can provide)
  • detect if sensitive accounts are using passwords, previously being hacked and found on HaveIBeenPwned
  • detect users with no password set
  • detect users with same passwords
  • detect accounts that are susceptible to the Kerberoasting attack
  • detect administrative accounts that are allowed to be delegated to a service
  • detect accounts where Kerberos pre-authentication is not required
  • detect accounts where Kerberos AES keys are missing
  • detect computer accounts having default passwords
  • detect accounts with ‘passwords will never expire’
  • detect accounts that are not required to have a password

If yes, then continue on reading this blog-post 🙂

Great job Michael Grafnetter

Initially, I would like to thank the author of DSInternals, Microsoft MVP Michael Grafnetter, for creating the amazing powershell module, DSInternals. This is a rockstar tool !!

What is DSInternals ?

The DSInternals project consists of these two parts:

How I use it for Password Auditing?

I use DSInternals for Password auditing to :

  • detect if service accounts or admins are re-using same passwords. They must have an unique password
  • detect if any accounts are using company standard passwords, based on a dictionary (TXT-file you can provide)
  • detect if sensitive accounts are using passwords, previously being hacked and found on HaveIBeenPwned
  • detect users with no password set
  • detect users with same passwords
  • detect accounts that are susceptible to the Kerberoasting attack
  • detect administrative accounts that are allowed to be delegated to a service
  • detect accounts where Kerberos pre-authentication is not required
  • detect accounts where Kerberos AES keys are missing
  • detect computer accounts having default passwords
  • detect accounts with ‘passwords will never expire’
  • detect accounts that are not required to have a password

I have uploaded my script on my github, where you can see how I use the tool for password auditing.

Script (main program)

#--------------------------------------------------------
# Variables
#--------------------------------------------------------

$PathOutput = "D:\Scripts\Output"

# This is the location where your password dictionary file exists. You can start by creating a simple file with one line like Password1234
$Passwords  = "D:\SCRIPTS\DATA\AD-DictionaryPasswords.txt"


#------------------------------------------------------------------------------------------------------------
# MAIN PROGRAM
#------------------------------------------------------------------------------------------------------------

$ExportDateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"

$OutPutReport_ALL                   = "$($PathOutput)\OUTPUT\AD-PasswordQualityReport_ALL_$($ExportDateTime).txt"
$OutPutReport_Enabled_Only_ALL      = "$($PathOutput)\OUTPUT\AD-PasswordQualityReport_Enabled_Only_ALL_$($ExportDateTime).txt"
$OutPutReport_Disabled_Only_ALL     = "$($PathOutput)\OUTPUT\AD-PasswordQualityReport_Disabled_Only_ALL_$($ExportDateTime).txt"
$OutPutReport_Admins_Only_ALL       = "$($PathOutput)\OUTPUT\AD-PasswordQualityReport_Admins_Only_ALL_$($ExportDateTime).txt"

$Result_ALL                         = Get-ADReplAccount -All:$true -Server (Get-ADDomainController).Hostname -NamingContext (Get-ADRootDSE | select *naming*).defaultNamingContext
$Result_Enabled_Only_ALL            = $Result_ALL | Where-Object { ($_.Enabled -eq $true) -and ($_.SamAccountType -eq "User") }
$Result_Disabled_Only_ALL           = $Result_ALL | Where-Object { ($_.Enabled -eq $false) -and ($_.SamAccountType -eq "User")}
$Result_Admins_Only_ALL             = $Result_ALL | Where-Object { ($_.AdminCount -eq $true)  -and ($_.SamAccountType -eq "User")}

$PasswordResult_All                 = $Result_ALL | Test-PasswordQuality -WeakPasswordsFile $Passwords
$PasswordResult_Enabled_Only_ALL    = $Result_Enabled_Only_ALL | Test-PasswordQuality -WeakPasswordsFile $Passwords
$PasswordResult_Disabled_Only_ALL   = $Result_Disabled_Only_ALL | Test-PasswordQuality -WeakPasswordsFile $Passwords
$PasswordResult_Admins_Only_ALL     = $Result_Admins_Only_ALL | Test-PasswordQuality -WeakPasswordsFile $Passwords

Write-Output "Building reports ...."
$PasswordResult_All | Out-File -FilePath $OutPutReport_ALL -Encoding UTF8
$PasswordResult_Enabled_Only_ALL | Out-File -FilePath $OutPutReport_Enabled_Only_ALL -Encoding UTF8
$PasswordResult_Disabled_Only_ALL | Out-File -FilePath $OutPutReport_Disabled_Only_ALL -Encoding UTF8
$PasswordResult_Admins_Only_ALL | Out-File -FilePath $OutPutReport_Admins_Only_ALL -Encoding UTF8

Tip – adding OU-filtering

Get-ADReplAccount -All -Server 'dcsrv01.contoso.com' |
    Where-Object DistinguishedName -like '*,OU=Admins,DC=contoso,DC=com' |
    Test-PasswordQuality -WeakPasswordHashesSortedFile d:\scripts\data\ad-passwords.txt

Output

Active Directory Password Quality Report
----------------------------------------

Passwords of these accounts are stored using reversible encryption:
  
LM hashes of passwords of these accounts are present:
  
These accounts have no password set:
  
Passwords of these accounts have been found in the dictionary:
  
These groups of accounts have the same passwords:
  Group 1:
	xxxxx
	yyyyy
  Group 2:
	xxxxx
	yyyyy
  
These computer accounts have default passwords:
  
Kerberos AES keys are missing from these accounts:
  
Kerberos pre-authentication is not required for these accounts:
  
Only DES encryption is allowed to be used with these accounts:
  
These accounts are susceptible to the Kerberoasting attack:
	xxxxx
	yyyyy
  
These administrative accounts are allowed to be delegated to a service:
	xxxxx
	yyyyy
  
Passwords of these accounts will never expire:
	xxxxx
	yyyyy
  
These accounts are not required to have a password:
  
These accounts that require smart card authentication have a password:

Prerequisites before running the script

Microsoft Defender for Identity Exclusions

In case your environment is monitoring by Microsoft Defender for Identity, please start by making an exception of the machine, from where you run the scripts. Otherwise you will get an alert with ‘Suspected DCSync attack (replication of directory services)’

Creation of company dictionary password file

Create a text-file with any known company passwords, one line per password (sample below)

Link to sample file

Password2020
Password2021
Password2022

Installation of Powershell module, DSInternals

# TLS 1.2 must be enabled on older versions of Windows.
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12

# Download the NuGet package manager binary.
Install-PackageProvider -Name NuGet -Force

# Register the PowerShell Gallery as package repository if it is missing for any reason.
if($null -eq (Get-PSRepository -Name PSGallery -ErrorAction SilentlyContinue)) { Register-PSRepository -Default }

# Download the DSInternals PowerShell module.
Install-Module -Name DSInternals -Force

More information

Please check out the official DSInternal homepage using this link

Here you can find other great blog-posts of how to use the other features.

Leave a Reply