What?
🔗
NTHashes.com provides a free API that allows for querying of more than 850 million passwords which have been exposed via data breaches. The passwords are in NT-Hash format, which is the algorithm used by Microsoft’s Active Directory.
Why?
🔗
To provide a simple and frictionless means for organisations to audit AD account passwords and determine whether any have been leaked in a data breach.
Use of leaked passwords is discouraged as it places accounts at greater risk of credential stuffing. The NIST guidelines also recommend against their use.
How?
🔗
The API uses the k-Anonymity model to provide a level of privacy. In practice, the individual querying the API provides the first 5 characters of the NT Hash. The API responds with all hashes that begin with the provided characters (omitting the 5 characters provided).
On average around 800 hashes will be returned per query. Using this method ensures the service has no means of knowing which actual hash the API consumer is interested in, and whether or not it is present in the compromised passwords list.
The user takes the returned hashes and locally compares them to the remainder of the NT Hash that was not sent. If there is a match, the password has been leaked in a data breach and should not be used.
API Endpoint
🔗
https://api.nthashes.com/search/{first-5-characters-of-nthash}
No authentication is required.
PowerShell Example
Invoke-RestMethod -Uri https://api.nthashes.com/search/64f12 -Method Get
Output (browser)
PS C:\> Invoke-RestMethod https://api.nthashes.com/search/64f12
00AAD6A4F78117B40D1534FBE4D:1
00E420F19E1B91C622D89B6E0B5:1
00ED536FC3A02C755F07D0DB924:2
01664D34F5793C38452D882D894:2
017C407B2EAFFC754DC94A73566:2
01CE4B83CF37FFC436CAB311FE7:12
0219C72A9A33D033919C9D0AF60:1
027E46D884C5D48FBF54B3001E9:33
02B5EC5B2C016F800FB006C654A:1
02E6102FF0B16091EADC00E182B:1
035D958E7C6796C5882D8939956:2
037A3E12AF8E8BA26BEAC2D6682:1
039486ECB4D9790FC388EA9D655:1
03C52C64FFC8F0666BD2B090142:32
0513E40576592F20E4F53EC9006:1
*output truncated*
The format of the output is {remainder-of-hash}:{number-of-times-password-has-appeared-in-dumps}
How do I use this with AD? How do I extract the hashes?
🔗
The Internet is full of guides on different ways to achieve this, here I will provide two methods I have found to be safe, reliable, and simple.
Both methods will use the Windows Server AD DS inbuilt tool ntdsutil to create a “dump” of the Active Directory environment. This dump can be used as a data source to extract password hashes for each account.
The first method of extracting the hashes will be using NtdsAudit
. The second method will use the DSInternals
PowerShell module to perform the same task.
Both methods are provided below in full, and the output of each is a list of accounts with known bad passwords listed in the database. These are minimalist examples, I would encourage adapting them to your environment and needs.
Using NtdsAudit
🔗
This method may be more suitable on systems with older versions of PowerShell (<5), or if it is not desired to install third party PowerShell modules. By default, it also provides additional account information such as whether the user is a Domain/Enterprise admin and whether the account is disabled.
The NtdsAudit tool comes as a single binary which makes post-audit clean-up simple.
Create the Active Directory dump (generates ntds.dit and the SYSTEM registry hive under c:\ad-pw-audit
)
ntdsutil.exe 'ac i ntds' 'ifm' 'create full c:\ad-pw-audit' q q
Download NtdsAudit
cd c:\ad-pw-audit
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Invoke-WebRequest https://github.com/Dionach/NtdsAudit/releases/download/v2.0.7/NtdsAudit.exe -OutFile NtdsAudit.exe
Extract the hashes
.\NtdsAudit.exe '.\Active Directory\ntds.dit' -s .\registry\SYSTEM -p dump.txt
Reformat the exported data
$Temp = Import-Csv .\dump.txt -Delimiter ":" -Header "Username", "UID", "LMHash", "NTHash", "Data"
$Accounts = $Temp | % {$User = $_; $User.Data.Split(",") | % {$Data=$_.Split("="); $User | Add-Member -Name $Data[0] -MemberType NoteProperty -Value $Data[1]}; $User | Select -ExcludeProperty Data}
Query the API and compare to known hashes, outputting accounts with known breached passwords
$Accounts | % {$Acct = $_; ($acct.NTHash).Substring(0,5) | % {$Hashes = Invoke-RestMethod https://api.nthashes.com/search/$_; if (($Acct.NTHash).Substring(5) -in ($Hashes.split(":")) ) {Write-Output $Acct | select Username, UID, Disabled, IsAdministrator, IsDomainAdmin, IsEnterpriseAdmin} Start-Sleep -Milliseconds 100}}
Sample output
Username : domain.local\Administrator
UID : 500
Disabled : False
IsAdministrator : True
IsDomainAdmin : True
IsEnterpriseAdmin : True
Username : domain.local\User1
UID : 1255
Disabled : False
IsAdministrator : False
IsDomainAdmin : False
IsEnterpriseAdmin : False
Username : domain.local\User2
UID : 1256
Disabled : False
IsAdministrator : False
IsDomainAdmin : False
IsEnterpriseAdmin : False
Using DSInternals
🔗
DSInternals is a PowerShell module that exposes advanced Active Directory features. It is available via the PowerShell Gallery, and may be suitable for systems with PowerShell v5 and newer which provides Install-Module
functionality.
Create the Active Directory dump (generatates ntds.dit and the SYSTEM registry hive under c:\ad-pw-audit
)
ntdsutil.exe 'ac i ntds' 'ifm' 'create full c:\ad-pw-audit' q q
Install the DSInternals PowerShell module
Install-Module DSInternals -Force
If you have issues with installation via PSGallery, there are other options on the GitHub page.
Extract the hashes
cd c:\ad-pw-audit
$key = Get-BootKey -SystemHiveFilePath .\registry\SYSTEM
Get-ADDBAccount -All -DBPath '.\Active Directory\ntds.dit' -BootKey $key | Format-Custom -View PWDump | Out-File dump.txt -Force -Encoding ascii
Reformat the exported data
$Accounts = Get-Content .\dump.txt | % {$Account = $_.split(":"); if (($Account[0] -notmatch "[$]$|^Guest$") -and ($Account[0] -ne "")){[pscustomobject]@{Username=$Account[0]; UID=$Account[1]; Hash=$Account[3]}}}
Query the API and compare to known hashes, outputting accounts with known breached passwords
$Accounts | % {$Acct = $_; ($Acct.Hash).Substring(0,5) | % {$Hashes = Invoke-RestMethod https://api.nthashes.com/search/$_; if (($Acct.hash).Substring(5) -in ($Hashes.split(":")) ) {Write-Output $Acct | Select Username, UID} Start-Sleep -Milliseconds 100 }}
Sample output
Username UID
-------- ---
Administrator 500
User1 1255
User2 1256
Questions
🔗
Q: How can I download the entire password list?
A: The list used by NTHashes.com is available from the Have I Been Pwned website.
Q: Do you have the cleartext passwords?
A: No
Q: What if I have thousands of accounts?
A: You can still use the service, but if you intend to run regular audits it may be faster to download the password file locally and query it directly. The DSInternals module has a Cmdlet for this. I’d recommend keeping an eye on the HIBP site to check for updates.
Q: What version of the Pwned Passwords list does this use?
A: Version 8 dated December 2021
Thanks
🔗
This service wouldn’t be possible without the work Troy Hunt put into maintaining and sharing the password list. He has written several posts on how to architect performant querying of a dataset of this nature, and the use of the k-Anonymity model. Troy provides a similar API, but the passwords are SHA1 hashed.
The resources and knowledge he has shared have been invaluable in the creation of the NTHashes API.
Contact
🔗
The easiest way is to DM me on Twitter.
You can also find my blog and check out some of my other work at xkln.net.
Dig this? Want to share it?
🔗