Kerberoasting detection in 2026: the 4769 signals that hold up, AES downgrade tells, and clearing service-account account noin week one
Kerberoasting has survived a decade of detection writeups for one boring reason: any authenticated domain user can request a service ticket for any account with an SPN, and the KDC will hand it over without complaint. No exploit, no privilege escalation up front, no malware on disk. Just a normal Kerberos TGS-REQ that looks exactly like the ten-to-twenty service tickets every user pulls on a normal morning. The attacker takes the encrypted blob offline and grinds it against a wordlist on a GPU rig. Nothing touches your network during the part that actually breaks the password.
That is the whole problem with detecting it. The malicious request and the legitimate request are the same protocol message. You are not looking for a bad event; you are looking for a bad pattern hiding inside one of the highest-volume event streams a domain controller produces.
So let’s be precise about what still works in 2026, what’s quietly degrading, and what’s going to flood your SOC in the first week if you turn it on without tuning.
The event you actually care about
Enable Audit Kerberos Service Ticket Operations (success) on your domain controllers, under Advanced Audit Policy Configuration → Account Logon. That gives you event 4769 — a Kerberos service ticket (TGS) was requested — and 4770 for renewals. 4769 is the one that matters. And the obvious-but-skipped check first: if you don’t see 4769 in your DC event logs at all, the audit subcategory isn’t enabled, and nothing downstream matters until it is.
The field that does the work is Ticket Encryption Type. The values you’ll see, in hex:
| Etype | Meaning |
|---|---|
0x17 |
RC4-HMAC (23) |
0x12 |
AES256-CTS-HMAC-SHA1-96 (18) |
0x11 |
AES128-CTS-HMAC-SHA1-96 (17) |
0x1 / 0x3 |
DES-CBC-CRC / DES-CBC-MD5 (legacy, should not exist) |
Classic roasting tools requested RC4 because it cracks orders of magnitude faster than AES — no salt, no iterated hash when deriving the key from the password (AES key derivation runs the password through 4096 PBKDF2 iterations; RC4-HMAC just uses the account’s NT hash directly). So the original, still-useful detection is: 4769 events where Ticket Encryption Type = 0x17 against an account that has an SPN and isn’t a machine account. In Splunk, if you have the Windows TA mapping the field, you’re looking at roughly:
EventCode=4769 Ticket_Encryption_Type=0x17
Service_Name!=*$
Account_Name!=*$
| stats dc(Service_Name) AS distinct_spns count BY Account_Name, src_ip
Note what that query does and doesn’t do. It filters RC4, drops machine accounts (the trailing $ — you’re keeping only non-machine accounts), and then counts distinct SPNs requested per account. The encryption type alone is not the signal — raw 0x17 is everywhere in normal traffic. The fan-out is. One user pulling RC4 tickets for forty different service accounts in ninety seconds is roasting. One user pulling an RC4 ticket for the one legacy app that still negotiates RC4 is Tuesday.
Here is where the lab demo meets production
The AdSecurity writeup that everyone learned this from put the baseline plainly years ago, and it still holds: expect 10 to 20 TGS requests per user per day, and 4769 is one of the most numerous events in the entire domain, which is exactly why so many shops never logged it in the first place. That number is the whole story for your ingest budget.
Do the arithmetic before you turn it on. A 10,000-user domain at 15 requests a day is 150,000 4769 events daily as a floor, and that’s users — service-to-service auth pushes it higher. If you’re on Splunk with ingest-based licensing, shipping every 4769 is real money for an event you’ll filter 99% of away. Two sane options: filter at the forwarder to keep only RC4 (0x17) and DES etypes plus a sampled slice of AES, or keep everything but route it to a cheap cold tier and only accelerate the RC4 subset. The Elastic equivalent works too, it’s just messier because you’re doing the etype filtering in the ingest pipeline instead of at a forwarder, and a broken grok pattern silently drops the field rather than erroring.
The field-parsing failure is the one that bites quietly. If your TA or pipeline isn’t mapping Ticket Encryption Type correctly — and field names and positions can drift after an OS or agent update — your RC4 filter matches nothing and the rule reports clean forever. Verify the mapping after any such update, and run a heartbeat to catch silent breakage: EventCode=4769 | stats count by Ticket_Encryption_Type should always return populated etype values; if the field comes back null, the pipeline is broken, not the network. A detection that can’t fire looks identical to a quiet network right up until the post-incident review.
The first week will be loud, and you already know who’s guilty
Turn on the distinct-SPN fan-out rule and the first alerts will not be attackers. They’ll be your own infrastructure:
Vulnerability scanners doing authenticated scans. Tenable or Qualys running credentialed AD scans will request tickets across a huge swath of SPNs from a single service account. That is, by behavior, indistinguishable from roasting. Note that some scanners cache and spread requests over minutes rather than firing them in one burst, so a tight five-minute window can miss them — test against your scanner’s actual cadence. Carve the scanner’s service account out by name, but pin the carve-out to the scanner’s source IPs so a stolen scanner credential used from a workstation still alerts.
SCCM, SCOM, and backup agents fan out similarly. So does any monitoring platform that enumerates service health. The honest version of this rule has an allow-list of maybe a dozen accounts after the first week, and every entry on that list is a small risk acceptance you should be able to name. Audit and document each one — (RA and AC families, if you’re mapping this to an ATO package — the allow-list is an access-control decision with a risk justification, not a tuning convenience.)
And the legacy RC4 talkers. NetApp filers historically defaulted to RC4-only Kerberos; so do a long tail of appliances and older Java stacks. Those generate a steady drip of 0x17 4769 events that are completely benign and will never stop until someone reconfigures the appliance, which is never. Baseline them and exclude them by Service_Name (the SPN itself, not the requesting account) — but write down that you did, because “we suppressed RC4 alerts for these SPNs” is a sentence an assessor will want to see justified.
One more false-positive source worth pre-empting: Kerberos delegation. IIS app pools and other delegating services produce 4769s that can look like fan-out; tickets issued for delegation carry the Transmitted Services field, so account for or exclude those before you trust the count.
The AES downgrade tell, and why it’s fading
The sharper version of encryption-type detection isn’t “RC4 exists.” It’s “RC4 was issued for an account that should have used AES.” Every account carries an msDS-SupportedEncryptionTypes attribute. If a service account is configured for AES (bit values giving you 0x18 for AES128+AES256) but the KDC issued a 0x17 RC4 ticket, something asked for the weaker cipher on purpose. That’s a downgrade, and downgrades are a much higher-fidelity signal than raw RC4 because they shouldn’t happen in normal operation.
The catch is that the KDC will still happily issue RC4 if the account’s supported-etypes attribute is unset or includes RC4, which across an older AD it very often is by default. So the downgrade tell is only as good as your encryption-type hygiene. If you haven’t enforced AES on service accounts and changed their passwords afterward — and the password change matters, because the KDC derives the RC4 key from the account’s existing NT hash, so setting the etype without rotating the password leaves that RC4 key fully derivable — then “AES account got an RC4 ticket” describes half your estate and detects nothing.
There’s a bigger problem coming, and it’s worth being clear-eyed about. Microsoft has said it intends to disable RC4 by default in a future update to Windows 11 24H2 and Windows Server 2025. Good for hardening. Bad for any detection built on 0x17, because as RC4 gets disabled domain-wide, roasting doesn’t stop — it moves to AES. AES tickets crack slower, but a service account with a weak password falls regardless of cipher. Microsoft’s own October 2024 guidance says this directly: AES is not a fix for brute force, it has to be paired with strong passwords.
The opsec-aware tooling already adapted. Rubeus has had an /rc4opsec mode that deliberately avoids roasting accounts that require AES, precisely so it doesn’t trip the RC4 downgrade alarm. An attacker using it requests AES tickets and your encryption-type rule sees nothing unusual — and against an account whose negotiation strictly forbids RC4 fallback, the attacker is stuck with AES cracking speeds whether they like it or not. Which is exactly why the durable detection can’t rest on the cipher.
The detection that survives RC4’s retirement
When the cipher stops being a tell, behavior is what’s left. The durable signal is the fan-out: a single principal requesting service tickets for an abnormal number of distinct SPNs in a short window, regardless of encryption type. Drop the etype filter from the earlier query, keep the dc(Service_Name) count, and baseline per account. A normal user touches a handful of services a day. A roasting run enumerates SPNs from LDAP first (there’s your GetUserSPNs-style query, often visible as a spike in directory reads) and then pulls tickets for all of them. Because the rule keys on volume rather than a tool signature, it survives obfuscation and ASR/WDAC-evading tradecraft in a way that signature-based detection does not.
Threshold-setting is where this gets annoying. Set the distinct-SPN count too low and the scanners and admins flood you; too high and a patient attacker who roasts twenty accounts an hour slips under it. There’s no universal number — and any value you read here is environment-dependent, not a default to copy. A tightly-scoped 2,000-user domain might alarm at eight distinct SPNs in five minutes, while a sprawling forest with chatty middleware needs the window widened and the threshold pushed up before the false-positive rate is survivable. Start loose, watch a week of real data, and tighten. Expect the first cut to be noisy until the build agents and monitoring accounts get carved out — after which a well-tuned rule typically drops from hundreds of daily hits to a handful.
Two signals stack well on top of the fan-out and cost you almost nothing:
The LDAP reconnaissance that precedes most roasting — an account querying the directory for all objects with a servicePrincipalName set. If you have directory-service object-access auditing on, this surfaces as Event ID 4662 (an operation was performed on an object); a servicePrincipalName enumeration followed within minutes by a burst of 4769s from the same account is a much tighter story than either alone. And Microsoft Defender for Identity raises external ID 2410, Suspected Kerberos SPN exposure, if you run it — useful as a corroborating input, not as your only line, since it sits on the same telemetry and inherits the same blind spots.
Where this maps in the control set
The detection lives in AU — you cannot detect what you didn’t audit, and “Audit Kerberos Service Ticket Operations” being off is the most common reason a shop has no Kerberoasting visibility at all. The monitoring and alerting sit in SI. But the controls that actually reduce the attack surface are IA and AC: gMSA and dMSA accounts, whose passwords run 120 characters and rotate automatically, take service accounts out of brute-force range entirely, and that’s a far better spend than any SIEM rule. dMSA on Server 2025 even supports migrating an existing standalone service account in place. Where you can’t use managed accounts, a 25-plus character random password on every SPN-bearing account does most of the same work. The detection is your safety net for the accounts you couldn’t fix; it was never supposed to be the fix.
So the priority order is: first reduce the surface area with managed accounts and strong passwords, then detect what you couldn’t fix. And if you build only one detection this week, build the distinct-SPN fan-out rule with the encryption type as an enrichment field rather than a filter — the move that matters is from signature-based (etype) to behavioral (frequency and volume). It catches lazy RC4 roasting today and still works the morning RC4 finally gets turned off. The encryption-type-only rule does not, and the calendar on that is no longer hypothetical.
Sources
- Microsoft’s guidance to help mitigate Kerberoasting (Microsoft Security Blog)
- Detecting Kerberoasting Activity (Active Directory Security / adsecurity.org)
- Detect and remediate RC4 usage in Kerberos (Microsoft Learn)
- Suspected Kerberos SPN exposure, external ID 2410 (Microsoft Learn)
- Kerberoasting, T1558.003 (MITRE ATT&CK)