With a service account’s password hash, an attacker can craft a service ticket (TGS) for that service without ever contacting the KDC. The target service accepts it, and the Domain Controller logs nothing. Detection therefore compares the service host’s view with the DC’s view and looks for tickets that arrived with no matching request.
Signals at a Glance
| Signal | Where | ATT&CK |
|---|---|---|
| Kerberos network logon on a service host with no 4769 at any DC beforehand | Host 4624 + DC 4769 | T1558.002 |
| RC4 service ticket for an account configured for AES | Host 4624, DC 4769 | T1558.002 |
| Unexpected domain-name casing or empty fields in 4624 | Host Security 4624 | T1558.002 |
| Logon for a username that does not exist in AD | Host 4624 + AD lookup | T1558.002 |
| Service account password unchanged for years | AD attribute audit | T1558.002 |
Correlating the Gap
A normal Kerberos service logon is preceded by a TGS request: Event 4769 on a DC for that user and service. A forged ticket skips it. Collect Kerberos network logons (Event 4624, logon type 3) on member servers and anti-join them against DC 4769 events in a short window. The match key is approximate, so treat results as leads:
let window = 10m;
let tgs = SecurityEvent
| where EventID == 4769 and Status == "0x0"
| extend user = tolower(tostring(split(TargetUserName, "@")[0]))
| extend svc = tolower(trim_end("\\$", ServiceName))
| project TgsTime = TimeGenerated, user, svc;
SecurityEvent
| where EventID == 4624 and LogonType == 3 and AuthenticationPackageName == "Kerberos"
| where TargetUserName !endswith "$" and TargetUserName != "ANONYMOUS LOGON"
| extend user = tolower(TargetUserName), svc = tolower(tostring(split(Computer, ".")[0]))
| join kind=leftanti (tgs) on user, svc
| where Computer !in (dynamic(["DC01.corp.local","DC02.corp.local"]))
| project TimeGenerated, Computer, TargetUserName, IpAddress, WorkstationName
// tune/validate: widen the window to cover ticket reuse (tickets live ~10 hours);
// the cleaner design is a stateful join over a rolling cache of recent 4769.
Ticket reuse is the main false-positive source. A user who obtained a TGS hours ago will log on again without a new 4769, so the correlation window and a per-user ticket cache matter more than the query itself.
Anomalies and Hardening
Forged tickets often carry odd values that real clients never produce, and the forging depends on a stale service-account key. Verify both, starting with the account attributes:
# tune/validate: review service accounts with old keys or RC4 allowed
Get-ADUser -Filter 'servicePrincipalName -like "*"' `
-Properties PasswordLastSet, 'msDS-SupportedEncryptionTypes' |
Select-Object SamAccountName, PasswordLastSet, 'msDS-SupportedEncryptionTypes' |
Where-Object { $_.PasswordLastSet -lt (Get-Date).AddYears(-1) }
- Compare 4624 Kerberos logons that show a lowercase or mismatched domain name, or a username with no matching AD object.
- Enable PAC validation behaviour that Microsoft documents for your server versions, and keep Domain Controllers patched so ticket signatures are enforced.
- Replace user-based service accounts with gMSAs; a silver ticket against a gMSA fails to be useful because the key rotates.
- Where a service runs as a computer account, remember the key rotates every 30 days by default, which limits the forged ticket’s life.
Use the SigmaHQ and Elastic Kerberos rules, the Splunk ESCU forged-ticket analytics, Microsoft’s Kerberos PAC hardening notes and Trimarc service-account guidance. Baseline your own environment — ticket reuse, clock skew and cross-domain referrals all create 4624 events with no nearby 4769 and must be tuned out.
Build Detections That Fire
Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.
- Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
- Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
- 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Stay ahead of emerging threats. Get notified when we publish new intelligence reports and advisories.
Subscribe to Alerts