Given that Active Directory logins still primarily rely on usernames and passwords, it's crucial to use secure passwords. However, many passwords have been compromised due to hacking attacks and should be avoided. To determine whether a user is utilizing compromised credentials, you can query HaveIBeenPwned.com.
Wolfgang Sommergut

It's easy to find lists containing vast numbers of hacked passwords on the Internet. These credentials are easily accessible and can be exploited by malicious actors for brute force attacks.

To check whether Active Directory users are utilizing compromised passwords, you can query HaveIBeenPwned.com. This website contains a database of hundreds of millions of stolen passwords.

Consulting HaveIBeenPwned

The website provides a form for interactive usage where you can input a password for verification. This proves useful, for instance, when you want to determine whether a password has been compromised before assigning or changing it.

Determining whether a password has been leaked after a cyberattack

Determining whether a password has been leaked after a cyberattack

For administrators looking up passwords from Active Directory in the lists of HaveIBeenPwned, however, this function is rendered useless because AD passwords are stored as hashes.

Invoke API function

Nonetheless, the website offers an API for this task, where you provide the first five characters of a hash. As a result, you receive all hashes from the database that start with this character sequence, truncated by the initial five characters.

For the hash

198ffc97717b69d5b8227a1dde33bada

you would call the function as follows:

https://api.pwnedpasswords.com/range/198ff?mode=ntlm

The response would then contain c97717b69d5b8227a1dde33bada if the password were compromised.

Retrieving hashes from AD

The initial challenge lies in the fact that neither the GUI tools nor the PowerShell module for Active Directory provides direct access to password hashes stored in AD. Some guides suggest dumping the AD database using a shadow copy for this purpose.

A more elegant approach is available using the DSInternals PowerShell module. It contains the Get-ADReplAccount cmdlet, which generates a replica of the AD database via MS-DRSR. Therefore, you must invoke it with the credentials of an account owning the necessary replication rights.

Installing DSInternals and configuring replication users

The first step is to install DSInternals using the following command:

Install-Module DSInternals

Subsequently, provide the account you intend to use for this task with the required permissions. While a domain admin could be used for this purpose, it's not recommended in production environments.

For this task, open the properties from the context menu of the domain in AD Users and Computers and navigate to the Security tab.

Then grant the desired user or group the Replicating Directory Changes All and Replicating Directory Changes permissions.

Grant permissions to the user responsible for reading the password hashes

Grant permissions to the user responsible for reading the password hashes

Now, you can retrieve an account's password hash and pass the first five characters to the API function of HaveIBeenPwned.

However, you have to overcome another hurdle because the hash is not available as a string but rather as a byte array of decimal numbers. These need to be converted to hexadecimal format and then combined into a string.The complete script is as follows:

Import-Module DSInternals
# Get users who have changed their password after a certain date
$user = Get-ADUser -Properties PasswordLastSet -Filter "PasswordLastSet -gt '08/21/2023'"
# Request the credentials of the user who will fetch the password hashes
$cred = Get-Credential

$user | foreach{
$hash=""
"`nChecking password for: " + $_.SamAccountName
$r = Get-ADReplAccount -SamAccountName $_.SamAccountName -Domain contoso -Server dc1 -Credential $cred -Protocol TCP
#Turn byte array into a hex string
$r.NTHash |foreach{
    $hash += ([Convert]::ToString($_,16)).padleft(2,"0")
}
#Calling Web API passing the first five chars of the hash
$pwned = Invoke-WebRequest -UseBasicParsing -Uri ("https://api.pwnedpasswords.com/range/" + $hash.substring(0,5) + "?mode=ntlm")
#Look up hash in the response from haveIbeenpwned
if($pwned.Content.ToLower().contains($hash.substring(5))){
    "`nPassword for " + $r.DisplayName + " is compromised!"
 }}

The script identifies all users who have changed their passwords since a specific date, such as the beginning of the current month, and checks whether the new password has been compromised.

Executing the AD password verification script

Executing the AD password verification script

Summary

Given that access to Active Directory often relies on just a username and password, it's crucial to employ secure passwords. Administrators can ensure this, to a certain extent, through the password policy.

However, to prevent the use of compromised passwords, external services need to be consulted. HaveIBeenPwned maintains an extensive collection of stolen passwords that can be utilized for this purpose. By calling an API function using PowerShell, one can determine whether passwords have been compromised.

10 Comments
  1. Avatar
    Armando Lopez 9 months ago

    Very useful, thank you.

  2. Avatar
    JC 9 months ago

    This sounds sketchy. Doesn’t this require you to trust HaveIBeenPwned? One may argue that you didn’t give them the entire hash but if they reply with a match that would be a hash try whether it is a valid match or not.

    • Avatar Author
      Wolfgang Sommergut 9 months ago

      Since you don’t have to register with the service, they don’t even know who you are.

    • Avatar
      Brian 9 months ago

      You can also download the entire 613 million hashes from the website and check your hashes against the hibp hashes offline

    • Avatar
      Marcus 9 months ago

      As an additional safety measure I’d recommend not connecting to the service with an which can be tracked back to your institution.

  3. Avatar
    Andy 9 months ago

    It makes me wonder, where did they get their list of emails and passwords in the first place. Foreign contractors, Microsoft’s Foreign force, disgruntle employees, or the maybe a federal government? I would not give anyone any clues as to the users in my domain. You might as well be saying: “Hi Conner here is a list of my users. Put them in your database, please. And then sell them to your comrades.”

    It’s foolware at best but let’s just presume they really do mean good, what happens when they are hacked? And they will be.

    Do you know where the site is hosted? What country? Is it on a dedicated colocation server with little security, is it a VM server on a big tech Cloud ready to be copied, or are they simply spammers looking to build an easy spam list? Maybe it’s the MI6 or KGB, the CIA tally whackers, or is it the NWO monkeys. The point is, avoid it like the plague as some @*%$#$^ will eventually hack it one way or the other. Solar winds, and Amazon should be a huge lesson to any IT professional.

    If you want security, get off the public clouds, traditionally known as web hosts, and create a secure private cloud with military grade Authentication using 2FA and smartcards at a minimum. Again avoid all big tech companies as much as possible. Big tech is not, and never was, your friend. Specifically after the federal antitrust shakedown that happened before 9/11. I miss my “paid for” relatively secure Windows 7.

    I am close to finishing a book with Apress on “Building Secure Private Clouds”. Stay tuned.

    Be Smart and Safe,

    Andy

    • Avatar Author
      Wolfgang Sommergut 8 months ago

      Andy, I think you didn’t understand properly how HIBP works.

      > I would not give anyone any clues as to the users in my domain.

      You don’t. You only send an anonymous HTTP request containing the first 5 chars of a password hash, but no user names. As a response you get a list of hashes (without the leading 5 chars). Your hash may be included in the list or not.

      > Do you know where the site is hosted? What country? Is it on a dedicated colocation server with little security, is it a VM server on a big tech Cloud ready to be copied, or are they simply spammers looking to build an easy spam list?

      The site is run by this guy, who seems to be quit trustworthy:
      https://haveibeenpwned.com/About

      > The point is, avoid it like the plague as some @*%$#$^ will eventually hack it one way or the other.

      And why would this matter to you? What impact would that have on your API call? In the worst case some useless results.

  4. Avatar
    Thomas Welch 9 months ago

    there is similar software that downloads the hashes to the local
    I would put a link, but it would get blocked prob “Specops password auditor”
    You can get a 1 year free Lic as well

  5. Avatar
    Peter Depoorter 8 months ago

    Hi, there’s an easier way, DSInternals contains a function “passwordquality”
    See https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/Test-PasswordQuality.md#test-passwordquality

  6. Avatar
    DefToneR 3 months ago

    I just did a quick test, and hashed 123456 (32ED87BDB5FDC5E9CBA88547376818D4) and run it via the API and didnt found it.

    So my quick tough is that they DB in pwnedpasswords is based on leaks that came in hash already. so they didnt “hash” their password db.

    This still a good idea, but it wont find leaked passwords that the origin wasnt already NTLM hash.

Leave a reply

Please enclose code in pre tags: <pre></pre>

Your email address will not be published. Required fields are marked *

*

© 4sysops 2006 - 2024

CONTACT US

Please ask IT administration questions in the forums. Any other messages are welcome.

Sending
WindowsUpdatePreventer

Log in with your credentials

or    

Forgot your details?

Create Account