ADKERB-010: Kerberos Ticket Lifetime
- Platform
- Active Directory
- Category
- AD Kerberos Security
- Severity
- Medium
- Zero Trust pillar
- Identity (weight 3)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
The check binds to the domain root (defaultNamingContext) and reads the five Kerberos policy attributes that are written by Default Domain Policy and exposed on the domain object: maxTicketAge (TGT lifetime, hours), maxServiceAge (TGS lifetime, minutes), maxRenewAge (renewal window, days), maxClockSkew (allowable KDC-client clock drift, minutes), and ticketValidateClient (boolean, enforces user logon restrictions). These map one-to-one to the GPO settings under Computer Configuration > Policies > Windows Settings > Security Settings > Account Policies > Kerberos Policy. The check also enumerates membership in the Protected Users group (objectSid ending in -525) because that group automatically caps TGT lifetime at 4 hours and disables NTLM, delegation, DES, RC4, and cached credentials for its members, overriding the domain-wide policy for the highest-value accounts. Findings are raised when: (a) maxTicketAge is greater than 10 hours or equal to 0, (b) maxServiceAge is greater than 600 minutes or equal to 0, (c) maxRenewAge is greater than 7 days, (d) maxClockSkew is greater than 5 minutes (widens the replay window for captured tickets), or (e) Tier 0 accounts (Domain Admins, Enterprise Admins, Schema Admins, Administrator, krbtgt) are absent from Protected Users while the domain lifetime exceeds 4 hours.
Why it matters
Every Kerberos ticket carries an encrypted authorization payload (the PAC) signed with the krbtgt key (for TGTs) or the target service key (for TGS). The ticket is bearer-grade: any process that can present the ticket to the target service authenticates as the principal in the ticket, regardless of where the ticket came from. This makes ticket lifetime a direct measure of post-compromise dwell time. A 10-hour TGT extracted from LSASS at 09:00 is usable until 19:00 the same day, then renewable for up to 7 days without ever touching the user password again. Raising the TGT lifetime to 24 hours doubles the window; setting it to 0 (no expiration) is functionally equivalent to a golden ticket for the lifetime of the krbtgt key. The 5-minute clock skew defines the replay window for any captured ticket against systems with skewed clocks, and is the upper bound on how much time can elapse between ticket capture and rejection by the KDC for being out of date. Mimikatz sekurlsa::tickets, Rubeus dump, and Impacket ticketer all produce ticket material whose useful lifetime is bounded entirely by these five attributes. Tier 0 accounts are particularly sensitive: a Domain Admin TGT that lives for 10 hours and renews for 7 days is a 168-hour lateral movement window from a single LSASS scrape. Protected Users membership caps that at 4 hours with no renewal and forces AES, materially shrinking the blast radius without changing any password.
Attack path
Step 1: Foothold and credential access. The attacker compromises a workstation where a privileged user has an interactive session, a saved RDP credential, or a Kerberos ticket in LSASS. Tools: Mimikatz (sekurlsa::tickets /export), Rubeus dump /service:krbtgt, or Cobalt Strike mimikatz. The output is a set of .kirbi files, each containing a TGT or TGS for the cached principal. Step 2: Ticket inventory. The attacker enumerates the lifetime field on each captured ticket using Rubeus describe /ticket:<base64> or klist. Tickets whose endtime is hours or days in the future are higher value than tickets near expiry. In a domain where maxTicketAge has been raised to 24 hours, every harvested TGT is usable for the full remainder of that 24-hour window. Step 3: Lateral movement via pass-the-ticket. The attacker injects the harvested TGT into a logon session on an attacker-controlled host using Rubeus ptt /ticket:<file.kirbi> or Mimikatz kerberos::ptt. Subsequent SMB, WinRM, LDAP, and MSSQL connections from that session present the injected TGT to the KDC and receive valid TGS tickets for any service the principal can reach. No password, no NTLM hash, no AS-REQ traffic, no Event 4625. Step 4: Renewal for persistence. Before the TGT endtime expires, the attacker calls KRB_TGS_REQ with the RENEW flag set. The KDC validates that current_time is less than renew_till (maxRenewAge from policy) and reissues the TGT with a fresh endtime. With the default 7-day renewal window, a single harvest provides a week of authenticated access; with a misconfigured 30-day renewal, a month. Rubeus renew /ticket:<file.kirbi> /autorenew automates this. Step 5: Persistence escalation. If the attacker obtained the krbtgt hash (DCSync via T1003.006, or NTDS.dit theft), they forge a golden ticket with mimikatz kerberos::golden /aes256:<krbtgt> /user:any /id:500 /groups:512,513,518,519,520 /endin:600 /renewmax:10080 /ptt. The /endin and /renewmax parameters are bounded only by the attacker preference (the KDC does not validate them against domain policy on the forged TGT until the next TGT renewal). On a domain with a permissive policy or no enforcement of Protected Users, the golden ticket is effectively perpetual. Step 6: Clock skew abuse. Where maxClockSkew has been widened beyond 5 minutes to accommodate poor time synchronization, captured TGS tickets remain valid for replay over a longer window. An attacker who captures a ticket via SMB relay or memory dump and replays it against a target with a skewed clock has additional time before the KDC rejects it as stale.
How Guerrilla assesses it
Guerrilla connects to the closest writable domain controller via LDAP and reads the five Kerberos policy attributes from the domain root object using an LDAP search with base = defaultNamingContext, scope = base, attributes = maxTicketAge, maxServiceAge, maxRenewAge, maxClockSkew, ticketValidateClient. These attributes are populated by the Default Domain Policy GPO via the gPLink on the domain head and are the authoritative runtime values used by the KDC. The check converts the raw values (which are stored as negative 100-nanosecond intervals in the directory) to human-readable units before evaluation. It then enumerates members of the Protected Users group (CN=Protected Users,CN=Users,<DN>; objectSid ending -525) and cross-references against the well-known Tier 0 group memberships (Domain Admins -512, Enterprise Admins -519, Schema Admins -518, Administrators -544, krbtgt -502). A finding is raised when any of the lifetime thresholds is exceeded, when a value is 0 (no expiration), when maxClockSkew exceeds 5 minutes, or when Tier 0 principals are missing from Protected Users while domain TGT lifetime exceeds 4 hours. The check is read-only and does not require Domain Admin rights: authenticated user is sufficient because the policy attributes on the domain head are world-readable.
Recommended value
TGT maximum lifetime: 4-10 hours. Service ticket maximum lifetime: 600 minutes. Maximum ticket renewal: 7 days. Maximum clock skew: 5 minutes
Remediation
Configure Kerberos policy in Default Domain Policy: Computer Configuration > Policies > Windows Settings > Security Settings > Account Policies > Kerberos Policy. Set maximum lifetime for service ticket (600 minutes), maximum lifetime for user ticket (10 hours or less), and maximum lifetime for user ticket renewal (7 days). For Tier 0 accounts, add them to the Protected Users group which automatically enforces a 4-hour TGT lifetime
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- AC-12
- CIS AD Benchmark
- 7.5.1