Work in progress
SID Filtering Bypass
Spoofing a domain SID to smuggle privileged SIDs across a forest trust
Theory
SID filtering is what makes the forest, rather than the domain, the security
boundary: SIDs that do not belong to the trusted domain are stripped from
authorisation data crossing the trust. See
SID filtering for the mechanics and
the trustAttributes flags that govern it.
The filtering is not absolute. A few SIDs are (almost) never filtered:
the "Enterprise Domain Controllers" (S-1-5-9) SID and those described by the trusted domain object (TDO), as well as seven well-known SIDs (see the MS-PAC doc and improsec's post).
Anything that gets a privileged SID into that unfiltered set, or that makes the trusting forest treat an attacker-chosen SID as belonging to the trusted forest, bypasses the boundary.
Practice
CVE-2020-0665
CVE-2020-0665 bypasses SID filtering to authenticate as a server in the trusting forest, targeting that server's local administrator (RID 500).
The local domain SID of the target server is spoofed to fake a child domain in the trusted forest. After 24 hours that SID is added to the list of trusted SIDs in the trusting forest domain's TDO. A referral ticket is then forged with the spoofed SID as an extra SID and used to request a service ticket to that server.
The attack runs in three steps:
- Get the target server's local domain SID. Uses MS-LSAT RPC to query the server. This requires Windows older than build 1607 (or pre-Server 2016); newer versions restrict it and require administrative privileges on the target.
- Spoof that local domain SID. Must run as
SYSTEMon the trusted forest's domain controller. The published Frida script targets Windows Server 2016 1607; other versions need different address offsets and extra preparation. - Forge the ticket. See Kerberos authentication for which trust key applies, then follow Forging tickets across trusts.
Preconditions for reproducing this:
- full control over the trusted forest
- the ability to modify information flowing to the trusting forest
- at least one server joined to a domain in the trusting forest
For how this works underneath, see dirkjanm.io by Dirk-jan Mollema.