Public/Helpers/ConvertFrom-JWT.ps1
|
function ConvertFrom-JWT { [CmdletBinding()] Param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, Position = 0)] # [ValidatePattern('^[A-Za-z0-9][A-Za-z0-9-]+[A-Za-z0-9]$', ErrorMessage = "It does not match a valid JWT Token")] $Base64JWT ) Begin { if ($Base64JWT -like "Bearer *") { $Base64JWT = $Base64JWT -replace "Bearer ", "" } } Process { $Spl = $Base64JWT.Split(".") $token = [PSCustomObject] @{ Header = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String((Invoke-SplitJWT $Spl[0]))) | ConvertFrom-Json Payload = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String((Invoke-SplitJWT $Spl[1]))) | ConvertFrom-Json } $jwtroles = @() # Handle wids (Well-Known IDs for directory roles) if ($token.Payload.wids) { foreach ($Role in $token.Payload.wids) { $jwtRoles += ($SessionVariables.Roles | Where-Object { $_.ID -eq $Role }).displayName } } # Handle roles claim (application permissions or role names) if ($token.Payload.roles) { foreach ($Role in $token.Payload.roles) { $jwtRoles += $Role } } # Handle scp claim (delegated scopes/permissions) $scopes = @() if ($token.Payload.scp) { $scopes = $token.Payload.scp -split ' ' } } End { $result = [PSCustomObject]@{ Audience = $token.Payload.aud Issuer = $token.Payload.iss IssuedAt = [System.DateTimeOffset]::FromUnixTimeSeconds($token.Payload.iat) Expires = [System.DateTimeOffset]::FromUnixTimeSeconds($token.Payload.exp) NotBefore = [System.DateTimeOffset]::FromUnixTimeSeconds($token.Payload.nbf) UPN = $token.Payload.upn FirstName = $token.Payload.given_name LastName = $token.Payload.family_name "ObjectId" = $token.Payload.oid "Auth. Method" = $token.Payload.amr "IP Address" = $token.Payload.ipaddr "Tenant ID" = $token.Payload.tid AppId = $token.Payload.appid AppDisplayName = $token.Payload.app_displayname IdentityProvider = $token.Payload.idp Scope = if ($scopes.Count -gt 0) { $scopes } else { $token.Payload.scp } Roles = if ($jwtRoles.Count -gt 0) { $jwtRoles } else { $null } } return $result } <# .SYNOPSIS Converts a JSON Web Token (JWT) from Base64 encoding to a PowerShell object. .DESCRIPTION Converts Base64-encoded JWT to PowerShell object with decoded header and payload properties. .PARAMETER Base64JWT The Base64-encoded JWT to convert. .OUTPUTS The function returns a PowerShell object with the following properties: - Audience: The audience of the JWT. - Issuer: The issuer of the JWT. - IssuedAt: The timestamp when the JWT was issued. - Expires: The timestamp when the JWT expires. - NotBefore: The timestamp when the JWT becomes valid. - UPN: The user principal name associated with the JWT. - FirstName: The first name of the user associated with the JWT. - LastName: The last name of the user associated with the JWT. - User Object ID: The object ID of the user associated with the JWT. - Auth. Method: The authentication method used for the JWT. - IP Address: The IP address associated with the JWT. - Tenant ID: The ID of the tenant associated with the JWT. - Scope: The scope of the JWT. - Roles: An array of roles associated with the JWT. .EXAMPLE $jwt = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJCbGFja0NhdCIsImlhdCI6MTcyMDAzNzg4MCwiZXhwIjoxNzM1Njc2MjgwLCJhdWQiOiJodHRwOi8vZ2l0aHViLmNvbS9henVyZWtpZC9ibGFja2NhdCIsInN1YiI6Impyb2NrZXRAZXhhbXBsZS5jb20iLCJnaXZlbl9uYW1lIjoiSGFybGFuZCIsImZhbWlseV9uYW1lIjoiU2FuZGVycyIsInVwbiI6Imguc2FuZGVyc0BibGFja2NhdC5pbyIsIm9pZCI6IjkyYmUzMGQ4LTNiYzctNDZjNy05ZDJjLWQ5MGY2MTlmOWNkNCIsImFtciI6Ik1GQSIsImlwYWRkciI6IjEyNy4wLjEuMSIsInNjcCI6IkxhYnMiLCJ3aWRzIjoiNjJlOTAzOTQtNjlmNS00MjM3LTkxOTAtMDEyMTc3MTQ1ZTEwIiwidGlkIjoiNmNhZWM2YWEtMDYzYS00ZGMyLTg2MjUtMGQzN2YwM2ViMWNhIn0.ui-Axc5b6EhazRwYtRYLdMFJpESiwykP8l-4rJgnduQ" $result = ConvertFrom-JWT -Base64JWT $jwt $result This example demonstrates how to use the ConvertFrom-JWT function to convert a Base64-encoded JWT into a PowerShell object. The resulting object is then assigned to the $result variable and displayed. .LINK MITRE ATT&CK Tactic: TA0006 - Credential Access https://attack.mitre.org/tactics/TA0006/ .LINK MITRE ATT&CK Technique: T1552.004 - Unsecured Credentials: Private Keys https://attack.mitre.org/techniques/T1552/004/ #> } |