Functions/Test-JwtSecret.ps1
function Test-JwtSecret { <# .SYNOPSIS Attempts to obtain the secret for an HS256, HS384 or HS512-signed JSON Web Token. .DESCRIPTION Attempts to obtain the secret for an HS256, HS384 or HS512-signed JSON Web Token from a wordlist containing potential secrets. .PARAMETER JsonWebToken The target JSON Web Token to test the list of secrets against. .PARAMETER WordListFilePath The wordlist file containing typical passwords/secrets to test the JWT against. .PARAMETER HashAlgorithm The RSA hash algorithm for the signature. Acceptable values are SHA256, SHA384, and SHA512. Default value is SHA256. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYxNDEwOTMsIm5iZiI6MTYwNjE0MTA5MywiZXhwIjoxNjA2MTQxMzkzLCJqdGkiOiI1Njk5YTBlYTk3YzM0Yzc2OTlkZGZlNzNmNTIzOTI1MiIsInN1YiI6InVzZXJuYW1lQGNvbXBhbnkuY29tIn0.Ej86QALzH37R1zB7QhwwYdFjXL1UhG2E3n6nezEYONY" $jwt | Test-JwtSecret -WordListFilePath ./wordlist.txt Tests an HMAC-SHA256 signed JWT signature against a wordlist. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzUxMiJ9.eyJpYXQiOjE2NzYzMDg2MTksIm5iZiI6MTY3NjMwODYxOSwiZXhwIjoxNjc2MzA4OTE5LCJzdWIiOiJ1c2VybmFtZUBjb21wYW55LmNvbSIsImp0aSI6ImVlODczMzc1MmQ0YTQxNzNiOTA0ODcxZjFjODMxNzQ2In0.rKDBCWkALz7FBTavX9G4HNnaLcyQY8i1WurAs1aQpfDA5Tmi3EtKn6K1k2OO9V-J-94t0ToaypxrtePyc0h8rA" $jwt | Test-JwtSecret -WordListFilePath ./wordlist.txt -HashAlgorithm SHA512 Tests an HMAC-SHA512 signed JWT signature against a wordlist. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE2MDYxNDEwOTMsIm5iZiI6MTYwNjE0MTA5MywiZXhwIjoxNjA2MTQxMzkzLCJqdGkiOiI1Njk5YTBlYTk3YzM0Yzc2OTlkZGZlNzNmNTIzOTI1MiIsInN1YiI6InVzZXJuYW1lQGNvbXBhbnkuY29tIn0.Ej86QALzH37R1zB7QhwwYdFjXL1UhG2E3n6nezEYONY" tjwts -t $jwt -f .\wordList.txt -v Tests an HMAC-SHA256 signed JWT signature against a wordlist with verbose output using function and parameter aliases. .INPUTS System.String A string is received by the JsonWebToken parameter. .OUTPUTS System.String .LINK https://tools.ietf.org/html/rfc7519 #> [CmdletBinding()] [Alias('tjwts')] [OutputType([System.String])] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] [ValidateLength(16, 131072)][Alias("JWT", "Token", "t")][String]$JsonWebToken, [Parameter(Mandatory = $true, ValueFromPipeline = $false, Position = 1)][Alias("Path", "FilePath", "f")] [ValidateScript({ if ( -Not ($_ | Test-Path) ) { $fileNotFoundExceptionMessage = "Wordlist file not found in the following path: {0}" -f $_ $FileNotFoundException = [System.IO.FileNotFoundException]::new($fileNotFoundExceptionMessage) throw $FileNotFoundException } return $true })][System.IO.FileInfo]$WordListFilePath, [Parameter(Mandatory = $false, Position = 2)][Alias('alg')][ValidateSet("SHA256", "SHA384", "SHA512")][String]$HashAlgorithm = "SHA256" ) BEGIN { $decodeExceptionMessage = "Unable to decode JWT." $ArgumentException = New-Object -TypeName ArgumentException -ArgumentList $decodeExceptionMessage } PROCESS { [bool]$hasValidJwtStructure = Test-JwtStructure -JsonWebToken $JsonWebToken -VerifySignaturePresent if (-not($hasValidJwtStructure)) { Write-Error -Exception $ArgumentException -Category InvalidArgument -ErrorAction Stop } [string]$inputFilePath = "" [string[]]$wordList = @() try { $inputFilePath = Get-Item -Path $WordListFilePath | Select-Object -ExpandProperty FullName $wordList = [System.IO.File]::ReadAllLines($inputFilePath) } catch { $fileLoadExceptionMessage = "Unable to open the following file: {0}" -f $WordListFilePath $FileLoadException = [System.IO.FileLoadException]::new($fileLoadExceptionMessage) Write-Error -Exception $FileLoadException -ErrorAction Stop } [int]$wordCount = $wordList.Count [int]$currentIndex = 1 [bool]$secretDiscovered = $false [string]$outputMessage = "Secret not found." foreach ($secret in $wordList) { if ($secret.Trim().Length -ge 1) { $verboseMessage = "Tested $currentIndex of $wordCount secrets." $currentIndex++ Write-Verbose -Message $verboseMessage [bool]$cracked = Test-JwtSignature -JsonWebToken $JsonWebToken -Key $secret.Trim() -HashAlgorithm $HashAlgorithm if ($cracked) { $outputMessage = "The following value is the correct token signing key: {0}" -f $secret Write-Output -InputObject $outputMessage $secretDiscovered = $true break } } } if (-not($secretDiscovered)) { Write-Output -InputObject $outputMessage } } } |