ADPRIV-022: krbtgt Password Age

Platform
Active Directory
Category
AD Privileged Account Security
Severity
Critical
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 default naming context of every domain in the forest and resolves the well-known krbtgt account (CN=krbtgt,CN=Users,DC=<domain>; RID 502; objectSid S-1-5-21-<domain>-502). For each domain it reads pwdLastSet, whenChanged, msDS-KeyVersionNumber (the kvno used by the KDC), msDS-SupportedEncryptionTypes, and userAccountControl. The age of the password is computed as (now - pwdLastSet) in days. Guerrilla raises a Critical finding when pwdLastSet is older than 180 days, a High finding between 90 and 180 days, and an informational baseline below 90 days. The check additionally enumerates every read-only domain controller (RODC) and inspects each RODC-specific krbtgt account (krbtgt_<NumericSuffix>) under the same logic, because each RODC has its own krbtgt principal with an independent rotation schedule. msDS-KeyVersionNumber is captured so operators can determine whether the account has been reset once (kvno incremented by 1) or twice (kvno incremented by 2 with sufficient replication delay between the two resets); a single increment after a known compromise indicates the rotation procedure was not completed correctly and outstanding Golden Tickets may still validate.

Why it matters

The krbtgt key is the root of trust for Kerberos in the domain. A TGT is encrypted with the krbtgt key, and the KDC validates an inbound TGT by decrypting it with the same key; the KDC performs no further check on whether the TGT was actually issued by a real authentication event. An attacker who reads the krbtgt hash (typically via DCSync against any account holding Replicating Directory Changes All, or via offline NTDS.dit extraction from a backup, or via lsass memory on a domain controller) can forge a Golden Ticket containing any sAMAccountName, any SID, any group membership (Domain Admins, Enterprise Admins, the Builtin Administrators alias S-1-5-32-544, the Schema Admins SID), and any lifetime up to ten years. The forged ticket is indistinguishable from a real TGT at the protocol level. Until the krbtgt password is rotated twice, every TGT ever forged against the prior key (or any prior key still cached in the KDC) remains valid for its embedded lifetime. The double rotation is mandatory because the KDC keeps the previous krbtgt key in memory to validate in-flight tickets across a password change; a single reset only invalidates the key two generations old, not the one the attacker holds. Real-world dwell time for Golden Ticket persistence has been measured in years (Mandiant M-Trends 2022 documents intrusions where the same forged TGT was reused across multiple incident-response engagements because the victim reset krbtgt only once). The blast radius is the entire forest, and remediation requires either two timed resets or a forest recovery.

Attack path

Step 1: Obtain the krbtgt hash. The most common path is DCSync from any principal holding the Replicating Directory Changes (DS-Replication-Get-Changes, 1131f6aa-9c07-11d1-f79f-00c04fc2dcd2) and Replicating Directory Changes All (DS-Replication-Get-Changes-All, 1131f6ad-9c07-11d1-f79f-00c04fc2dcd2) extended rights on the domain head. mimikatz lsadump::dcsync /domain:contoso.local /user:krbtgt or secretsdump.py contoso/admin@dc01.contoso.local -just-dc-user krbtgt returns the NTLM hash, the AES128 key, the AES256 key, and the current kvno. Alternative paths include offline extraction from an NTDS.dit backup (ntdsutil snapshot, exported and parsed with secretsdump -ntds), lsass dumping on a DC (procdump -ma lsass.exe followed by mimikatz sekurlsa::krbtgt), or abuse of the print spooler or other DC-coercion primitives to relay to ADCS for a DC certificate that authorizes DCSync. Step 2: Forge the Golden Ticket. The attacker runs mimikatz kerberos::golden /user:Administrator /domain:contoso.local /sid:S-1-5-21-1234567890-1234567890-1234567890 /krbtgt:<NTLM hash> /id:500 /groups:512,513,518,519,520 /ptt, or Rubeus.exe golden /aes256:<aes256 key> /user:fakeuser /id:500 /domain:contoso.local /sid:S-1-5-21-... /nowrap. The forged TGT can specify any user (including non-existent ones, because the KDC does not validate the embedded PAC against the directory on TGS-REQ), any group set, and a lifetime up to ten years. AES256 keys are preferred over RC4 because RC4-encrypted TGTs are increasingly logged as anomalous by Microsoft Defender for Identity and modern SIEM analytics. Step 3: Inject and use. The /ptt switch loads the forged TGT into the current logon session. The attacker then requests service tickets for any resource (TGS-REQ to the KDC), and the KDC issues them based purely on the PAC inside the forged TGT. Common follow-on actions: dir \\DC01\C$, PsExec.exe \\DC01 cmd, DCSync of every account, creation of a backdoor service account in Domain Admins, modification of AdminSDHolder. Step 4: Persistence. The Golden Ticket survives password resets on all targeted user accounts, deletion of the impersonated user, group membership changes, and account disablement, because the KDC trusts the PAC inside the TGT without revalidation. The only way to invalidate the ticket is to rotate the krbtgt key. Critically, a single rotation does NOT invalidate the ticket: the KDC retains the previous krbtgt key (the N-1 key) to handle in-flight tickets across the password change. The attacker holds the N key from before the rotation, which becomes the N-1 key after one rotation and is still accepted. Only after a second rotation, with sufficient time between the two for replication to converge, does the attackers key fall out of the KDC ring and the Golden Ticket cease to validate. Step 5: Living off the trust. Mature operators register a one-time scheduled task or WMI subscription that re-injects the forged ticket on demand, or store the krbtgt material in an out-of-band C2 channel for re-use months later if initial access is lost. Because the krbtgt password is opaque and rarely rotated, the same forged TGT often remains valid across multiple incident-response engagements.

How Guerrilla assesses it

Guerrilla performs an LDAP search against the default naming context of every domain in the forest with the filter (sAMAccountName=krbtgt) and the attribute set [pwdLastSet, whenChanged, msDS-KeyVersionNumber, msDS-SupportedEncryptionTypes, userAccountControl, objectSid]. pwdLastSet is a Windows FILETIME and is converted to a UTC DateTime, then differenced against the current time to produce age-in-days. The check then enumerates every RODC via Get-ADDomainController -Filter {IsReadOnly -eq $true} and resolves each per-RODC krbtgt account (sAMAccountName matching krbtgt_*) to compute its own age. Findings are emitted per-account: the domain krbtgt over 180 days raises Critical, RODC krbtgt accounts over 180 days raise High (smaller blast radius, limited to the RODCs replication scope). msDS-KeyVersionNumber is captured to support post-incident review: if the operator reports a compromise on date X but kvno has only incremented by 1 since date X, the two-step rotation was not completed and outstanding Golden Tickets may still be valid. The check does not require any rights beyond authenticated-user read on the directory; pwdLastSet is world-readable.

Recommended value

krbtgt password changed within the last 180 days. Rotated twice (to invalidate all existing tickets) after any suspected compromise

Remediation

Check krbtgt password age using Get-ADUser krbtgt -Properties PasswordLastSet. Reset the password twice (with sufficient time between resets for replication to complete) to invalidate all existing tickets. Use the krbtgt reset script from Microsoft to safely perform the rotation. Schedule regular rotation every 180 days

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.

Verdict scenarios for ADPRIV-022
ScenarioExpected verdict
cleanPASS
known-badFAIL
throttledNot Assessed

Framework mappings

NIST SP 800-53
IA-5(1), SC-12
CIS Benchmark
18.3.1
ANSSI
R39
CIS AD Benchmark
4.8.1
MITRE ATT&CK
T1558.001, T1550.003