Skip to content

Instantly share code, notes, and snippets.

@mrik23
Last active August 3, 2022 20:28
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mrik23/e8efe6dc9cdfe62c9d0bb84dc25288fa to your computer and use it in GitHub Desktop.
Save mrik23/e8efe6dc9cdfe62c9d0bb84dc25288fa to your computer and use it in GitHub Desktop.
PowerShell script to check password against leaked password database from https://haveibeenpwned.com/ using the Pwned Passwords V2 API. Only the first 5 characters of the password string hash is checked against the API (k-anonymity). More info on the HIBP API at https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/.
#requires -version 4
<#
.SYNOPSIS
Check password against leaked password database from https://haveibeenpwned.com/ using the Pwned Passwords V2 API https://api.pwnedpasswords.com/range/<hashPrefix>.
.DESCRIPTION
Only the first 5 characters of the password string hash is checked against the API (k-anonymity). The API returns a list of all passwords matching the hash prefix, then the script checks if the suffix is present or not.
More info on the HIBP API at https://www.troyhunt.com/ive-just-launched-pwned-passwords-version-2/.
.PARAMETER Password
Enter the password to check.
.PARAMETER SecurePassword
Switch to enable secure prompt for password.
.EXAMPLE
.\Test-LeakedPasswordHIBP.ps1 -password "P@ssw0rd"
#>
[CmdletBinding()]
Param(
[Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)]
[string]$Password,
[Parameter(Mandatory=$False)]
[switch]$SecurePassword
)
if ($SecurePassword) {
$Credentials = Get-Credential -Message "Enter the password to test" -UserName "dummy"
$Password = $credentials.GetNetworkCredential().Password
} else {
if ($Password -eq "") {
$Password = Read-Host -Prompt "Enter the password to test"
}
}
#Force TLS 1.2
[Net.ServicePointManager]::SecurityProtocol = [Net.ServicePointManager]::SecurityProtocol -bor [Net.SecurityProtocolType]::Tls12
#Create SHA-1 hash from string
Function Get-StringHash()
{
[CmdletBinding()]
Param (
[Parameter(Mandatory=$True)]
[String]$inputString
)
$Private:outputHash = [string]::Empty
$hasher = New-Object -TypeName "System.Security.Cryptography.SHA1CryptoServiceProvider"
$hasher.ComputeHash([System.Text.Encoding]::UTF8.GetBytes($inputString)) | ForEach-Object { $outputHash += $_.ToString("x2") }
$outputHash.ToUpper()
}
$stringHash = Get-StringHash -inputString $Password
$hashPrefix = $stringHash.Substring(0, 5)
$hashSuffix = $stringHash.Substring(5, ($stringHash.Length - 5))
try {
$response = Invoke-RestMethod -Uri "https://api.pwnedpasswords.com/range/$($hashPrefix)" -Method Get -ErrorVariable errorRequest
}
catch {
Write-Output "Error with the request!"
Write-Output $errorRequest
break
}
if ($response -ne $null) {
$findHashSuffix = $response.Contains($hashSuffix)
if ($findHashSuffix -eq $true) {
$result = $response.Substring($response.IndexOf($hashSuffix), $response.IndexOf([System.Environment]::NewLine, $response.IndexOf($hashSuffix)) - $response.IndexOf($hashSuffix))
$resultCount = ($result.Split(":"))[1]
Write-Output "Your password has been found $($resultCount) times!"
}
else {
Write-Output "Your password has not been found."
}
}
else {
Write-Output "No occurence of the hash prefix found."
}
@patschi
Copy link

patschi commented May 8, 2019

If anyone comes across the same issue: The script unfortunately fails on non-Windows machines, e.g. using PSCore on Linux. The failing line is 92, and related to the Substring.

The reason is that [System.Environment]::NewLine returns back following:

  • on Windows: \r\n
  • on Linux: \n

But as the HIBP API reports back the hashes splitted by the Windows line-endings, the IndexOf/Substring at line 92 fails. The fix is quite simple: Just replace [System.Environment]::NewLine on line 92 with `r`n.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment