AD-ACC-007: Accounts with SID history¶
medium high Accounts MITRE ATT&CK T1134.005 Reads: LDAP
Enabled accounts carry sIDHistory, which adds the old SIDs to every logon token; privileged or same-domain SIDs there are a persistence backdoor.
Also known as: sid-history
Why it matters¶
sIDHistory exists so that a user migrated from another domain keeps access to resources
that still name the old SID. Every SID in it is added to the account's Kerberos PAC and
access token at each logon, exactly as if the account were a member of that principal.
Attackers who once held Domain Admin rights use it for persistence: with Mimikatz
(sid::add) or DSInternals (Add-ADDBSidHistory, offline on ntds.dit) they write the
SID of Domain Admins or of the built-in Administrator into an ordinary account. That
account appears in no admin group and has no adminCount, yet logs on as an
administrator. A SID from the same domain never comes from a real migration, which
is why the check treats it as high.
Across trusts, SID filtering normally strips foreign SIDs; trusts that let SID history through are reported by AD-INF-006.
How ad-doctor detects it¶
From the LDAP snapshot: every enabled account (users and computers) with at least one
value in sIDHistory. The binary SIDs are converted to strings and compared with the
domain SID read from the domain head.
The detail lists the accounts with privileged or same-domain SIDs; each object is a
sAMAccountName, for example mig_user.
Attributes and probes read
sIDHistoryobjectSid of the domainuserAccountControl
Severity¶
High when at least one reported account has a SID in sIDHistory that ends in
-500 (Administrator), -512 (Domain Admins), -518 (Schema Admins) or -519
(Enterprise Admins) in any domain, is S-1-5-32-544 (Administrators), or belongs to the
scanned domain itself. Medium when every SID found looks like an ordinary leftover of
a migration from another domain.
False positives and limits¶
- Migrations in progress. Accounts migrated with ADMT keep SID history until resource ACLs are translated. Those are medium findings; record them in an accepted-risk file with an expiry date that matches the end of the migration.
- A high finding can come from a migration (the old domain's Domain Admins SID), but the account is still an admin wherever that old SID is honoured, so fix it rather than accept it.
Fix¶
-
List every account with SID history (read-only):
-
Treat high findings as a possible compromise. Find when the value was written and from where: event 4765 (SID History was added to an account) on the DCs, and the replication metadata:
Then reset the account's password and look for other persistence.
-
Remove the SID history once resource ACLs no longer need it. To remove one SID:
or all of them (what ad-doctor fix generates; use Set-ADComputer for a computer):
```powershell
Set-ADUser mig_user -Clear sIDHistory -WhatIf
```
- Keep SID filtering on for every trust (see AD-INF-006).
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-ACC-007"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
Specifications
Research
- Sneaky Active Directory Persistence #14: SID History (Sean Metcalf)
- Active Directory forest trusts part 1: How does SID filtering work? (Dirk-jan Mollema)
MITRE ATT&CK
Available since 0.1.0.