Tools · Active Directory defense · 03 / 23
Kerberoasting explained: how to detect it with Event 4769 and prevent it
Understand why service accounts with SPNs and weak passwords are at risk, find them, detect bursts of RC4 service ticket requests, and fix with gMSAs and AES.
How the technique works
Any authenticated domain user can request a service ticket for any account that has a servicePrincipalName. Part of that ticket is encrypted with the service account’s password-derived key. An attacker can save the ticket and try passwords against it offline, with no further contact with the domain. If the service account has a short or common password, it falls quickly, and service accounts are often privileged.
Nothing about the request is unusual on its own, which is why prevention matters more than detection.
Find exposed accounts
List user accounts, not computers, that have SPNs. Computer accounts have long random passwords that rotate automatically and are not practical to crack. User accounts with SPNs are the risk, especially those in privileged groups or with old passwords.
Check msDS-SupportedEncryptionTypes as well. Accounts that still allow RC4 produce tickets that are much faster to attack.
Get-ADUser -Filter 'ServicePrincipalName -like "*"' -Properties ServicePrincipalName, PasswordLastSet, MemberOf, 'msDS-SupportedEncryptionTypes' |
Select Name, PasswordLastSet, @{n='SPNs';e={$_.ServicePrincipalName -join ';'}}, @{n='Enc';e={$_.'msDS-SupportedEncryptionTypes'}}, @{n='Groups';e={($_.MemberOf | % { ($_ -split ',')[0] -replace 'CN=' }) -join ';'}}Lab: detect a burst
In the lab, request service tickets for several SPNs from the workstation using the built-in klist get command or a PowerShell call to System.IdentityModel, which is how a curious user would. Then on the DC, look for a single account requesting 4769 tickets for many different services in a short window, especially with encryption type 0x17.
Normal users request tickets for a handful of services they use. One account requesting tickets for dozens of SPNs within a minute is the pattern to alert on. A honeypot service account with an SPN that nothing uses makes detection even simpler: any ticket request for it is suspicious.
klist get MSSQLSvc/srv01.lab.internal:1433
# DC: accounts requesting many distinct service tickets in 10 minutes
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4769; StartTime=(Get-Date).AddMinutes(-10)} |
% { $x=[xml]$_.ToXml(); $d=@{}; $x.Event.EventData.Data | % { $d[$_.Name]=$_.'#text' }; [pscustomobject]@{User=$d.TargetUserName; Svc=$d.ServiceName; Enc=$d.TicketEncryptionType} } |
Where-Object { $_.Svc -notmatch '\$|krbtgt' } | Group-Object User | Where-Object { ($_.Group.Svc | Sort -Unique).Count -gt 5 } | Select Name, CountPrevention
Replace user-based service accounts with group Managed Service Accounts, whose 120-character passwords rotate automatically. Where that is not possible, use long random passwords of 25 or more characters stored in a vault. Remove SPNs that are no longer used. Set msDS-SupportedEncryptionTypes to AES only and disable RC4 once compatibility is confirmed.
Remove service accounts from Domain Admins. A service rarely needs domain-wide rights, and a cracked privileged service account is a full domain compromise.
Diagram
A kerberoastable account versus a resilient one
Same service, different exposure.
Account. User account svc_sql with SPN
Password. Seasonal word and year, set 2019
Encryption. RC4 allowed; member of Domain Admins
Account. gMSA with SPN
Password. 120 random characters, rotated automatically
Encryption. AES only; least privilege
Check yourself
1. Who can request a service ticket for an account with an SPN?
2. Which accounts are the realistic kerberoasting risk?
3. Which fix removes the risk most completely?