The complexity of a user password in Active Directory domain is one of the key security elements both for user data, and the entire domain infrastructure. Many users prefer to use simple and easy-to-remember passwords despite the recommendation not to use personal info, dictionary words and simple combinations as passwords. In this article, we we’ll show you how to audit Active Directory user passwords, find weak and simple passwords using PowerShell.
Pa$$w0rd
or P@ssw0rd
. How to Install the DSInternals (Directory Services Internals) PowerShell Module?
In order to compare hashes of user passwords stored in the Active Directory database (ntds.dit file) with a dictionary of simple and common passwords, you can use a third-party PowerShell module – DSInternals. This module contains a number of cmdlets that allow to perform different actions with AD database in online or offline mode (directly with ntds.dit). In particular, we are interested in Test-PasswordQuality cmdlet that allows to detect users having weak, similar, standard, blank passwords (Password Not Required), or whose passwords never expire.
In PowerShell version 5 (and newer), you can install the DSInternals module online from the official PowerShell script gallery as follows:
Install-Module DSInternals
In earlier PowerShell versions or in disconnected environment, you have to download the .zip archive with the latest module version from GitHub (https://github.com/MichaelGrafnetter/DSInternals/releases). By the time this article had been written, the latest release was DSInternals v4.4.1. Extract this archive into one of the directories containing PowerShell modules:
- C:\Windows\system32\WindowsPowerShell\v1.0\Modules\DSInternals
- C:\Users\%username%\Documents\WindowsPowerShell\Modules\DSInternals
Or import the DSInternals module into your current PowerShell session using this command:
Import-Module C:\distr\PS\DSInternals\DSInternals.psd1
cannot be loaded because running scripts is disabled on this system
” appears when importing a module, you need to change the current PowerShell execution policy and allow external PS scripts to run at least in the current session:Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass –Force
The list of available module cmdlets can be obtained as follows:
Get-Command -Module DSInternals
Find Weak Active Directory Passwords with Test-PasswordQuality Cmdlet
Next, you need to create a password dictionary. It will be a simple text file with a list of commonly used, weak, and other bad passwords. You can download a password dictionary file from the Internet or create yourself. The DSInternal module allows you to compare the hashes of your users’ passwords in Active Directory with the hashes of words from this file. Save the passwords to a text file PasswordDict.txt.
Now create a small PowerShell script. In the following variables, specify the path to the password file, the domain name and the domain controller name:
$DictFile = "C:\distr\PS\DSInternals\PasswordDict.txt"
$DC = "lon-dc01"
$Domain = "DC=woshub,DC=loc"
Then using the Get-ADReplAccount cmdlet, get a list of users in AD (like Get-ADUser). Additionally, this cmdlet returns their NT and LM hashes, as well as the hash history. Then, for each user, compare the hash of the password with the hashes from the dictionary file (the check is also performed for disabled user accounts):
Get-ADReplAccount -All -Server $DC -NamingContext $Domain | Test-PasswordQuality -WeakPasswordsFile $DictFile -IncludeDisabledAccounts
The result of running the script may look like that:
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: TEST\DefaultAccount TEST\Guest Passwords of these accounts have been found in the dictionary: TEST\a.adams TEST\jbrion TEST\jsanti These groups of accounts have the same passwords: Group 1: TEST\a.novak TEST\Administrator TEST\amuller TEST\k.brown Group 2: TEST\a.adams TEST\jbrion TEST\jsanti 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 administrative accounts are allowed to be delegated to a service: TEST\a.adams TEST\a.novak TEST\Administrator TEST\jbrion TEST\jsanti TEST\k.brown TEST\krbtgt Passwords of these accounts will never expire: TEST\a.adams TEST\Administrator TEST\DefaultAccount TEST\Guest TEST\k.brown TEST\krbtgt TEST\web These accounts are not required to have a password: TEST\ADFS1$ TEST\DefaultAccount TEST\Guest These accounts that require smart card authentication have a password:
ShowPlainText
parameter was available to display the user’s password in clear text if its hash was found in the dictionary. It is missing in the current release of Test-PasswordQuality. If you want to use an older version of the DSInternals module, install it with the command:Install-Module -Name DSInternals -RequiredVersion 2.23
Hash searches are performed including user password history stored in AD. As you can see, AD users with simple passwords were successfully found (passwords match the dictionary). Several users with the same passwords were also found. This script will help you find accounts with simple passwords that are subject to the custom Fine-Grained Password Policies.
You can also perform an offline scan of the Active Directory database file (ntds.dit). You can get a copy of the ntds.dit file from a shadow copy or from a domain controller backup.
To offline check user hashes in the ntds.dit file, use the following commands:
$keyboot= Get-BootKey -SystemHiveFilePath 'C:\ADBackup\registry\SYSTEM'
Get-ADDBAccount -All -DatabasePath 'C:\ADBackup\ntds.dit -BootKey $keyboot | Test-PasswordQuality -WeakPasswordsFile $DictFile
You can also export the list of all hashes to a text file:
Get-ADDBAccount -All -DBPath 'C:\ADBackup\ntds.dit' -Bootkey $keyboot | Format-Custom -View HashcatNT | Out-File c:\ps\ad_hashes.txt -Encoding ASCII
So, using this scenario you can easily analyze the quality of AD user passwords, their resistance against brute force attacks, conclusions the current domain password policy complexity and make the necessary conclusions. Active Directory administrators can (and should) perform this audit regularly.
8 comments
Great post thanks ! 🙂
Thanks for the detailed instructions and I wish it was possible to use this module with bigger password files as stream and for the output file too.
For the section of the report “These groups of accounts have the same passwords:”
Is this for CURRENT passwords or historical?
This means that the current AD password hashes of the users are the same
[…] https://woshub.com/auditing-users-password-strength-in-ad/ […]
Really useful! Thanks!
[…] are great guides and awesome tools out there to solve this – that’s why I didn’t invent anything […]
Thanks, but what does “These administrative accounts are allowed to be delegated to a service” mean?