Cannot Find Key of Appropriate Type, Kerberoasting & Hadoop
Luke Hebert
- 9 minutes read - 1769 wordsWhen a service fails to decrypt an AP-REP message, the root cause is almost always an encryption type mismatch between the keytab and what the KDC actually used to encrypt the service ticket. This guide walks through the Kerberos sequence, identifies where the failure occurs, and provides concrete steps to align encryption types across Active Directory, keytabs, and client configurations.
Kerberos Authentication Sequence
A Kerberos authentication sequence consists of three consecutive request-reply conversations:
- AS-REQ / AS-REP - Client to KDC (AS)
- TGS-REQ / TGS-REP - Client to KDC (TGS)
- AP-REQ / AP-REP - Client to Service
During the TGS conversation, the KDC replies with:
- A service ticket encrypted with the service’s long-term key (most recent KVNO).
- A service session key encrypted with the TGS session key.
In the AP request, the client sends the encrypted service ticket along with an authenticator. At the AP-REP step, the service must decrypt the ticket using the matching key in its keytab. This is where authentication typically fails:
"Cannot find key of appropriate type to decrypt AP REP - <TYPE>"The service ticket was encrypted with <TYPE> in the TGS-REP, but the keytab lacks a matching key. The direct cause is a mismatch between the encrypted keys in the keytab and the encryption types on those keys.
Troubleshooting Checklist
- Determine if Active Directory is in use, and what version.
- AD 2008R2 with DFL/FFL 2008R2: additional steps may be required to enable AES. If not taken, RC4-HMAC (ARCFOUR/ARC4) will be used. Disabling RC4 in AD GPO is a larger organizational activity, not cluster-specific.
- Check keytab encryption types and compare to the error code’s etype.
- Check client and KDC encryption cipher types.
- Check keytab KVNO.
- Check which ciphers are enabled on the affected credentials.
- Check for Unlimited Strength JCE within the JDK (included in JDKs after 1.8u151).
- Potentially regenerate credentials.
msDS-SupportedEncryptionTypes
This is a 32-bit unsigned integer bitfield defined in [MS-KILE] 2.2.7. Per [MS-ADA2], the KDC uses this value when generating a service ticket for the account.
Critical defaults:
| Object Type | Default | Result |
|---|---|---|
| Computer accounts (Win7+/2008R2+) | 0x1C (28) | RC4 + AES128 + AES256, highest mutual = AES256 |
| User accounts | 0x7 (7) | DES_CBC_CRC + DES_CBC_MD5 + RC4, highest mutual = RC4 |
| Trusted domain objects | 0 (undefined) | Falls back to RC4 |
If the field is undefined or set to 0, [MS-KILE] 3.3.5.7 tells us the KDC defaults to 0x7. This is why AD will issue TGTs using AES but service tickets using ARC4/RC4 when the SPN is registered on a user account. The keytab then lacks an RC4 key, and AP-REP decryption fails.
The fix: Set msDS-SupportedEncryptionTypes to 24 (AES128 | AES256) on every SPN-owning object. This applies to user accounts, computer accounts, and trusted domain objects alike.
Cloudera Manager
Handles this via a checkbox labeled Active Directory Set Encryption Types. The types set are based on the encryption types specified in Cloudera Manager.
Ambari
Does not expose a checkbox. Instead, there’s an Account Attribute Template field under Advanced Kerberos-env in the Kerberos Service Configurations. Add "msDS-SupportedEncryptionTypes": "24" to the JSON:
{
"objectClass": ["top", "person", "organizationalPerson", "user"],
"cn": "$principal_name",
#if( $is_service )
"servicePrincipalName": "$principal_name",
#end
"userPrincipalName": "$normalized_principal",
"unicodePwd": "$password",
"accountExpires": "0",
"userAccountControl": "66048",
"msDS-SupportedEncryptionTypes": "24"
}Ambari does not regenerate credentials entirely by removing and re-adding them on each run, so template changes won’t apply automatically. You must disable and re-enable Kerberos while also removing existing credentials.
Verifying with LDAP
ldapsearch -H ldap://ad-1.lab.atx.example.com \
-D 'test1@LAB.ATX.EXAMPLE.COM' \
-b "DC=lab,DC=atx,DC=example,DC=com" -W \
servicePrincipalName="hdfs/*" msDS-SupportedEncryptionTypesReference Table
| Dec | Hex | Supported Encryption Types |
|---|---|---|
| 0 | 0x0 | Not defined, defaults to RC4_HMAC_MD5 |
| 1 | 0x1 | DES_DES_CBC_CRC |
| 2 | 0x2 | DES_CBC_MD5 |
| 3 | 0x3 | DES_CBC_CRC, DES_CBC_MD5 |
| 4 | 0x4 | RC4 |
| 5 | 0x5 | DES_CBC_CRC, RC4 |
| 6 | 0x6 | DES_CBC_MD5, RC4 |
| 7 | 0x7 | DES_CBC_CRC, DES_CBC_MD5, RC4 |
| 8 | 0x8 | AES 128 |
| 9 | 0x9 | DES_CBC_CRC, AES 128 |
| 10 | 0xA | DES_CBC_MD5, AES 128 |
| 11 | 0xB | DES_CBC_CRC, DES_CBC_MD5, AES 128 |
| 12 | 0xC | RC4, AES 128 |
| 13 | 0xD | DES_CBC_CRC, RC4, AES 128 |
| 14 | 0xE | DES_CBC_MD5, RC4, AES 128 |
| 15 | 0xF | DES_CBC_CRC, DES_CBC_MD5, RC4, AES 128 |
| 16 | 0x10 | AES 256 |
| 17 | 0x11 | DES_CBC_CRC, AES 256 |
| 18 | 0x12 | DES_CBC_MD5, AES 256 |
| 19 | 0x13 | DES_CBC_CRC, DES_CBC_MD5, AES 256 |
| 20 | 0x14 | RC4, AES 256 |
| 21 | 0x15 | DES_CBC_CRC, RC4, AES 256 |
| 22 | 0x16 | DES_CBC_MD5, RC4, AES 256 |
| 23 | 0x17 | DES_CBC_CRC, DES_CBC_MD5, RC4, AES 256 |
| 24 | 0x18 | AES 128, AES 256 |
| 25 | 0x19 | DES_CBC_CRC, AES 128, AES 256 |
| 26 | 0x1A | DES_CBC_MD5, AES 128, AES 256 |
| 27 | 0x1B | DES_CBC_CRC, DES_CBC_MD5, AES 128, AES 256 |
| 28 | 0x1C | RC4, AES 128, AES 256 |
| 29 | 0x1D | DES_CBC_CRC, RC4, AES 128, AES 256 |
| 30 | 0x1E | DES_CBC_MD5, RC4, AES 128, AES 256 |
| 31 | 0x1F | DES_CBC_CRC, DES_CBC_MD5, RC4, AES 128, AES 256 |
Example Scenario
A customer showed that authentication works against one service instance (node CBD00439) while having an identical krb5.conf and a service keytab containing only an arcfour-hmac encrypted key. A kinit also works with the new instance’s keytab, confirming it is not corrupt, the key is valid, and the KVNO matches. This suggests:
- In the success scenario, the KDC favored arcfour-hmac to secure the service ticket in the TGS-REP.
- In the failure scenario, the KDC favored aes256-cts-hmac-sha1-96.
If the latter comes from AD logs, it means AD encrypted the service ticket with AES256. Kerberos fails due to the AD-side configuration: the keytab has RC4, the ticket is AES.
Kerberoasting Revisited
Rubeus is a C# Kerberos abuse toolkit that started as a port of @gentilkiwi’s Kekeo toolset. Several recent enhancements to its Kerberoasting implementation required revisiting how it works under the hood. This resulted in some modifications to Rubeus’ approach as well as an explanation for some previous “weird” behaviors seen in the field.
If you’re not familiar with Kerberoasting, here’s the brief summary:
- Attacker authenticates to a domain and gets a TGT.
- Uses the TGT to issue a TGS-REQ for a target SPN (e.g.
MSSQLSvc/SQL.domain.com), specifying supported etypes. - KDC encrypts the service ticket with the highest mutually supported etype between the requester and the SPN-owning account’s
msDS-SupportedEncryptionTypes. - Attacker extracts the encrypted ticket and cracks it offline.
A note on terminology: RC4_HMAC_MD5, AES128_CTS_HMAC_SHA1_96, and AES256_CTS_HMAC_SHA1_96 are referred to as RC4, AES128, and AES256. All examples here are run from a Windows 10 client against a Server 2012 DC with a 2012 R2 domain functional level.
Two Approaches
Kerberoasting generally takes two forms:
- Standalone protocol (Impacket, Rubeus raw): Attacker builds TGS-REQ/TGS-REP manually over the network or via SOCKS proxy. Requires a TGT (plaintext creds or a hash). Full control over requested etypes. No tickets cached on the host.
- Host-based (
KerberosRequestorSecurityToken): .NET requests the ticket into the current logon session. Uses the existing user’s TGT, no creds needed. However, it requests all supported etypes, so the KDC picks the highest mutual. One service ticket cached per SPN.
We often lean toward the host-based approach in engagements because we operate over high-latency C2 and complex multi-party Kerberos exchanges are painful to pipe through a proxy. But the standalone approach gives us etype control that the host-based method doesn’t.
The Unexpected Behavior
Here’s where it gets interesting. If an account is set to 24 (AES only, no RC4 bit), then requesting a service ticket specifying RC4-only should error out.
It doesn’t. We still get an RC4 (type 23) encrypted ticket that we can crack. A Wireshark capture confirms RC4 is the only etype in the request, and the ticket enc-part is indeed RC4-encrypted.
This is likely for failsafe backwards-compatibility reasons. I ran this in multiple test domains with the same result, though someone else I asked couldn’t reproduce it. If anyone has more info, let me know.
Why this matters: If true, there’s no easy per-account way to disable RC4. Even with AES enabled on a user account with an SPN, it’s still Kerberoastable with the hacker-friendly RC4 flavor. The only reliable way to force KDC_ERR_ETYPE_NOTSUPP is disabling RC4 at the domain/DC GPO level, but that also breaks RC4 TGTs, so try it in a lab first.
Rubeus Flags
# Default: KerberosRequestorSecurityToken, all etypes, tickets cached in session
Rubeus.exe kerberoast /nowrap
# Raw TGS-REQ with a supplied TGT blob, full etype control, no host caching
Rubeus.exe kerberoast /nowrap /ticket:ticket.kirbi
# tgtdeleg trick: extract current user's TGT via fake cifs/DC delegation,
# then issue RC4-only TGS-REQs. Single extra cached ticket (cifs/DC).
Rubeus.exe kerberoast /nowrap /tgtdeleg
# Same as above but LDAP-filters to accounts WITHOUT AES (avoids "downgrade" indicator)
Rubeus.exe kerberoast /nowrap /tgtdeleg /rc4opsec
# Opposite: only AES-enabled accounts
Rubeus.exe kerberoast /nowrap /aesThe /ticket: flag lets you supply a TGT blob and build raw TGS-REQs with whatever etype you want. Disadvantage: you need a TGT (elevated extraction or asktgt with a hash).
The /tgtdeleg flag solves that. It uses @gentilkiwi’s Kekeo tgtdeleg trick:
1. GSS-API request for cifs/DC.domain.com (unconstrained delegation target)
2. KDC returns a "fake" delegation TGT containing the user's session key
3. Rubeus extracts that TGT + session key
4. Uses it to build raw TGS-REQs for target SPNs, specifying RC4-only
5. Parses TGS-REP, extracts encrypted service ticket, crackable hashThis also means service tickets aren’t cached on the roasting host, only a single cifs/DC.domain.com ticket is added to the logon session, minimizing host-based indicators.
/rc4opsec adds an LDAP filter to only target accounts that don’t have AES enabled, so we can state “all etypes supported” in the request and still get RC4 back (since RC4 is the highest mutual). This avoids the “encryption downgrade” detection indicator. /aes does the opposite filter.
Domain Trusts
Trusted domain objects start with msDS-SupportedEncryptionTypes undefined, so inter-domain service tickets default to RC4. Fix:
Set-ADObject -Identity "CN=FOREIGNDOMAIN,CN=Trusts,DC=domain,DC=com" `
-Replace @{"msDS-SupportedEncryptionTypes"=24}Kerberoasting should work much better over domain trusts as of the recent commit. Two foreign trusted domain examples have been added to the README.
Relevance
The AP-REP failure mode above, “Cannot find key of appropriate type to decrypt AP REP”, is the defensive mirror of what Kerberoasting exploits. Both hinge on the same KDC decision:
The KDC selects the service-ticket etype based on msDS-SupportedEncryptionTypes on the SPN-owning object, intersected with the requester’s supported etypes.
- Defensive failure: keytab has AES-only keys, but AD issued an RC4 ticket (because
msDS-SupportedEncryptionTypeswas unset/0 on the user account), AP-REP decrypt fails. - Offensive success: attacker requests RC4-only, AD complies (even if account is set to 24), crackable hash.
The fix in both cases is the same: ensure msDS-SupportedEncryptionTypes is explicitly set to the desired value (e.g. 24) on every SPN-owning object, and that keytabs / client configs match.
References
- Microsoft Security Advisory 2868725
- Windows Configurations for Kerberos Supported Encryption Type
- MS-KILE 3.3.5.7
- MS-KILE 3.1.1.5
- Decrypting the Selection of Supported Kerberos Encryption Types
- MS-KILE 2.2.7
- CrowdStrike: Kerberoasting
- harmj0y: Kerberoasting Revisited
- RedTeamSecure: A Guide to Kerberoasting
- SpecterOps: Kerberoasting Revisited
- IronGeek: DerbyCon 9 - Kerberoasting Revisited