AD-INF-006: Trusts that let SIDs or TGTs through¶
high Infrastructure MITRE ATT&CK T1134.005, T1482 Reads: LDAP
A trust to another domain or forest lets SID history through or allows TGT delegation, so a compromise of the other side can be carried into this domain.
Also known as: sid-filtering
Why it matters¶
A trust is only as safe as the domain on the other side. Two settings decide whether an attacker who controls that domain can step into this one:
- SID filtering. When this domain trusts another one, the domain controllers filter the SIDs in tickets coming from it. With filtering off on an external trust, or with SID history enabled on a forest trust, an attacker who owns the trusted domain forges a ticket whose SID history contains the SID of a privileged group in this domain and is treated as a member of it. Forest trusts with SID history still drop RIDs below 1000, so the targets there are custom admin groups and accounts with rights over tier 0.
- TGT delegation across a forest trust. With delegation enabled, users of one forest who authenticate to a host with unconstrained delegation in the other forest leave their TGT there. An attacker who owns such a host in the trusted forest, and coerces a domain controller of this forest to authenticate to it (PrinterBug, PetitPotam), gets the DC's TGT and can DCSync this domain. This is why Microsoft disabled TGT delegation across forest trusts by default in 2019.
How ad-doctor detects it¶
ad-doctor reads the trustedDomain objects under CN=System and evaluates
trustAttributes and trustDirection for every trust that leaves the forest (trusts
with TRUST_ATTRIBUTE_WITHIN_FOREST, 0x20, are skipped):
| Trust | Reported when |
|---|---|
| External, outbound or two-way | TRUST_ATTRIBUTE_QUARANTINED_DOMAIN (0x4) not set: SID filtering disabled |
| Forest, outbound or two-way | TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL (0x40) set: SID history enabled |
| Forest, inbound or two-way | TRUST_ATTRIBUTE_CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION (0x800) set |
Each object is the partner name with the reason, for example
partner.example (external, SID filtering disabled).
Attributes and probes read
trustPartnertrustDirectiontrustTypetrustAttributes
Severity¶
Always high: each reported trust turns a compromise of the other domain or forest into a compromise of this one.
False positives and limits¶
- Migrations in progress. SID history is sometimes enabled on purpose while users are moved from one forest to another. Accept the finding with the planned end of the migration as the expiry (accepted risks), and disable it when the migration is over.
- Both sides under the same administrators. If the other domain is run by the same tier-0 team with the same controls, the trust adds less risk; it is still a path an auditor will want documented.
Fix¶
-
Review every trust that leaves the forest.
-
Remove trusts nothing uses any more. That is the strongest fix.
-
Re-enable SID filtering.
netdom trusthas no dry-run mode; run each option without a value first, which only displays the current state:
Use /quarantine on external trusts and /enablesidhistory:no on forest trusts.
4. Disable TGT delegation across forest trusts:
```
netdom trust corp.example /domain:partner.example /enabletgtdelegation:no
```
- Remove unconstrained delegation on both sides of the trust (AD-DEL-001) and stop the spooler on DCs (AD-INF-009), which removes the coercion half of the TGT attack.
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-INF-006"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
Specifications
Research
- Active Directory forest trusts part 1: how does SID filtering work? (Dirk-jan Mollema)
- Not a Security Boundary: Breaking Forest Trusts (SpecterOps)
MITRE ATT&CK
Available since 0.1.0.