AD CS
AD CS Enumeration
Typically, the Active Directory Certificate Services (AD CS) server is independent of the Domain Controller (DC). The former can be enumerated via its membership in the Cert Publishers group.
> net localgroup "Cert Publishers"
Alias name Cert Publishers
Comment Members of this group are permitted to publish certificates to the directory
Members
-------------------------------------------------------------------------------
ca_svc
DC01$
The command completed successfully.Furthermore, AD CS usage can be enumerated via Certify (Certify.exe) for Windows and NetExec or Certipy for Linux.
# Enumerate AD CS (Windows)
.\Certify.exe find
# Enumerate ADCS information (Windows)
.\Certify.exe cas
# Enumerate AD CS (Linux)
$ nxc ldap dc01 -u molly -p $(cat password) -M adcs
...
ADCS 192.168.239.128 389 DC01 [*] Starting LDAP search with search filter '(objectClass=pKIEnrollmentService)'
ADCS 192.168.239.128 389 DC01 Found PKI Enrollment Server: DC01.molly.local
ADCS 192.168.239.128 389 DC01 Found CN: molly-DC01-CA
# Enumerate AD CS (Linux)
$ certipy find -u molly@mollysec.local -p $(cat password) -dc-ip 192.168.239.128 -stdout
Certipy v5.0.4 - by Oliver Lyak (ly4k)
...
[*] Enumeration output:
Certificate Authorities
0
CA Name : molly-DC01-CA
DNS Name : DC01.molly.local
Certificate Subject : CN=molly-DC01-CA, DC=molly, DC=localShadow Credentials
Prerequisites for the Shadow Credentials attack
The attacker must have appropriate rights (
GeneralAll,GenericWrite, orWriteProperty) over the target'smsDS-KeyCredentialLinkattribute.The domain must support PKINIT, which requires a domain functional level of Windows Server 2016 or higher and at least one DC running Windows Server 2016 or later.
The DC must possess a valid certificate and private key, typically deployed through AD CS or another internal PKI solution. These are used by the KDC to prove his identify. Without this, PKINIT authentication will fail with the error
KDC_ERR_PADATA_TYPE_NOSUPP.
The attacker generates their own asymmetric key pair and retains control of the private key.
They then insert the corresponding public key into the target account’s
msDS-KeyCredentialLinkattribute.
Because AD treats any public key stored in this attribute as valid authentication material, the attacker’s key becomes an accepted alternative credential for the account. From that point forward, the attacker can authenticate using PKINIT, obtain a TGT, and operate with the full privileges of the compromised account.
However, the attack can be extended further.
By performing an S4U2Self request, the attacker can obtain a TGS to themselves on behalf of the same account. This process exposes the PAC embedded within the Kerberos ticket which contains authorization data about the account and, in many environments, includes a structure known as NTLM_SUPPLEMENTAL_CREDENTIAL.
When present, this structure holds the NTLM hash of the account in encrypted form. If this structure exists, the attacker can decrypt it and recover the NTLM hash, effectively obtaining a password-equivalent credential that can be used in NTLM-based attacks such as Pass-the-Hash or SMB authentication.
On Windows systems, Whisker can be used to add new Key Credentials to a target account. It supports two approaches. The operator can either supply an existing certificate to be registered as alternative authentication material, or instruct Whisker to generate a new certificate automatically.
When generating a certificate, Whisker integrates with Rubeus by outputting the exact command required to request a TGT via PKINIT and retrieve the associated NTLM hash.
On Linux, Certipy's shadow auto command authenticates to LDAP, injects a malicious Key Credential into the target’s msDS-KeyCredentialLink attribute, performs PKINIT authentication, retrieves a TGT, and extracts the NTLM hash automatically.
The output includes a PFX file containing the generated certificate and private key, a Kerberos credential cache file, and the NTLM hash of the target account. The certificate can be reused for future PKINIT authentication, while the Kerberos cache or NTLM hash can be leveraged for lateral movement.
pyWhisker performs this attack by leveraging Impacket and PyDSInternals. It outputs a Key Credential ID, a certificate file (.pfx) and its password. Once these are generated, the PKINIT tools can be used for full exploitation: a TGT can be requested with gettgtpkinit.py and the NT hash can then be recovered via getnthash.py.
Certifried
Certifried: Active Directory Domain Privilege Escalation (CVE-2022–26923)
Patched on May 2022.
This vulnerability is based on the fact that when a machine account requests a certificate via the Machine template, the mapping is based on its dNSHostName property.
By simply creating a new machine account and spoofing its DNS name, we can impersonate the DC.
A new machine account can also be created with addcomputer.py script (does not add an SPN by default) and an SPN can be then assigned with powerview.py.
sChannel
This attack can be used when there are vulnerable templates, but the AD CS server does not support PKINIT. In such cases, the obtained certificate cannot be used for obtaining a TGT or hash.
Schannel by default is only available via LDAPS, in which case we can attack it with PassTheCert. It supports the following four actions:
Assign DCSync rights to a user in case we obtain/generate a certificate for a privileged account.
Add a computer to the domain, useful for RBCD.
Modify a machine's
msDS-AllowedToActOnBehalfOfOtherIdentityattribute for RBCD.Reset the password of an account.
PasstheCert also provides clean up commands (e.g. del_computer and remove_rbcd) as well as an ldap-shell for more attack options.
While the C# version is similar, we need to perform some extra steps with PowerView and also transfer the PFX file over.
ESC Attacks
The terms ESC1, ESC2, etc., come from a threat model and classification system introduced by SpecterOps (Certified Pre-Owned). These labels don’t stand for acronyms, ESC simply means ESCalation, and they’re followed by a number to identify different types of attack paths related to ADCS.
During pentests, note down the CSR ID(s) and then add it to the Clean Up section of the report.
If a template meets all pre-reqs but enrolment rights, see which groups are allowed and if their members can be compromised.
This ESC4 → ESC1 chain is especially dangerous as it leverages legitimate ADCS functionality, making detection difficult. Issued certificates may remain valid for years, providing long-term persistence unless explicitly revoked. For an example of this attack chain, see EscapeTwo.
The first step in all ESC attacks is to identify a vulnerable template:
ESC1
ESC1 is a template misconfiguration where low-privileged users can request certificates and specify arbitrary identities in the Subject Alternative Name (SAN) field with the CSR. This happens because the ENROLLEE_SUPPLIES_SUBJECT bit in the mspki-certificate-name-flag template attribute is enabled.
The Enterprise CA and the security descriptor of the template must both grant enrolment rights to low-privileged users. If either is restrictive, enrolment will be blocked:

No issuance requirements should be present:

The template must allow SAN specification within the CSR and have an authentication-related EKU.

ESC2
ESC2 is a misconfiguration where a template is set with the Any Purpose EKU or lacks an EKU altogether (which implicitly grants Any Purpose). This allows it to act as an Enrollment Agent.
When Schema Version 2+ target templates are configured to require authorised signatures for enrolment agent requests, they must explicitly list the Any Purpose or the specific Certificate Request Agent EKU.
If low-privileged users have enrolment rights for such a template, they can obtain a certificate that implicitly grants them the ability to request certificates on behalf of other users.
By combining this with a target template that permits enrolment agent requests (such as the default User or Machine templates), an attacker can utilise their Any Purpose certificate to impersonate a high-privileged user.
This results in privilege escalation through indirect impersonation, exploiting the CA’s implicit trust in the agent capabilities of the attacker’s certificate. Additionally, a subordinate CA certificate can sign new certificates, specifying arbitrary EKUs or fields; however, by default, subordinate CAs are not trusted by the NTAuthCertificates object.
Simirarly to ESC1, the Enterprise CA and the security descriptor of the template must both grant enrolment rights to low-privileged users and there should be no issuance requirements. The key thing here is that the template must have the Any Purpose or no EKU:

ESC2 has two privilege escalation paths:
The primary path is turning the Any Purpose into an Enrollment Agent certificate (ESC3).
The secondary path is when a SAN is present in the CSR (ESC1).
ESC3
ESC3 is a vulnerability arising from a misconfigured template that allows users to obtain Enrollment Agent certificates (Certificate Request Agent EKU). These can be used to request certificates on behalf of other users.

If a low-privileged user can enroll for such a certificate (either directly or via an Any Purpose template) and another template permits agent-based enrolment (e.g. the default User or Machine templates), they can impersonate high-privileged users. The former must have an authentication-related EKU and allow enrolment on the target account.
ESC4
ESC4 is a misconfiguration where unintended principals can modify the template's security settings. For example, we can make a template vulnerable to ESC1 (see here for more exploitation options).
In CTF labs the attack chain typically is based around compromising a member of the Cert Publishers group (e.g. ca_svc) which has WriteAccess over a template.


To simulate this in a lab settings, we need to explicitly own the template before making changes to its ACEs:
Certify doesn't have a command that makes a template vulnerable to ESC1, but we an use PowerView:
ESC5
ESC5 is having excessive permissions on PKI-related objects, typically located in the Configuration Naming Context:
For example, compromising the LA of the AD CS server give us the Manage CA role, which can then be leveraged for ESC7:
Keep in mind that Certipy does not flag ESC5 when searching for vulnerable templates, but Certify does:
Certipy can be also leveraged for ESC5 post-exploitation. In a similar scenario, where we have LA rights over the AD CS server, we can create a backup:
The molly-DC01-CA.pfx file can then be used to forge Golden Certificates (similar to Kerberos Golden Tickets). The -crl 'ldap:///' flag used below, specifies a dummy CRL distribution point. The KDC checks for its presence but does not validate it if the CA is trusted.
ESC6
ESC6 is a CA misconfiguration that is based on the EDITF_ATTRIBUTESUBJECTALTNAME2 flag. If this flag is set on the CA, users can specify a SAN within a CSR for all templates, regardless if the templates itself restricts it.

This issue was patched in May 2022, so we need to add the key manually in order to test it.
This path essentially allows to perform ESC1 on all templates:

ESC7
ESC7 is essentially having access to an account with the following excessive rights:
Manage CA (aka CA Administrator) has the ability to modify the CA's configuration, assign CA roles (including Cert Manager), and start/stop the AD CS service.
Manage Certificates (aka Certificate Manager/Officer) can approve pending CSRs.
This is typically leveraged via the SubCA built-in template which can be used for Any Purpose and allows SAN specification within CSR. Only DAs and EAs have enrolment rights to it, but this can be bypassed with the Manage CA role.

In the below example, ca_svc has the Manage CA role over the CA via the Cert Publishers group:

In addition to the above attack vector, if there is an almost-vulnerable template to another ESC attack that is only missing the manager approval pre-requisite, we can just approve it:
Similarly, the attack can be perform from a Windows host with the PSPKI's PowerShell module.
Although ca_svc had the Manage CA role via the Cert Publishers group, Certipy did not flag it:

It was flagged, only when the account was explicitly assigned FullControl rights:
Manage CAis a permission set applied to the CA service/CA object as exposed in the CA MMC on the CA server. It governs what an account can do to the CA service itself (manage the service, issue/revoke/configure CA behaviour) and is enforced by the CA service on the host.ESC7 (as Certipy checks it) is about dangerous ACEs on the
pKIEnrollmentServiceobject in AD’s Configuration partition. Those ACEs (GenericAll,WriteDacl,WriteOwner,AllExtendedRightsor equivalents) let an attacker control the AD object that certificates and enrolment services rely on.
Because these are two different ACLs (one in the CA service/host and one on the AD object), membership in a CA-manage role on the CA server does not necessarily create the dangerous AD ACEs Certipy looks for. Conversely, an AD ACE on pKIEnrollmentService can exist without the user being shown as “Manage CA” in the MMC. For the Certipy to detect ESC7, a dangerous ACE to the pKIEnrollmentService AD object needs to be explicitly added.
ESC8
For the ESC8 attack, see here.
ESC9
ESC9 aims to bypass two security protections:
The template's security extension (
szOID_NTDS_CA_SECURITY_EXT)The KDC's binding mode (
StrongCertificateBindingEnforcement)
It targets a template that is explicitly configured not to include the szOID_NTDS_CA_SECURITY_EXT. This can be done by setting its msPKI-Enrollment-Flag attribute to CT_FLAG_NO_SECURITY_EXTENSION which forces the KDC to rely on weaker UPN/SPN-based mapping found in the certificate's SAN:

A consideration for this attack is that the KDC behaves differently based on its certificate binding mode which is configured via the StrongCertificateBindingEnforcement registry key:

The following combinations can happen; as shown below, the only case that ESC9 is blocked, is when the KDC is hardened (Full Enforcement mode) and the template's secure extension is present:

As usual, the template must enable domain authentication and the compromised account must have enrolment rights. The key here is avoiding the combination where the KDC is in Full Enforcement mode and the szOID_NTDS_CA_SECURITY_EXT is present.
There are two attack paths:
UPN Manipulation: we must be able to modify the SPN attribute of an account who has enrolment rights.
Update the victim's SPN to match that of a privileged account.
When CSR as the victim the resulted certificate will contain the privilege's account UPN.
Revert the victim's UPN.
When authenticated, the KDC will use the UPN from the certificate's SAN.
Combined with ESC6: more powerful; it succeeds even when the KDC is in Full Enforcement mode.
CSR from the target template.
Inject the target's UPN and SID (formatted as a special SAN URL:
URL=tag:microsoft.com,2022-09-14:sid:) into the CSR.The resulted certification will contain the attacker-supplied SAN and SID.
In the below example, the goal is to escalate from sylune to molly (DA) via henry:
sylunehasGenericWriteoverhenry→ shadow creds to compromisehenryUpdate
henry’s SPN to match the DACSR as
henry→ obtain cert as DA
Certify does not allow us to provide credentials, so the following options are available:
If
henryhas RDP rights → RDPIf
henryhas logon rights → RunasCS.exeTry this Certify fork
ESC10
ESC10 leverages registry key misconfigurations and has two attack paths. In both cases, there must be a template that allows Client Authentication.
StrongCertificateBindingEnforcement→ mapping during Kerberos authenticationThe above key is set to
0(Legacy Mode) (deprecated after April 2023)Control over an account
CertificateMappingMethods→ mapping during Schannel authenticationThe above key set to
0x4Control over an account that can compromise another account without no UPN (machine or built-in Administrator)
The first path is basically this combination from ESC9, so the attack is identical:

The second path is quite similar to the first, but because the CertificateMappingMethods registry key handles the Schannel authentication, the certificate cannot be used for PKINIT authentication. Instead, we use -ldap-shell for Schannel authentication and perform LDAP-based attacks.
We can create a machine account and then use it to take over any other machine (e.g. the DC) by configuring a RBCD.
We can also create a user account and add it to a privileged group (e.g. Domain Admins).
ESC11
For the ESC11 attack, see here.
ESC16
ESC16 occurs when a CA is misconfigured to exclude a critical SID extension from all issued certificates. This weakens certificate-based authentication by forcing DCs to fall back on insecure mappings like UPN or DNS names. If the domain isn't in full enforcement mode, attackers can impersonate privileged users by abusing certificate templates — even without strong SID bindings. This can happen either due to a registry setting or because the CA is unpatched (missing the May 2022 security update). ESC16 can also be combined with ESC6 to fully bypass SID validation, even in stricter environments.
Read initial UPN of the victim account for restoration purposes:
Update the victim account's UPN to the target 's sAMAccountName:
Obtain credentials for the "victim" account (e.g., via Shadow Credentials):
Request a certificate as the "victim" user from any suitable client authentication template (e.g., "User") on the ESC16-vulnerable CA:
-target: The DNS hostname of the server running the CA.-ca: The CA name, usually in the format<domain>-<hostname>-CA.
Revert the "victim" account's UPN:
Authenticate as the target administrator:
Last updated