Skip to content

Add Exploit Support for ESC9, ESC10 & ESC16 #20189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 30, 2025

Conversation

jheysel-r7
Copy link
Contributor

@jheysel-r7 jheysel-r7 commented May 15, 2025

This adds support to exploit ESC9, ESC10 and ESC16

ESC9, ESC10 and ESC16 scenario 1 can all be exploited using the new module esc_update_ldap_object. This new module focuses on exploiting ESC techniques that involve connecting to the domain controller via LDAP to update the specific attributes of a user prior to requesting a certificate on their behalf. We chose to keep this LDAP updating functionality separate from the existing icpr_cert module and so it got it's own module

Also new in this PR is a module ldap_update_attribute (which surprise gets called by esc_update_ldap_object). This new module provides 4 actions to create, read, update and delete LDAP object attributes.

ESC16 scenario 2 is pretty much when the CA has globally disabled security protections to allow ESC6 to be exploited again. This does not require LDAP objects to be updated and so can be exploited using the icpr_cert module.

This also updates the Attacking-AD-CS-ESC-Vulnerabilities.md which should be referenced for all verification steps.

@jheysel-r7 jheysel-r7 force-pushed the feat/mod/esc9-esc10-exploit branch 2 times, most recently from ee4a98e to 50fe418 Compare May 15, 2025 07:20
@jheysel-r7 jheysel-r7 linked an issue May 21, 2025 that may be closed by this pull request
@jheysel-r7 jheysel-r7 marked this pull request as ready for review May 27, 2025 17:16
@smcintyre-r7 smcintyre-r7 self-assigned this May 27, 2025
@smcintyre-r7 smcintyre-r7 added module docs rn-modules release notes for new or majorly enhanced modules labels May 27, 2025
@smcintyre-r7 smcintyre-r7 moved this from Todo to In Progress in Metasploit Kanban May 27, 2025
@github-project-automation github-project-automation bot moved this from In Progress to Waiting on Contributor in Metasploit Kanban May 27, 2025
Copy link
Contributor Author

@jheysel-r7 jheysel-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the detailed review. I believe I've addressed all the comments.

I haven't updated the module output in the scenarios listed in Attacking-AD-CS-ESC-Vulnerabilities.md just yet - incase the output changes.

@smcintyre-r7 smcintyre-r7 moved this from Waiting on Contributor to In Progress in Metasploit Kanban May 30, 2025
@github-project-automation github-project-automation bot moved this from In Progress to Waiting on Contributor in Metasploit Kanban May 30, 2025
@jheysel-r7 jheysel-r7 changed the title Add Support for ESC9 & ESC10 Add Exploit Support for ESC9, ESC10 & ESC16 Jun 5, 2025
@jheysel-r7 jheysel-r7 force-pushed the feat/mod/esc9-esc10-exploit branch from 3a5d01f to b7b7d7d Compare June 9, 2025 16:10
register_options([
OptEnum.new('UPDATE_LDAP_OBJECT', [ true, 'Either userPrincipalName or dNSHostName, Updates the necessary object of a specific user before requesting the cert.', 'userPrincipalName', %w[userPrincipalName dNSHostName] ]),
OptString.new('UPDATE_LDAP_OBJECT_VALUE', [ true, 'The account name you wish to impersonate', 'Administrator']),
OptString.new('TARGET_USERNAME', [true, 'The username of the target LDAP object (the victim account).'])
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With my understanding now, this is redundant with the SMBUser datastore option. That is to say, the account you'd target is also the account you authentication to the MS-ICPR service over SMB with and I can't think of a case where TARGET_USERNAME would not be set to SMBUser. Please let me know if such a case exists.

With that in mind, I think it makes sense to consolidate these options into a single field. If possible, I think naming it TARGET_USERNAME makes the most sense because it's the account you're targeting with the LDAP-write access.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm - maybe I'm misunderstanding (apologies in advance) however I don't think theres a redundancy here.

SMBUser is the user that has write privileges over the TARGET_USER.

The TARGET_USER is the victim in this case and the user whose (userPrincipalName or dNSHostName) and msDS-KeyCredentialLink gets updated because SMBUser has write privileges over TARGET_USERNAME.

Yes, eventually we request the certificate as the TARGET_USER over SMB . But first we run the ldap_object_attribute and then the shadow_credentials module and both of those need to be run in the context of the user who has write privileges over the TARGET_USER, which i've opted to call SMBUser.

I'd be happy to make changes, let me know what you think.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SMBUser is the user that has write privileges over the TARGET_USER.

I thought that was the LDAPUser since the write operation takes place over LDAP.

msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) > show options 

Module options (auxiliary/admin/dcerpc/esc_update_ldap_object):

   Name                      Current Setting  Required  Description
   ----                      ---------------  --------  -----------
   ADD_CERT_APP_POLICY                        no        Add certificate application policy OIDs
   ALT_DNS                   dc.msflab.local  no        Alternative certificate DNS
   ALT_SID                                    no        Alternative object SID
   ALT_UPN                                    no        Alternative certificate UPN (format: USER@DOMAIN)
   CA                        msflab-DC-CA     yes       The target certificate authority
   CERT_TEMPLATE             ESC10-Test       yes       The certificate template
   LDAPDomain                                 no        The domain to authenticate to
   LDAPPassword              Password1!       no        The password to authenticate with
   LDAPUsername              aliddle          no        The username to authenticate with
   SSL                       false            no        Enable SSL on the LDAP connection
   TARGET_USERNAME           WS01$            yes       The username of the target LDAP object (the victim account).
   UPDATE_LDAP_OBJECT        dNSHostName      yes       Either userPrincipalName or dNSHostName, Updates the necessary object of a specific user before requesting the cert. (Accepted: userPrincipalName, dNSHostName)
   UPDATE_LDAP_OBJECT_VALUE  dc.msflab.local  yes       The account name you wish to impersonate


   Used when connecting via an existing SESSION:

   Name     Current Setting  Required  Description
   ----     ---------------  --------  -----------
   SESSION                   no        The session to run this module on


   Used when making a new connection via RHOSTS:

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   RHOSTS     192.168.159.10   no        The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT      445              no        The target port (TCP)
   SMBDomain  msflab.local     no        The Windows domain to use for authentication
   SMBPass    Password1!       no        The password for the specified username
   SMBUser    WS01$            no        The username to authenticate as


Auxiliary action:

   Name          Description
   ----          -----------
   REQUEST_CERT  Request a certificate



View the full module info with the info, or info -d command.

msf6 auxiliary(admin/dcerpc/esc_update_ldap_object) >

This is the datastore I use for exploiting ESC16 where MSFLAB\aliddle has write access to WS01$ which is then used to impersonate DC$. In this case I have to set both SMBUser and TARGET_USERNAME to WS01$ right?

deregister_options('PFX', 'ON_BEHALF_OF')

register_options([
OptEnum.new('UPDATE_LDAP_OBJECT', [ true, 'Either userPrincipalName or dNSHostName, Updates the necessary object of a specific user before requesting the cert.', 'userPrincipalName', %w[userPrincipalName dNSHostName] ]),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When this value is dNSHostName, UPDATE_LDAP_OBJECT_VALUE seems to require that it ends in $. That would be a good thing to check for when validating the options ahead of time.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good call, I've opted to fail_with in this scenario with an explanation, instead of just adding it for them and proceeding. That way the user is aware the $ might be required in the future ie., when using the get_ticket module.

@jheysel-r7 jheysel-r7 force-pushed the feat/mod/esc9-esc10-exploit branch from cad1e0f to 25b0ded Compare July 30, 2025 17:26
@jheysel-r7 jheysel-r7 force-pushed the feat/mod/esc9-esc10-exploit branch from d3bfef6 to de15d1e Compare July 30, 2025 22:08
Copy link
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes look good to me now. I tested ESC9, ESC10 and ESC16. For 9 and 10, I issued certificates that I validated where able to authenticate to LDAP via SCHANNEL and for 16 I issued a certificate that worked with PKINIT. I also tested the metamodule with Pro and ensured there were no regressions.

@github-project-automation github-project-automation bot moved this from Waiting on Contributor to In Progress in Metasploit Kanban Jul 30, 2025
@smcintyre-r7 smcintyre-r7 merged commit 8bbfaac into rapid7:master Jul 30, 2025
48 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in Metasploit Kanban Jul 30, 2025
@smcintyre-r7
Copy link
Contributor

smcintyre-r7 commented Jul 30, 2025

Release Notes

This adds a new module that streamlines the exploitation of ESC9, ESC10 and ESC16. It handles manipulating a target account over LDAP and then using that account to issue a certificate as an elevated user.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs module rn-modules release notes for new or majorly enhanced modules
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

Add Support for ESC9 & ESC10
2 participants