The Incident That Started It All
I'm sitting in a war room with a CISO and their incident response team. The attacker has been evicted, the compromised accounts reset, but the question hangs in the air: How did they get to Domain Admin in under two hours?
The answer was sitting right in plain sight — a service account with a password that hadn't changed since 2019, an SPN registered to it, and a direct path to Domain Admin through group membership. The attacker didn't brute force anything. They just requested a TGS ticket and cracked it offline.
That's Kerberoasting — and if your service accounts have weak passwords or aren't using AES encryption, it's trivial. I see this in maybe half of the identity-based intrusions I work these days.
What Kerberoasting Actually Is
Kerberoasting is an attack that exploits the Kerberos service ticket (TGS) request process. Here's what happens:
- The attacker identifies a user account with a Service Principal Name (SPN) registered
- They request a TGS ticket for that SPN from the KDC
- The KDC returns a ticket encrypted with the account's NT hash
- The attacker takes that ticket offline and cracks the NT hash to recover the password
The key insight: TGS tickets for user accounts are encrypted with the account's own NT hash, not a shared secret like with computer accounts. That means if you know or can guess the password, you can verify guesses against the ticket offline without touching the domain controller.
How Attackers Find Targets
You don't need fancy tools to find Kerberoastable accounts, though BloodHound makes it faster. Here are the three main methods attackers use:
Method 1: GetUserSPNs.py (Impacket)
Method 2: BloodHound Query
Method 3: PowerShell (enumerate locally)
All three methods return the same thing: accounts with SPNs. If you have hundreds of these, that's a problem. Even one high-privilege account with an SPN and weak password is worth cracking.
Why Weak Service Account Passwords Make It Trivial
The attack success rate depends entirely on password strength. Kerberoasting doesn't care if your password is complex — it only cares whether the NT hash can be cracked.
I've seen environments where service accounts had these passwords:
- ServiceAccount2019!
- SQLService$123
- DomainAdmin2024
These crack in seconds using hashcat:
The real issue isn't the attack technique. It's that organizations treat service accounts as "not real users" and let them have weak passwords, never rotate them, and leave them with unnecessary privileges.
Here's the scary part: A properly configured Kerberoastable account with a weak password is more valuable to an attacker than a regular user account. Why? Because:
- Service accounts often have elevated privileges (local admin on multiple servers, database permissions, etc.)
- They're rarely monitored for anomalous activity
- Their passwords never change (or change very infrequently)
- They're often in privileged groups for operational reasons
Detection: What You Should Be Looking For
You can detect Kerberoasting attempts by monitoring a very specific event:
Event ID 4769 — A Kerberos service ticket was requested
Look for these indicators in the event data:
| Field | Normal | Suspicious |
|---|---|---|
| Ticket Encryption Type | 0x12 (AES256), 0x17 (RC4) | 0x17 with high volume |
| Ticket Options | 0x408000 (forwardable) | 0x40A000 (renewable, forwardable) |
| Requesting Account | Regular user accounts | Accounts with no legitimate reason for TGS requests |
| Target SPN | Service-specific (e.g., HTTP/webapp.corp.local) | Generic service names, domain controller SPNs |
The smoking gun: High volume of 4769 events with Ticket Encryption Type 0x17 (RC4) from the same account. This often means someone is requesting many TGS tickets to offline crack.
You can also alert on accounts with SPNs that:
- Haven't changed password in 180+ days
- Are enabled but haven't logged in recently (service accounts should have logon rights, not interactive logons)
- Have paths to Domain Admin in BloodHound
Remediation: Stop the Attack at the Source
You can't "detect your way out" of Kerberoasting. You need to make the attack difficult or impossible. Here's what actually works:
1. Use Group Managed Service Accounts (gMSA)
This is the only real solution for new service accounts. gMSAs:
- Have automatically generated, random 256-character passwords
- Change the password every 30 days automatically
- Are never stored in AD as a recoverable value
- Can't be Kerberoasted because they don't have user SPNs in the same way
2. Enforce AES-Only Encryption for SPN Accounts
RC4 encryption (type 0x17) is what makes offline cracking easy. AES-256 (type 0x12) is much slower to crack and often not worth the effort for attackers.
Configure accounts to use AES only:
3. Remove Unnecessary SPNs
Every SPN you register increases your attack surface. Audit regularly:
- Remove SPNs from accounts that don't need them
- Consolidate service accounts where possible
- Use host-specific SPNs (HTTP/webserver1.corp.local) instead of generic ones (HTTP/corp.local)
4. Rotate Passwords on Legacy Accounts
If you can't use gMSA (legacy apps, third-party software), ensure password rotation:
- Change passwords every 30-90 days
- Use 25+ character passwords with all character types
- Store credentials in a vault, not AD
Tools like Ansible, PowerShell scripts, or commercial password managers can automate this.
The Bottom Line
Kerberoasting works because we treat service accounts as second-class citizens. We give them weak passwords, let them accumulate privileges, and forget they exist — until an attacker uses them as a skeleton key to your domain.
Stop treating service accounts as non-user accounts. Every account with a password is a potential Kerberoasting target. If you have accounts with SPNs that haven't had their password changed in over a year, those are your highest-priority remediations. Start with gMSA for new services. Enforce AES-only encryption on existing SPN accounts. Remove SPNs that aren't needed.
The attack is trivial if you let it be. With proper configuration, it becomes non-trivial — and that's all you need to make the attacker move on to someone else.