ADTRUST-002: Trust Direction Analysis
- Platform
- Active Directory
- Category
- AD Trust Relationships
- Severity
- Medium
- Zero Trust pillar
- Identity (weight 1)
- Golden fixtures
- 3
- Branch coverage
- Observed: fixtures prove the verdicts they exercise
- Provenance
- baseline
What it checks
The check binds to the System container of every domain naming context in the forest and enumerates objects of class trustedDomain. For each object it reads trustDirection (1 = inbound/trusting, 2 = outbound/trusted, 3 = bidirectional), trustType (1 = downlevel/Windows NT, 2 = uplevel/Active Directory, 3 = MIT Kerberos realm, 4 = DCE), trustAttributes (bitmask covering TRUST_ATTRIBUTE_NON_TRANSITIVE 0x1, TRUST_ATTRIBUTE_UPLEVEL_ONLY 0x2, TRUST_ATTRIBUTE_QUARANTINED_DOMAIN 0x4 which represents SID filtering on external trusts, TRUST_ATTRIBUTE_FOREST_TRANSITIVE 0x8, TRUST_ATTRIBUTE_CROSS_ORGANIZATION 0x10 which represents selective authentication, TRUST_ATTRIBUTE_WITHIN_FOREST 0x20, TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL 0x40, TRUST_ATTRIBUTE_USES_RC4_ENCRYPTION 0x80, TRUST_ATTRIBUTE_PIM_TRUST 0x400), trustPartner (the remote DNS or NetBIOS name), securityIdentifier (the partner domain SID), and whenCreated / whenChanged. The check classifies every trust with trustDirection 1 or 3 as an inbound authentication path and cross-references trustAttributes for the absence of TRUST_ATTRIBUTE_QUARANTINED_DOMAIN on external trusts and the absence of TRUST_ATTRIBUTE_CROSS_ORGANIZATION on forest trusts. A finding is raised on every inbound or bidirectional trust along with the partner identity, age, SID-filter state, and selective-authentication state so the operator can assess whether the trust is required and whether it is appropriately hardened.
Why it matters
Trust direction defines who can authenticate into the local domain. An outbound-only trust (trustDirection 2) lets local users reach resources in the partner, but the partner cannot authenticate principals into the local domain; the attack surface added to the local domain is essentially zero. An inbound trust (direction 1) or bidirectional trust (direction 3) reverses this: every principal in the partner is a candidate identity for KDC referrals, NTLM pass-through, and resource access against the local domain. The blast radius of a compromised partner therefore extends into the local domain whenever the trust is inbound or bidirectional. The risk is not theoretical: bidirectional trusts have been the lateral-movement vector in multiple publicly documented intrusions, because attackers who gain Domain Admin in any trusted domain (often a smaller subsidiary, a lab forest, or a partner organization) can use that foothold to forge cross-realm tickets, replay NTLM, or inject SID history against the trusting domain. Where SID filtering (TRUST_ATTRIBUTE_QUARANTINED_DOMAIN on external, TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL on forest) is not enabled, an attacker with KRBTGT or trust-key material on the trusted side can craft tickets containing arbitrary SIDs from the trusting domain, escalating to Enterprise Admin equivalence with no further compromise. Sean Metcalf has documented that the AD forest, not the domain, is the security boundary precisely because of these trust-traversal primitives. Reducing bidirectional trusts to one-way and pruning unjustified inbound trusts directly shrinks this surface.
Attack path
Step 1: Trust discovery. The attacker, holding any authenticated foothold, enumerates trusts (MITRE T1482) using nltest /domain_trusts /all_trusts, Get-ADTrust -Filter *, or BloodHound's GetDomainTrusts collection. The output reveals which partners have inbound or bidirectional trusts into the target domain, the trustAttributes bitmask, and whether SID filtering is in place. Step 2: Pivot target selection. The attacker identifies the weakest trusted partner. Common picks are subsidiary domains, acquired companies, lab or test forests joined to production, and partner-organization trusts left over from past projects. A trust is exploitable from the trusted side, so any partner where the attacker can reach Domain Admin or KRBTGT becomes a path back into the trusting domain. Step 3: Trusted-domain compromise. Standard attacks on the partner (Kerberoasting, AS-REP roasting, ADCS abuse, GPO abuse, ACL abuse) are used to escalate to KRBTGT or to the inter-realm trust key (stored on each side as TDO secret material). Step 4: Cross-realm ticket forge. With the inter-realm trust key, the attacker uses Mimikatz (kerberos::golden /sids:) or Rubeus to forge a referral TGT for the trusting domain. On bidirectional or non-SID-filtered trusts, the attacker injects extra SIDs into the ExtraSids field of the PAC (MITRE T1134.005, SID-History Injection), including the Enterprise Admins SID (S-1-5-21-<root>-519) of the trusting forest. Step 5: Authentication into trusting domain. The forged ticket is presented to a domain controller in the trusting domain. Because the trust is inbound or bidirectional, the local KDC accepts the cross-realm referral. Because SID filtering is absent, the injected SIDs are honored, granting the attacker Enterprise Admin equivalence in the trusting forest. Step 6: Persistence. The attacker may also use Trust Modification (MITRE T1484.002) to add new trusts, weaken trustAttributes, or convert an outbound trust to bidirectional to preserve access. Trust modifications appear as edits to the trustedDomain object and are visible in Event ID 4716 (Trusted domain information was modified).
How Guerrilla assesses it
Guerrilla retrieves the list of domains in the forest via Get-ADForest, then for each domain binds to CN=System,<domain DN> over LDAP and runs (objectClass=trustedDomain). For each returned object the check pulls trustDirection, trustType, trustAttributes, trustPartner, securityIdentifier, flatName, whenCreated, and whenChanged. trustDirection is decoded as 1 inbound, 2 outbound, 3 bidirectional, 0 disabled. trustAttributes is decoded bitwise to surface non-transitive trusts, forest-transitive trusts, SID-filter state (QUARANTINED_DOMAIN for external trusts, TREAT_AS_EXTERNAL for forest trusts where appropriate), selective authentication (CROSS_ORGANIZATION), RC4-only trust keys (USES_RC4_ENCRYPTION, which is a separate hardening miss), and PIM trusts. The check also reads msDS-TrustForestTrustInfo where present to enumerate name-suffix routing on forest trusts. Every trust with direction 1 or 3 is reported as an inbound authentication path. The finding payload includes the partner DNS name, trust type, age in days, last-modified timestamp, SID-filter state, selective-authentication state, and a derived classification of whether the trust is intra-forest (no security boundary), external one-way outbound (low risk), external inbound (medium), bidirectional external (high) and so on. Operators reviewing the finding can match each trust against documented business justification and either remove, convert to one-way, or harden with SID filtering and selective authentication.
Recommended value
All trust directions justified and documented. Bidirectional trusts converted to one-way where possible to reduce attack surface
Remediation
Review each trust direction using Get-ADTrust -Filter *. For bidirectional trusts, evaluate whether both directions are required. Convert to one-way trusts where the business need only requires one direction. Document the justification for all inbound trust paths
Fixture-proven verdicts
Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.
| Scenario | Expected verdict |
|---|---|
| clean | PASS |
| known-bad | FAIL |
| throttled | Not Assessed |
Framework mappings
- NIST SP 800-53
- AC-20, AC-4
- CIS AD Benchmark
- 3.1.2
- MITRE ATT&CK
- T1482, T1078.002