AD-ACC-012: pwdLastSet newer than the real password change on tier-0 accounts¶
medium high Accounts MITRE ATT&CK T1098 Reads: LDAP
On krbtgt or a tier-0 account, pwdLastSet is later than the time replication metadata gives for the last write of unicodePwd, so the password is older than it looks.
Also known as: fake-pwdlastset
Why it matters¶
pwdLastSet is not a record of a password change. Anyone who may write it can set it to 0
and then to -1, and the directory stores the current time, while the password stays the
same. A stolen password or a krbtgt key an attacker holds then looks freshly rotated, and
every age check that trusts the attribute goes quiet.
A real password change writes unicodePwd. Replication metadata records when that attribute
was last written, and that time cannot be moved the same way.
How ad-doctor detects it¶
For krbtgt, the built-in Administrator, domain controllers and every account in a tier-0
group, ad-doctor asks for msDS-ReplAttributeMetaData in the BASE read of the account it
makes anyway. The attribute is constructed, so a subtree search cannot return it, and the
cost stays limited to tier 0. An ordinary domain user could read it on every account tried in
the lab, krbtgt included.
An enabled account (and krbtgt, which is always disabled) is listed when pwdLastSet is
more than 5 seconds later than the last originating change of unicodePwd. That is the
rounding tolerance PingCastle's FakePasswordChangeDetector uses. The other direction is
not reported: the built-in Administrator of a new forest has a pwdLastSet from before the
promotion.
AD-KRB-001, AD-ACC-011 and the password part of
AD-KRB-005 use the older of the two times. If the metadata does not come back
for an account, the scan names it in a note, and its age checks fall back on pwdLastSet.
Accounts outside tier 0 are not read, so their pwdLastSet is still taken at face value.
Attributes and probes read
pwdLastSetmsDS-ReplAttributeMetaData (unicodePwd, BASE read of tier-0 accounts)
Severity¶
High for krbtgt: nobody has a routine reason to touch its pwdLastSet, and its age is
what limits forged tickets. Medium for other tier-0 accounts, where an administrator
clearing User must change password at next logon has the same effect.
False positives and limits¶
- "User must change password at next logon" ticked and cleared. Both steps write
pwdLastSetonly. On an admin account it is still worth knowing: the password did not change.
Fix¶
-
Find out when and where it was written (read-only):
Get-ADReplicationAttributeMetadata -Object (Get-ADUser adm_bob) -Server dc01 ` -Properties pwdLastSet, unicodePwdEvent 4738 on that DC, at that time, names the account that made the change.
-
Really change the password. For
krbtgt, rotate it twice, waiting for replication in between. -
Treat an unexplained case as an incident: someone hid the age of a tier-0 password.
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-ACC-012"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Specifications
Tools
MITRE ATT&CK
New in the next release.