Dissecting Kerberoasting: Protocol Mechanics, Telemetry Blindspots, and Modern Detection Engineering
Executive Overview & The Emerging Threat Surface In enterprise identity security, Active Directory (AD) remains the operational backbone for authentication and access governance across global networks. However, architectural decisions codified in foundational RFC standards continue to provide adversaries with reliable, stealthy post-exploitation attack vectors. Among credential extraction methodologies, Kerberoasting represents one of the most structurally resilient techniques. It requires no elevated privileges, operates within normal protocol expectations, and weaponizes the core trust architecture of the Kerberos V5 protocol (RFC 4120).
The threat mechanics expose a structural design trade-off in distributed authentication: any authenticated domain account—regardless of how restricted its access rights are—possesses legitimate authority to request a Ticket Granting Service (TGS) ticket for any service registered with a Service Principal Name (SPN) inside the Active Directory forest. When an adversary establishes initial access via an unprivileged compromised user account or an unmanaged domain-joined workstation, they can systematically interrogate the Key Distribution Center (KDC) hosted on domain controllers for service tickets. The KDC generates each requested service ticket and encrypts the ticket segment containing user authorization data with the secret key of the target service account.
Crucially, the domain controller does not verify whether the requesting security principal actually initiates a network connection to the target application server, nor does it enforce access control lists (ACLs) on the ticket issuance itself. Ticket generation strictly verifies two prerequisites: that the requester possesses a valid Ticket Granting Ticket (TGT), and that the requested SPN maps to an existing Active Directory principal.
Once the adversary receives the TGS response (KRB_TGS_REP), the ticket ciphertext can be extracted directly from client memory or collected from network captures and transferred to an offline attacking machine. At this junction, the attack moves entirely out-of-band:
- Zero additional packets are transmitted to target domain infrastructure.
- Domain account lockout policies (LockoutBadCount) are rendered completely ineffective.
- Adversaries execute high-throughput dictionary or brute-force attacks across dedicated GPU clusters without triggering account lockouts or host-based security alerts.
The persistence of Kerberoasting across enterprise environments stems from two systemic operational vulnerabilities:
- Legacy Cryptographic Fallback: Despite ubiquitous operating system support for the Advanced Encryption Standard (AES), thousands of production environments still permit RC4-HMAC (0x17) cipher suites for Kerberos ticket encryption (RFC 4757). Under RC4-HMAC, the Kerberos secret key is directly equivalent to the service account's NTLM hash (MD4(UTF-16LE(password))), enabling modern GPU rigs to evaluate tens of billions of candidate passwords per second.
- Service Account Governance Decay: In enterprise networks, legacy service accounts frequently hold administrative entitlements, such as membership in Domain Admins or sysadmin privileges on clustered database instances. Organizations routinely configure these accounts with static passwords that are rarely or never rotated, creating direct domain compromise paths upon offline hash recovery.
Security Operations Centers (SOCs) face an acute telemetry challenge. In active corporate environments, line-of-business applications (e.g., SharePoint, Microsoft SQL Server, enterprise reporting services) legitimately generate hundreds of TGS ticket requests hourly. Dissecting routine operational traffic from adversary harvesting requires telemetry pipelines capable of analyzing cryptographic parameters, request velocities, service principal categories, and baseline account behavior. Attack Anatomy & Technical Breakdown Engineering effective detection logic and architectural mitigations requires dissecting the cryptographic handshakes, cipher negotiation structures, and offline execution boundaries defined by RFC 4120 and RFC 4757.
sequenceDiagram
sequenceDiagram autonumber actor Attacker as Adversary (Low-Priv User) participant KDC as Domain Controller / KDC participant LDAP as Active Directory LDAP participant Host as Target Service Host (MSSQL) participant Rig as Offline Cracking Rig (GPU) Note over Attacker,KDC: Phase 1: Authentication & Reconnaissance Attacker->>KDC: AS-REQ (Client Timestamp pre-authentication) KDC-->>Attacker: AS-REP (TGT encrypted with krbtgt key + Session Key) Attacker->>LDAP: LDAP Query: (&(servicePrincipalName=*)(samAccountType=805306368)) LDAP-->>Attacker: Enumerates user accounts with SPNs (e.g., MSSQLSvc/db01.corp.local) Note over Attacker,KDC: Phase 2: In-Band Service Ticket Request Attacker->>KDC: TGS-REQ (TGT + Authenticator + SPN + RC4 0x17 requested) Note over KDC: KDC logs Event ID 4769<br/>TicketEncryptionType: 0x17<br/>Status: 0x0 KDC-->>Attacker: TGS-REP (Service Ticket encrypted with target account NTLM hash) Note over Attacker,Rig: Phase 3: Out-of-Band Offline Hash Recovery Attacker->>Rig: Extract ticket ciphertext from LSASS memory or network stream Note over Rig: High-Throughput Hashcat Dictionary Attack (~100 GH/s)<br/>Zero network packets sent to target AD infrastructure<br/>Domain account lockout thresholds bypassed Rig-->>Attacker: Plaintext Service Password Recovered Attacker->>Host: Lateral Movement & Elevated Execution via Cracked Credentials
The Three-Tier Protocol Exchange The Kerberos V5 authentication framework operates across three distinct exchanges:
- Authentication Service Exchange (AS-REQ / AS-REP): The client initiates authentication by sending a KRB_AS_REQ containing pre-authentication data—an encrypted timestamp generated with a key derived from the user's password. The KDC decrypts the timestamp to validate credentials and ensure the client clock is within the domain skew tolerance (default: 5 minutes). Upon validation, the KDC issues a KRB_AS_REP containing the client's Ticket Granting Ticket (TGT) encrypted with the domain's krbtgt account key, along with a logon session key encrypted with the client's secret key.
- Ticket-Granting Service Exchange (TGS-REQ / TGS-REP): To access a network service, the client transmits a KRB_TGS_REQ containing the TGT, an authenticator message encrypted with the logon session key, and the target service's SPN (e.g., MSSQLSvc/db01.corp.local:1433). Within this request, the client advertises its acceptable encryption algorithms (etypes) in the padata and body fields.
- KDC Ticket Packaging and Cipher Selection: The KDC decrypts the TGT using its krbtgt secret key. It queries Active Directory via LDAP to match the requested SPN to a specific security principal (User or Computer account). The KDC extracts the target account's secret key, packages the user's authorization data (the Privilege Attribute Certificate or PAC), and encrypts the service ticket using the target account's secret key. The KDC then transmits the resulting KRB_TGS_REP back to the client.
flowchart TD
graph TD
A[Initial Compromise: Low-Privilege Domain User] --> B[Enumerate User Accounts with SPNs via LDAP]
B --> C{SPN Account Class?}
C -->|Computer Account $| D[Bypass: 120-byte random password automatically rotated every 30 days]
C -->|User Service Account| E[Construct TGS-REQ with EType 0x17 RC4-HMAC]
E --> F[KDC Issues Event 4769 & Returns TGS-REP]
F --> G[Extract Ticket Ciphertext to Offline Cracking Rig]
G --> H{Ticket Encryption Type?}
H -->|RC4-HMAC 0x17| I[Direct MD4 NTLM Hash: ~100 GH/s on Modern 8x GPU Rig]
H -->|AES256 0x12| J[PBKDF2 Salted HMAC-SHA1 4096 iters: ~8 MH/s Intractable]
I --> K[Recover Cleartext Password / Lateral Movement]
J --> L[Cracking Fails / Defeated by Computational Complexity]Cipher Negotiation & Cryptographic Threat Matrix The computational viability of cracking extracted tickets depends on the cipher negotiated during the TGS exchange:
Dimension / Metric RC4-HMAC (etype 0x17) AES128-CTS-HMAC-SHA1 (0x11) AES256-CTS-HMAC-SHA1 (0x12) Governing Standard RFC 4757 RFC 4120 RFC 4120 Underlying Key Material Direct NTLM Hash (MD4(UTF-16LE)) 128-bit PBKDF2-HMAC-SHA1 256-bit PBKDF2-HMAC-SHA1 KDF Salt Requirement None (Raw Password Hash) Domain FQDN + SamAccountName Domain FQDN + SamAccountName PBKDF2 Iteration Count 0 iterations 4,096 iterations 4,096 iterations Cracking Speed (8x RTX 4090) ~80 - 110 Billion hashes/sec ~12 - 18 Million hashes/sec ~6 - 10 Million hashes/sec Lockout Risk During Execution Zero (Completely Out-of-Band) Zero (Completely Out-of-Band) Zero (Completely Out-of-Band) Practical Feasibility Trivial against human passwords Computationally Intractable Computationally Intractable
When an adversary crafts a KRB_TGS_REQ, they can deliberately restrict the requested encryption types to 0x17 (RC4-HMAC). If the target service account does not explicitly enforce AES support—or if the domain controller policy permits legacy fallback—the KDC satisfies the request using RC4.
Under RC4-HMAC, the key used to encrypt the ticket is directly derived from the account's NTLM hash (MD4(UTF-16LE(password))). Cracking software executes plain MD4 transformations directly against wordlists. Conversely, with AES128 (0x11) and AES256 (0x12), the key is derived using PBKDF2 with 4,096 iterations of HMAC-SHA1 salted with the combined domain realm and username string. This cryptographic overhead slows candidate password evaluation by a factor of nearly 10,000. The Critical "0x18" Trap in Active Directory Auditing A frequent engineering error in Active Directory auditing stems from confusing the hexadecimal value 0x18:
- In the Active Directory LDAP schema attribute msDS-SupportedEncryptionTypes, 0x18 is a bitwise combination: 0x8 (AES128_CTS_HMAC_SHA1_96) + 0x10 (AES256_CTS_HMAC_SHA1_96) = 0x18. In this attribute, 0x18 represents the hardened state where only modern AES algorithms are permitted.
- In Windows Security Event Log Event ID 4769 (A Kerberos service ticket was requested), the field TicketEncryptionType reflects protocol enums defined in RFC 4120 and RFC 4757. Here, 0x17 indicates RC4-HMAC, whereas 0x18 indicates RC4-HMAC-EXP (an obsolete export-grade cipher). A SIEM query filtering on TicketEncryptionType == 0x18 captures legacy export ciphers, not hardened AES. Hardened AES ticket issuances appear in Event ID 4769 strictly as 0x11 (AES128) or 0x12 (AES256). PowerShell Environment Audit Script To inventory enterprise exposure, security engineers must identify all user accounts (excluding machine accounts whose passwords rotate automatically with 120-byte pseudo-random strings) that have SPNs registered, alongside their configured encryption capabilities and administrative status.
[CmdletBinding()]
param (
[Parameter(Mandatory = $false)]
[string]$DomainController = $env:LOGONSERVER.TrimStart('\')
)
Import-Module ActiveDirectory -ErrorAction Stop
Write-Host "[*] Auditing Active Directory SPN Attack Surface on $DomainController..." -ForegroundColor Cyan
# Query user accounts with registered SPNs, excluding computer objects
$SpnUsers = Get-ADUser -Filter {servicePrincipalName -like "*"} `
-Server $DomainController `
-Properties servicePrincipalName, msDS-SupportedEncryptionTypes, `
PasswordLastSet, CannotChangePassword, PasswordNeverExpires, `
AdminCount, MemberOf
$AuditRecords = [System.Collections.Generic.List[PSObject]]::new()
foreach ($User in $SpnUsers) {
# Exclude machine accounts (SamAccountNames terminating in $)
if ($User.SamAccountName.EndsWith('$')) {
continue
}
$ETypeBitmask = $User.'msDS-SupportedEncryptionTypes'
$SupportsAES = $false
$Status = "Vulnerable (Default / RC4 Fallback)"
if ($null -ne $ETypeBitmask) {
# Check for AES128 (0x8) and AES256 (0x10) flags
$HasAES128 = [bool]($ETypeBitmask -band 0x8)
$HasAES256 = [bool]($ETypeBitmask -band 0x10)
if ($HasAES128 -or $HasAES256) {
$SupportsAES = $true
$Status = if ($HasAES256) { "Hardened (AES-256 Enabled)" } else { "Partially Hardened (AES-128 Only)" }
}
}
$IsPrivileged = ($User.AdminCount -eq 1)
$AuditRecords.Add([PSCustomObject]@{
SamAccountName = $User.SamAccountName
DistinguishedName = $User.DistinguishedName
RegisteredSPNs = ($User.servicePrincipalName).Count
EncryptionBitmask = if ($null -eq $ETypeBitmask) { "0x0 (Unset)" } else { "0x{0:X}" -f $ETypeBitmask }
SupportsAES = $SupportsAES
Status = $Status
PrivilegedAdminCount = $IsPrivileged
PasswordLastSet = $User.PasswordLastSet
})
}
Write-Host "[+] Audit complete. Found $($AuditRecords.Count) user SPN accounts." -ForegroundColor Green
# Filter and display high-risk accounts lacking AES or holding administrative flags
$HighRiskAccounts = $AuditRecords | Where-Object { -not $_.SupportsAES -or $_.PrivilegedAdminCount }
$HighRiskAccounts | Format-Table -AutoSize SamAccountName, Status, EncryptionBitmask, PrivilegedAdminCount, PasswordLastSet
- Architectural Remediation: Group Managed Service Accounts (gMSA) The definitive architectural solution to Kerberoasting is replacing traditional user-based service accounts with Group Managed Service Accounts (gMSAs). Introduced in Windows Server 2012, gMSAs delegate credential lifecycle management directly to the KDC.
Key security controls of gMSAs include:
- 128-Character Randomized Passwords: The KDC generates complex 128-character passwords using high-entropy random byte arrays. Even if an adversary extracts a ticket for a gMSA, cracking a 128-character high-entropy secret offline is computationally impossible.
- Automatic 30-Day Rotations: Passwords rotate automatically without administrative intervention or service interruption.
- Disabled Interactive Logon: gMSAs cannot be used for interactive console, RDP, or SSH sessions, eliminating credential dumping from local LSASS memory.
Group Managed Service Account Deployment for Clustered SQL Services
Run on Domain Controller or Administrative Host with RSAT ActiveDirectory
Step 1: Ensure the KDC Root Key exists (configured once per forest)
Get-KdcRootKey -ErrorAction SilentlyContinue | Out-Null
if (-not (Get-KdcRootKey)) {
Add-KdcRootKey -EffectiveTime ((Get-Date).AddHours(-10))
}
Step 2: Create the gMSA object with AES encryption enforced
New-ADServiceAccount -Name "gmsa-sql-prod" `
-DNSHostName "gmsa-sql-prod.corp.local" `
-PrincipalsAllowedToRetrieveManagedPassword "SQL-Host-Servers" `
-KerberosEncryptionType AES128,AES256 `
-ServicePrincipalNames "MSSQLSvc/sql-node-01.corp.local:1433", "MSSQLSvc/sql-node-02.corp.local:1433"
Step 3: Install and verify the gMSA on the application host
Run on SQL-Node-01:
Install-ADServiceAccount -Identity "gmsa-sql-prod"
Test-ADServiceAccount -Identity "gmsa-sql-prod" # Returns True if operational
- Domain-Wide RC4 Deprecation & AES Key Regeneration For legacy services that cannot migrate to gMSAs:
- Enforce passphrases of at least 30 characters using passphrases to resist offline dictionary attacks.
- Explicitly configure the msDS-SupportedEncryptionTypes attribute on user accounts to 0x18 (AES128 + AES256) or 0x10 (AES256 only) in accordance with Microsoft Learn Guidance.
- Reset the service account password after applying encryption attributes; Active Directory does not compute AES Kerberos keys until the account password is changed.
Canary Accounts (Honey SPNs) Security teams can deploy deception tripwires to achieve high-fidelity detection:
Create an unprivileged decoy user account (e.g., svc-backup-engine).
Assign a plausible SPN (e.g., BackupExec/backup01.corp.local).
Set a randomized 64-character password and restrict logon hours or assign an impossible logon workstation constraint.
Any KRB_TGS_REQ ticket request targeting this SPN represents an immediate, high-confidence alert indicating automated SPN enumeration and roasting.
Production-Grade Detection Engineering: Windows Security Event 4769 The primary domain controller telemetry source for Kerberoasting detection is Windows Event ID 4769 (A Kerberos service ticket was requested).
When constructing detection rules, analysts must evaluate:
- TicketEncryptionType: 0x17 (RC4-HMAC ticket request, indicating legacy exposure or deliberate downgrade).
- ServiceName: Exclude machine accounts (ending in $) and the Kerberos infrastructure ticket (krbtgt).
- TicketOptions: 0x40810000 or 0x40800000 (standard ticket options for client requests).
- Status: 0x0 (Successful ticket issuance).
Below is the production-grade Sigma rule for detecting suspicious RC4 ticket requests targeting user accounts.
title: Suspicious RC4 Kerberos Service Ticket Request (Kerberoasting)
id: d7e85764-7f8e-49b8-a72e-360cb2bc3829
status: production
description: |
Detects requests for Kerberos service tickets (TGS) utilizing weak RC4 encryption (0x17)
against user accounts holding Service Principal Names (SPNs). This behavior frequently
correlates with offensive Kerberoasting activity seeking offline password extraction.
references:
logsource:
product: windows
service: security
detection:
selection:
EventID: 4769
TicketEncryptionType: '0x17'
Status: '0x0'
filter_machine_accounts:
ServiceName|endswith: '$'
filter_krbtgt:
ServiceName: 'krbtgt'
filter_known_exclusions:
TargetUserName|startswith: 'HEALTHCHECK-'
condition: selection and not 1 of filter_*
fields:
Computer
TargetUserName
ServiceName
IpAddress
TicketOptions
TicketEncryptionType
falsepositives:
Legacy enterprise software running on pre-Windows Server 2008 platforms
Unix/Linux identity integrations lacking AES keytabs
level: high
tags:
attack.credential_access
attack.t1558.003
- Automated SIEM Log Correlation Engine In enterprise environments where legacy applications still legitimately request RC4 tickets, atomic alerting creates operational noise. Telemetry pipelines must correlate ticket request velocity across distinct SPNs originating from a single client IP or user account within a sliding inspection window.
#!/usr/bin/env python3
# Automated Kerberoasting Telemetry Correlator
# Evaluates normalized Windows Security Event 4769 records for multi-SPN harvesting velocity.
from collections import defaultdict
from datetime import datetime, timedelta
from typing import Dict, List, Optional, Set
class KerberoastDetector:
def __init__(self, velocity_threshold: int = 5, window_seconds: int = 300):
# velocity_threshold: Number of distinct SPNs requested to trigger alert
# window_seconds: Sliding inspection window in seconds (default: 5 minutes)
self.threshold = velocity_threshold
self.window = timedelta(seconds=window_seconds)
self.tracker: Dict[str, List[tuple]] = defaultdict(list)
def process_event(self, event: dict) -> Optional[dict]:
# Ingests and evaluates a single normalized Event ID 4769 record.
if event.get("EventID") != 4769:
return None
# Filter for successful ticket issuance (Status 0x0) with RC4 encryption (0x17)
if event.get("Status") != "0x0" or event.get("TicketEncryptionType") != "0x17":
return None
service_name = event.get("ServiceName", "")
# Filter out computer accounts and KDC service
if service_name.endswith("$") or service_name.lower() == "krbtgt":
return None
client_ip = event.get("IpAddress", "unknown")
timestamp_str = event.get("TimeCreated")
timestamp = datetime.fromisoformat(timestamp_str)
requesting_user = event.get("TargetUserName", "")
# Evict records falling outside the sliding inspection window
current_history = self.tracker[client_ip]
self.tracker[client_ip] = [
record for record in current_history if (timestamp - record[0]) <= self.window
]
# Record current event
self.tracker[client_ip].append((timestamp, service_name, requesting_user))
# Evaluate unique SPNs requested within the window
unique_spns: Set[str] = {record[1] for record in self.tracker[client_ip]}
if len(unique_spns) >= self.threshold:
alert_payload = {
"Alert": "High-Velocity Kerberoasting Anomaly Detected",
"Severity": "CRITICAL",
"ClientIP": client_ip,
"UniqueSPNCount": len(unique_spns),
"TargetedSPNs": list(unique_spns),
"RequestingAccount": requesting_user,
"WindowSeconds": self.window.total_seconds(),
"Timestamp": timestamp_str
}
# Clear tracker for client to prevent alert fatigue
self.tracker[client_ip].clear()
return alert_payload
return None
if name == "main":
detector = KerberoastDetector(velocity_threshold=3, window_seconds=120)
# Simulated stream of Event 4769 records from an unprivileged workstation
sample_stream = [
{"EventID": 4769, "Status": "0x0", "TicketEncryptionType": "0x17", "ServiceName": "MSSQLSvc/db01.corp.local", "IpAddress": "10.0.5.42", "TargetUserName": "jdoe", "TimeCreated": "2026-09-03T02:10:01"},
{"EventID": 4769, "Status": "0x0", "TicketEncryptionType": "0x17", "ServiceName": "HTTP/portal.corp.local", "IpAddress": "10.0.5.42", "TargetUserName": "jdoe", "TimeCreated": "2026-09-03T02:10:15"},
{"EventID": 4769, "Status": "0x0", "TicketEncryptionType": "0x17", "ServiceName": "HOST/hyperv.corp.local", "IpAddress": "10.0.5.42", "TargetUserName": "jdoe", "TimeCreated": "2026-09-03T02:10:30"},
]
for record in sample_stream:
alert = detector.process_event(record)
if alert:
print(f"[!] SIEM ALERT: {alert['Alert']}")
print(f" Source IP: {alert['ClientIP']} | Target Count: {alert['UniqueSPNCount']}")
print(f" Services Targeted: {', '.join(alert['TargetedSPNs'])}")
Fast Cyber Defense Key Takeaways
- Protocol Trust Design Remains the Primary Exposure: Kerberoasting does not rely on software vulnerabilities or memory flaws; it abuses standard Kerberos protocol specifications (RFC 4120). Any authenticated user can legitimately request service tickets for any registered SPN.
- Enforce Group Managed Service Accounts (gMSAs): The most resilient structural mitigation is replacing user-based service accounts with gMSAs. The KDC enforces 128-character high-entropy passwords that rotate every 30 days, rendering offline cracking computationally infeasible.
- Eradicate RC4-HMAC Across Active Directory: RC4-HMAC (0x17) bridges modern Kerberos authentication back to NTLM-grade security. Service accounts must be configured for AES-256 (0x12), and account passwords must be reset following configuration to generate AES key structures.
- Differentiate Attribute Bitmasks from Event Log Types: Avoid confusing 0x18 in the msDS-SupportedEncryptionTypes LDAP attribute (which represents hardened AES128 + AES256) with 0x18 in Windows Event ID 4769 (which denotes vulnerable export-grade RC4-HMAC-EXP).
- Deploy Canary SPNs for Zero-False-Positive Alerting: Creating decoy accounts with registered SPNs provides an immediate tripwire for detecting domain-wide reconnaissance and roasting activity.
- Implement Sliding-Window Velocity Analytics in the SIEM: In hybrid networks with legacy software dependencies, configure correlation logic to detect bursts of Event ID 4769 records for non-machine SPNs originating from identical client endpoints. References & Further Reading
- RFC 4120 - The Kerberos Network Authentication Service (V5)
- RFC 4757 - The RC4-HMAC Kerberos Encryption Types Used by Microsoft Windows
- Microsoft Learn - Detect and Remediate RC4 Usage in Kerberos
- Microsoft Security Blog - Guidance to Help Mitigate Kerberoasting
- SigmaHQ Rule Repository - Windows Security Suspicious RC4 Kerberos Ticket Request
Comments
Post a Comment