Back to blog
Mar 20267 min read

Trust is a Graph Problem

Active Directory trusts visualised as attack paths

Active Directory trusts are edges in an attack graph. Every trust relationship between domains is a potential lateral movement path. Bidirectional trusts double the attack surface. Transitive trusts chain together into paths that nobody intended to exist. If you're not thinking about trusts as graph traversal, you're missing paths.

Trust Types as Attack Edges

Not every trust is created equal. The type determines how you can traverse it, what authentication flows across it, and what protections exist at the boundary.

Trust TypeDirectionTransitiveSID Filtering
Parent-ChildBidirectionalYesOFF
ForestBidirectionalYesON
ExternalOne-way or BiNoON
ShortcutOne-way or BiYesOFF

Parent-child trusts are the most abusable. SID filtering is off by default, which means if you compromise a child domain, you can forge a golden ticket with the Enterprise Admins SID from the parent and own the entire forest. One child domain falls, everything falls.

Enumerating the Trust Map

You can query trusts manually with nltest or Get-ADTrust, but that only shows trusts from the domain you are sitting in. In a multi-forest environment with nested child domains, you need something that crawls recursively, classifies every trust from its attribute bitmasks, and tells you which ones are actually abusable. That is what TrustCrawler does.

TrustCrawler is a Python tool that queries trustedDomain objects via LDAP, extracts trust direction, type, SID filtering status, and encryption flags, then follows each trust into the next domain and repeats. It crawls child and sibling domains within target forests, enumerates foreign security principals, discovers Kerberoastable SPNs across trust boundaries, and even checks for vulnerable ADCS templates (ESC1-3) in trusted forests. The output is severity-rated attack paths with copy-paste commands for your toolset.

trustcrawler.sh
$ proxychains -q trustcrawler -d corp.local -u admin -H :ntlmhash --dc 10.10.1.1
 
CORP.LOCAL <--> DEV.CORP.LOCAL
Type: Parent-Child Direction: Bidirectional SID Filtering: OFF
CRITICAL ExtraSIDs golden ticket to forest root
 
CORP.LOCAL <--> PARTNER.COM
Type: Forest Direction: Bidirectional SID Filtering: ON
MEDIUM Cross-trust Kerberoasting (2 SPNs found)
HIGH 3 foreign security principals in privileged groups
 
PARTNER.COM --> VENDOR.IO
Type: External Direction: Outbound SID Filtering: ON
HIGH ESC1 vulnerable template in PARTNER CA

This is the difference between enumeration and analysis. A manual nltest /domain_trusts tells you trusts exist. TrustCrawler tells you which ones are exploitable and how. The parent-child to DEV.CORP.LOCAL gets flagged CRITICAL because SID filtering is off and you can forge an ExtraSIDs golden ticket straight to forest root. The forest trust to PARTNER.COM has filtering on, but it found Kerberoastable SPNs and foreign group memberships across the boundary. And it crawled into PARTNER.COM's own trusts to discover the outbound external trust to VENDOR.IO with a vulnerable ADCS template you would never have found from your starting domain. It runs from Linux through proxychains, authenticates with password, hash, or Kerberos, and generates ready-to-use commands for Impacket, Rubeus, Certipy, or whatever toolset you are working with.

SID Filtering: The Only Real Boundary

SID filtering strips foreign SIDs from authentication tokens as they cross a trust boundary. Without it, you can add any SID to your token (including Domain Admins from another domain) and it gets accepted. With it, those extra SIDs get removed at the trust boundary.

SID FILTERING OFF
Your token: user@child.corp
Extra SIDs: S-1-5-...-512 (DA of parent)
Crosses trust boundary...
Token accepted with DA SID intact.
You are Domain Admin in the parent.
SID FILTERING ON
Your token: user@partner.com
Extra SIDs: S-1-5-...-512 (DA of corp)
Crosses trust boundary...
Foreign SIDs stripped.
You are just user@partner.com.

Cross-Trust Attack Paths

When SID filtering is on (forest trusts), you can't just forge SIDs and walk in. But that doesn't mean the trust is a dead end. You need to find legitimate access paths that cross the boundary.

1
Foreign Group Membership
Users from Domain A added to groups in Domain B. This is the most common cross-trust path. One compromised user might be a member of a privileged group in a completely different forest.
2
Cross-Forest Kerberoasting
If the trust allows Kerberos authentication, you can request service tickets for SPNs in the trusted domain using a user from your compromised domain. Crack the ticket offline, get the service account password, pivot across.
3
Credential Reuse
The least technical and most effective. Users reuse passwords across domains. Dump credentials in Domain A, spray them against Domain B. Trusts exist because the organisations work together, and people who work together reuse passwords.
4
ADCS Across Trusts
If a Certificate Authority in the trusted forest has misconfigured templates (ESC1, ESC8), you can request certificates as users from the other domain. The CA doesn't care where the request comes from if the template allows it.

Visualising the Graph

This is why tools like BloodHound exist. A three-domain environment with bidirectional trusts, foreign group memberships, and shared service accounts creates an attack graph that no human can reason about manually. The paths are non-obvious, multi-hop, and cross boundaries that administrators think are walls.

attack-path.graph
NON-OBVIOUS CROSS-FOREST PATH
compromised_user @ CORP.COM
| member of "IT-Support" in DEV.LOCAL (foreign group)
v
IT-Support @ DEV.LOCAL
| has ReadLAPSPassword on BUILD01 (ACL)
v
BUILD01$ @ DEV.LOCAL
| has constrained delegation to FILE01 (delegation)
v
SYSTEM @ FILE01 (contains secret.txt)

Four hops, two domains, three different abuse types. No single administrator in either domain would see this path by looking at their own configuration. It only becomes visible when you model the entire environment as a graph and ask "what can this user reach?"

The Takeaway

Trusts are not firewalls. A trust says "I will accept authentication from this domain." That's a door, not a wall. The only thing that controls what walks through that door is SID filtering and explicit ACL configuration, and most organisations set up their trusts once and never audit them again.

Every trust you find during enumeration is an edge to explore. Enumerate foreign group memberships, check for cross-trust SPNs, spray credentials across boundaries. The path to domain admin often goes through a domain that nobody thought was connected.

Active DirectoryLateral MovementTradecraft

Trust behaviour and SID filtering defaults described here apply to Windows Server 2016+ functional levels. Older domain levels may behave differently.