SIDHistory: the migration legacy that can hide privileges
Years after a domain consolidation or a cross-forest migration, many accounts still carry old SIDs in their SIDHistory attribute. Nobody knows any more whether they are needed. And among these inherited values, a privileged SID added by an attacker would easily go unnoticed.
What SIDHistory is for
When an account is migrated from one domain to another, it gets a new security identifier (SID). But permissions on shares, files and applications in the old domain reference the old SID. So that the user keeps access during the transition, migration tools copy the old SID into the new account's sIDHistory attribute. At logon, the SIDs in the history are added to the user's token, exactly as if they were still a member of the old domain.
It is a transition mechanism. Once permissions have been translated to the new SIDs, it has no reason to remain.
Why it is a persistence vector
Because every SID in the history is added to the token, placing the SID of a privileged group (Domain Admins, Enterprise Admins) in sIDHistory gives its rights to a seemingly ordinary account, without it appearing in the group's member list. The attribute cannot be changed through a plain LDAP write: it requires either the migration interfaces or domain controller-level access. It is therefore a post-compromise persistence technique, designed to survive a cleanup of privileged groups. Tools that only look at group membership miss it.
Auditing accounts with a history
- List every user, group and computer with a populated
sIDHistoryattribute. - For each value, identify the source domain from the domain part of the SID. A SID belonging to the current domain is abnormal: a migration brings in SIDs from another domain.
- Look for well-known privileged SIDs, especially those whose relative identifier matches an admin group (512, 518, 519, or 544 for Administrators).
- Check whether the source domains still exist and whether trusts lead to them.
Domain controllers log the addition of a SID to the history (event 4765) and failed attempts (event 4766) when account management auditing is enabled. Outside a planned migration, these events should trigger an investigation.
Cleaning up after a migration
Cleanup follows a simple logic: translate first, remove second. Migration and security translation tools replace old SIDs with new ones in the ACLs of file servers, profiles and applications. Once that translation has been done and verified, sIDHistory values can be removed by script, in batches, keeping an export so you can restore any forgotten access. Work population by population, watch for access-denied requests for a few weeks, then generalise.
The role of SID filtering. On a trust, SID filtering strips from tokens any SIDs that do not belong to the trusted domain or forest. It is on by default for external trusts and forest trusts. Disabling it, or explicitly allowing SID history on a forest trust to ease a migration, lets an administrator of the trusted forest inject privileged SIDs from your forest. Any exception must be temporary and documented.
What an audit checks
- the number of accounts with a
sIDHistoryand their source domains; - privileged SIDs or SIDs from the current domain in the history;
- the status of SID filtering and the SID history option on every trust;
- logging and monitoring of events 4765 and 4766.