ADKERB-001: Kerberoastable Accounts
- Platform
- Active Directory
- Category
- AD Kerberos Security
- Severity
- High
- Zero Trust pillar
- Identity (weight 3)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
The check binds to the default naming context and executes the LDAP query (&(objectCategory=person)(objectClass=user)(servicePrincipalName=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) to return every enabled user account that has at least one SPN registered. For each result it captures servicePrincipalName (full list), sAMAccountName, distinguishedName, userAccountControl, msDS-SupportedEncryptionTypes, pwdLastSet, memberOf, adminCount, and lastLogonTimestamp. It then evaluates each account against three risk dimensions. First, encryption posture: accounts where msDS-SupportedEncryptionTypes is null, 0, or contains the RC4_HMAC_MD5 bit (0x4) without AES bits (0x8 AES128, 0x10 AES256) are flagged as Kerberoast-friendly because RC4 tickets are dramatically faster to crack than AES. Second, privilege exposure: accounts where adminCount=1 or memberOf includes Domain Admins, Enterprise Admins, Schema Admins, Account Operators, Backup Operators, Print Operators, Server Operators, or any custom Tier 0 group are escalated to Critical. Third, password hygiene: pwdLastSet older than 365 days or accounts with the DONT_EXPIRE_PASSWORD bit (0x10000) in userAccountControl are flagged as long-lived secrets that have likely been re-used or leaked. Computer accounts (objectCategory=computer) and Group Managed Service Accounts (objectClass=msDS-GroupManagedServiceAccount) are excluded because their passwords are 120-character random secrets rotated automatically and are not practically crackable.
Why it matters
Kerberoasting is the most reliable path from any domain user to Tier 0 in real environments. Microsoft Defender for Identity, Mandiant, and Secureworks all consistently rank it in the top three lateral-movement techniques observed in ransomware and APT engagements. The attack has four properties that make it durable. (1) It is entirely passive from the targets perspective: the request is a standard TGS-REQ that the KDC happily services for any authenticated user, generating Event ID 4769 that looks identical to legitimate service ticket requests. (2) It bypasses account lockout because cracking is performed offline against the harvested ticket. (3) It bypasses MFA because the service ticket is issued based on the TGT, not a fresh interactive logon. (4) The blast radius is determined entirely by the privilege of the SPN-bearing account, which historically has been high because SQL Server, IIS, SCCM, vCenter, MSSQLSvc, and home-grown applications were commonly installed under domain user accounts that were then granted Domain Admin "just to make it work." A single weak password on a single Kerberoastable account that holds Tier 0 group membership compromises the entire forest. The technique is in active use by Conti, LockBit, BlackCat, APT29, Volt Typhoon, and essentially every modern intrusion playbook.
Attack path
Step 1: Foothold. The attacker holds credentials for any enabled domain user account, obtained via phishing, password spray, NTLM relay, or a low-privilege initial access vector. No groups, no SeDebugPrivilege, no local admin anywhere is required. Step 2: SPN enumeration. The attacker queries LDAP for users with SPNs: Get-DomainUser -SPN (PowerView), GetUserSPNs.py -dc-ip 10.0.0.1 contoso.local/lowpriv:Password123 (Impacket), or Rubeus.exe kerberoast /stats. Modern tradecraft filters out high-RC4-cost accounts and prioritizes accounts in privileged groups via BloodHound edge MemberOf to Domain Admins. Step 3: Ticket request. The attacker triggers a TGS-REQ for each SPN: Rubeus.exe kerberoast /outfile:hashes.txt /nowrap, or GetUserSPNs.py -request. Rubeus and Impacket explicitly request etype RC4_HMAC (0x17) in the KRB-REQ body, which most KDCs honor for backwards compatibility unless msDS-SupportedEncryptionTypes on the account is hardened to AES-only. Step 4: Offline cracking. The captured tickets are formatted as $krb5tgs$23$* (RC4) or $krb5tgs$17$* / $krb5tgs$18$* (AES128/AES256) and fed to hashcat: hashcat -m 13100 hashes.txt rockyou.txt -r best64.rule for RC4, or -m 19700 / 19600 for AES variants. On commodity GPU hardware RC4 tickets crack at billions of hashes per second; an 8-character password from a common pattern (Season+Year, Company+Number) falls in under an hour. AES tickets are roughly two orders of magnitude slower but still cracked when the password is below 12 characters of mixed entropy. Step 5: Pass-the-password or kerberos-pre-auth. The attacker authenticates as the now-cracked service account: runas /netonly, Rubeus asktgt /user:svc_sql /password:Cracked123!, or simply uses the credentials against the service to pivot. If the account is in Domain Admins, the engagement is over. Step 6: Persistence. Real-world adversaries register a new SPN on a low-privilege account they already control (setspn -A) so they can Kerberoast on demand even after the initial path is closed. This adds an SPN to BloodHound that defenders rarely re-baseline.
How Guerrilla assesses it
Guerrilla performs an LDAP search on the default naming context with filter (&(objectCategory=person)(objectClass=user)(servicePrincipalName=*)(!(userAccountControl:1.2.840.113556.1.4.803:=2))) and the attribute set [servicePrincipalName, sAMAccountName, distinguishedName, userAccountControl, msDS-SupportedEncryptionTypes, pwdLastSet, memberOf, adminCount, lastLogonTimestamp, description]. The 1.2.840.113556.1.4.803 OID is the LDAP_MATCHING_RULE_BIT_AND used to exclude disabled accounts (UAC bit 0x2 = ACCOUNTDISABLE). Each returned object is enriched with three derived fields: the cracking cost class (RC4-permitted vs AES-only), the privilege tier (membership recursion through tokenGroups against well-known privileged SIDs S-1-5-32-544, S-1-5-21-*-512, S-1-5-21-*-518, S-1-5-21-*-519, S-1-5-21-*-520), and the password age in days computed from pwdLastSet. The check does not actually request service tickets, so it leaves no Event 4769 trail and cannot be distinguished from a benign read by a downstream IDS. For runtime detection, Guerrilla emits a paired recommendation to enable Audit Kerberos Service Ticket Operations (Success) and to alert on Event ID 4769 where Ticket Encryption Type = 0x17 (RC4) and Service Name does not match the per-account baseline, which is the canonical signal for an active Kerberoast.
Recommended value
Minimal user accounts with SPNs. All Kerberoastable accounts identified, documented with business justification, and protected with 25+ character passwords or migrated to gMSA
Remediation
Enumerate Kerberoastable accounts using Get-ADUser -Filter {ServicePrincipalName -ne '$null'} -Properties ServicePrincipalName. For each account: (1) evaluate if the SPN is still needed, (2) remove unnecessary SPNs, (3) migrate to Group Managed Service Accounts where possible, (4) for remaining accounts ensure passwords are 25+ characters and rotated regularly. Monitor for Kerberos TGS requests targeting sensitive accounts via Event ID 4769
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- IA-5(1)
- ANSSI
- R36
- CIS AD Benchmark
- 7.1.1
- MITRE ATT&CK
- T1558.003