AD CS is an identity system, not merely a certificate server
An enterprise certification authority can issue certificates used by Kerberos, smart cards, Wi-Fi, VPN, LDAPS, Intune or web servers. A bad combination of template settings, enrolment rights and identity mapping can therefore turn an ordinary user account into a certificate accepted as proof of a privileged identity.
The names ESC1, ESC4, ESC6 and ESC8 come from the taxonomy published by Will Schroeder and Lee Christensen in the Certified Pre-Owned research. They are neither CVEs nor automatic severity ratings; they are attack paths. Confirm every condition, actual template publication and compensating control before calling an environment exploitable.
In an assessment, I start with the entire chain: enterprise CAs, published templates, ACLs, web enrolment services, KDC configuration and certificates already issued. Looking only at the Certification Authority console can easily miss permissions stored in Active Directory or a forgotten IIS endpoint.
Recognize the four attack paths quickly
A single setting is not always sufficient. Supply in the request, for example, serves legitimate needs for some web certificates. ESC1 emerges when that setting meets an authentication purpose, a low-privilege requester and no validation. ESC4, by contrast, is concerning even when the template is safe today: whoever can write it can create ESC1, issue a certificate and restore the original values afterwards.
| Path | Dangerous combination | Risk | First action |
|---|---|---|---|
| ESC1 | Requester-supplied SAN + authentication EKU + broad enrolment + no approval/signature | Request a certificate as another account | Unpublish the template or immediately remove broad enrolment |
| ESC4 | An unprivileged principal can modify the template or its ACL | Turn a normal template into an exploitable one | Fix the owner and write permissions |
| ESC6 | EDITF_ATTRIBUTESUBJECTALTNAME2 enabled on the CA | Supply a SAN on every template, even without Supply in the request | Remove the flag after dependency testing |
| ESC8 | Web enrolment/CES with NTLM, HTTP or no EPA | Relay NTLM authentication to AD CS | Require HTTPS and EPA; remove the service if unused |
Build a read-only inventory before touching templates
Run the collection from an administrative workstation with the ActiveDirectory module. The script below exports enterprise CAs, the templates they publish, important flags and permissions capable of modifying a template. It requests no certificate and changes nothing.
Expand custom and nested groups afterwards. A group named PKI-Enrollment is not safe because of its name: verify its effective members, owner and membership process. Also retain certutil output from every CA, the AD CS role list and IIS configurations.
Import-Module ActiveDirectory
$Out = 'C:\Temp\ADCS-Audit'
New-Item -ItemType Directory -Path $Out -Force | Out-Null
$configNC = (Get-ADRootDSE).ConfigurationNamingContext
$services = "CN=Public Key Services,CN=Services,$configNC"
$templateBase = "CN=Certificate Templates,$services"
$caBase = "CN=Enrollment Services,$services"
$cas = Get-ADObject -SearchBase $caBase -LDAPFilter '(objectClass=pKIEnrollmentService)' `
-Properties dNSHostName,certificateTemplates,cACertificate
$cas | Select-Object Name,dNSHostName,certificateTemplates |
Export-Clixml "$Out\Enterprise-CAs.xml"
$templates = Get-ADObject -SearchBase $templateBase `
-LDAPFilter '(objectClass=pKICertificateTemplate)' `
-Properties displayName,msPKI-Certificate-Name-Flag,msPKI-Enrollment-Flag,`
msPKI-RA-Signature,pKIExtendedKeyUsage
$templates | ForEach-Object {
[pscustomobject]@{
Template = $_.Name
DisplayName = $_.DisplayName
PublishedBy = (($cas | Where-Object certificateTemplates -Contains $_.Name).Name -join '; ')
SuppliesSubject = (([int]$_.'msPKI-Certificate-Name-Flag' -band 0x1) -ne 0)
ManagerApproval = (([int]$_.'msPKI-Enrollment-Flag' -band 0x2) -ne 0)
AuthorizedSignatures = [int]$_.'msPKI-RA-Signature'
EKU = ($_.pKIExtendedKeyUsage -join '; ')
DistinguishedName = $_.DistinguishedName
}
} | Export-Csv "$Out\Templates.csv" -NoTypeInformation -Encoding UTF8
$templates | ForEach-Object {
$template = $_
(Get-Acl -Path ("AD:\{0}" -f $template.DistinguishedName)).Access |
Where-Object { $_.AccessControlType -eq 'Allow' -and
$_.ActiveDirectoryRights -match 'GenericAll|GenericWrite|WriteDacl|WriteOwner|WriteProperty' } |
ForEach-Object {
[pscustomobject]@{
Template = $template.DisplayName
Principal = $_.IdentityReference
Rights = $_.ActiveDirectoryRights
ObjectType = $_.ObjectType
Inherited = $_.IsInherited
}
}
} | Export-Csv "$Out\Template-Write-Rights.csv" -NoTypeInformation -Encoding UTF8certutil -getreg policy\EditFlags
certutil -getreg CA\AuditFilter
certutil -CATemplates > C:\Temp\ADCS-Audit\Published-Templates.txt
Get-WindowsFeature ADCS-Cert-Authority,ADCS-Web-Enrollment,ADCS-Enroll-Web-Svc
Get-Website
Get-WebApplication | Select-Object Site,Path,PhysicalPathESC1: the requester can choose the certificate identity
An exploitable ESC1 template generally combines four elements: it is published; an unprivileged user can enrol; the requester can supply the subject or SAN; and the certificate permits authentication through Client Authentication, Smart Card Logon, PKINIT Client Authentication, Any Purpose or sometimes no EKU. Without manager approval or authorized signatures, the request can be issued immediately.
In the Certificate Templates console, inspect Subject Name, Extensions, Security and Issuance Requirements. Do not stop at Domain Users and Authenticated Users: an ACL granted to an application group can become broad through nested membership. Also confirm that the template actually appears under Certificate Templates to Issue on at least one CA.
The safest correction depends on the requirement. Unpublish an unused template first. Otherwise derive the subject from Active Directory, remove authentication EKUs when unnecessary, restrict Enroll/Autoenroll to a managed group, and add approval or signatures where the process supports them. For a web server that must supply multiple DNS names in its SAN, create a separate template and reserve it for controlled deployment accounts.
- Do not change a template shared by NPS, VPN, Wi-Fi, smart cards or Windows Hello without identifying its consumers.
- Prefer duplicating a template, piloting the replacement and then unpublishing the old one over an immediate global change.
- A random Deny entry can create unexpected results; simplify groups and Allow permissions instead.
- Treat any authentication certificate already issued with an unexpected subject as a possible incident artifact.
ESC4: audit who can rewrite the template
A template is an object in Active Directory's Configuration partition. Its owner and ACL control far more than enrolment. GenericAll, GenericWrite, WriteProperty, WriteDacl or WriteOwner can allow someone to change the subject, EKUs, issuance requirements or enrolment rights. Microsoft Defender for Identity reports a weak template owner and weak template ACL separately under ESC4.
For every exported entry, trace the effective user. Rights assigned to Enterprise Admins, Domain Admins or a tightly managed PKI group are expected; rights assigned to Authenticated Users, Domain Users, Everyone, an ordinary service account or a delegated group without a change process require immediate justification.
Return ownership to a privileged and monitored identity, remove unnecessary write rights and separate template administration from enrolment. If you suspect malicious modification, do not rely on the current ACL alone: compare events 4899 and 4900, Active Directory backups and certificates issued during the change window.
ESC6: one CA flag affects every template
EDITF_ATTRIBUTESUBJECTALTNAME2 permits a SAN supplied as a request attribute at CA level. Unlike Supply in the request, this setting applies to every template processed by that CA. One published, accessible and authentication-capable template can then complete a dangerous combination.
On every CA, explicitly look for EDITF_ATTRIBUTESUBJECTALTNAME2 in the certutil output. Before removing it, identify systems that send SAN: in request attributes—legacy integrations, web certificate tools or gateways. Move them to a dedicated template and controlled request mechanism; do not preserve a global exception for one product.
Microsoft documents the following command to remove the flag. It changes configuration and restarts Certificate Services, so schedule it, back up the configuration, test enrolment scenarios and prepare rollback. Do not run it as though it were an audit command.
certutil -getreg policy\EditFlagscertutil -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2
net stop certsvc & net start certsvcESC8: close the NTLM relay target in IIS
ESC8 primarily targets Certificate Authority Web Enrollment, commonly exposed at /certsrv, and Certificate Enrollment Web Service (CES). When these services accept NTLM without HTTPS and Extended Protection for Authentication, an attacker can try to relay coerced authentication from a computer or user and obtain a certificate for that identity.
Microsoft recommends enabling EPA—Required is the safest option—for both Web Enrollment and CES, and then Require SSL. For CES, the role's web.config must also reflect extendedProtectionPolicy=Always when IIS is set to Required. Restart IIS only in an approved window and test real clients, SPNs, load balancers and any TLS termination.
Remove Web Enrollment or CES if there is no confirmed consumer. If the service remains, disable NTLM where testing permits and prefer Negotiate:Kerberos. HTTPS without EPA is not a complete relay fix, and blocking one coercion method does not close the target either. The durable control sits on the enrolment service itself.
- Inventory /certsrv, CES applications, HTTP/HTTPS bindings and authentication methods.
- Require a valid TLS certificate and Require SSL on every enrolment application.
- Set EPA to Required; use When Supported only as a documented transition.
- Validate Kerberos, SPNs and the end-to-end TLS channel before disabling NTLM.
- Filter the network so only expected clients or proxies can reach enrolment endpoints.
Import-Module WebAdministration
Get-Website | Select-Object Name,State,PhysicalPath
Get-WebBinding | Select-Object protocol,bindingInformation,certificateHash
Get-WebApplication | Where-Object { $_.Path -match 'certsrv|CES' } |
Select-Object Site,Path,PhysicalPath
& $env:windir\system32\inetsrv\appcmd.exe list config `
/section:system.webServer/security/authentication/windowsAuthenticationStrong certificate mapping helps, but does not replace hardening
KB5014754 strengthened how domain controllers map a certificate to an account. Patched controllers moved to Full Enforcement by default with the February 2025 updates, and the ability to return to Compatibility mode ended with the September 9, 2025 security update. A certificate without a valid SID extension or another strong mapping is then denied for the affected authentication flow.
This change reduces several abuses that rely on weak mapping, but it does not make ESC1 or ESC6 acceptable. CAs and templates must still limit who chooses the subject, certificates may be used by other protocols, and explicit mappings or special configurations change the outcome. Microsoft continuing to assess ESC1 and ESC6 in Defender for Identity is a useful reminder: fix the cause and use strong mapping as another defensive layer.
On domain controllers, monitor Kdcsvc events 39, 40 and 41 for certificates that cannot be mapped strongly or whose SID does not match. A legacy certificate application failure should not lead to restoring weak mapping indefinitely; issue a compliant certificate or create an explicit, strong and documented mapping instead.
Enable the logs that prove what happened
In a GPO applied to CAs, enable Advanced Audit Policy Configuration > Object Access > Audit Certification Services for Success and Failure. The CA also has its own audit filter: read CA\AuditFilter and set the required categories in CA properties. An enabled GPO with an incomplete CA filter still leaves gaps.
Events 4886 and 4887 connect a request, requester and issued certificate. Events 4882, 4885, 4890 and 4891 reveal sensitive CA changes. Events 4899 and 4900 show changes to template content and security respectively. Centralize them in your SIEM; retaining them only in the local log of a compromised server is not a detection strategy.
| Event | What it shows | Useful alert |
|---|---|---|
| 4882 / 4885 | CA permissions / audit filter changed | Any change outside a PKI window |
| 4886 / 4887 | Request received / certificate issued | Privileged SAN, rare authentication template or abnormal volume |
| 4890 / 4891 | Officer or CA configuration changed | EditFlags, module or issuance rule changed |
| 4899 / 4900 | Template content / security changed | EKU, subject, approval or ACL changed |
| Kdcsvc 39 / 40 / 41 | Strong mapping issue | Legacy certificate or inconsistent identity |
$ids = 4882,4885,4886,4887,4890,4891,4899,4900
Get-WinEvent -FilterHashtable @{
LogName = 'Security'
Id = $ids
StartTime = (Get-Date).AddDays(-7)
} | Select-Object TimeCreated,Id,MachineName,Message |
Export-Csv C:\Temp\ADCS-Audit\CA-Security-Events.csv `
-NoTypeInformation -Encoding UTF8Use Defender for Identity as a continuous control
Defender for Identity provides posture assessments for ESC1, ESC4, ESC6, ESC8 and other AD CS settings. Controls that depend on local CA or IIS configuration require a sensor on the AD CS server. Impacted entities update quickly, while score and overall status can take up to 24 hours after remediation.
This view accelerates prioritization but does not replace the inventory. Add business templates, enrolment dependencies, offline CAs, existing certificates and nested groups to the case. After each correction, verify both that the recommendation clears and that a legitimate request succeeds in the pilot.
- Install and maintain a healthy MDI sensor on every supported enterprise CA.
- Assign an owner to every recommendation and document affected templates or hosts.
- Baseline CAs, published templates, ACLs and web services every month.
- Alert on differences between baselines, not just the Secure Score value.
If a suspicious certificate was issued, switch to incident mode
Fixing a template prevents new requests; it does not invalidate an existing certificate. Search the CA database for requests matching the template, requester, subject and suspected period. Compare events 4886/4887, privileged account sign-ins and template or CA changes.
Revoke certificates confirmed as malicious, publish a new CRL and confirm that consumers actually check the CRL or OCSP. A certificate may remain useful to an attacker until expiry when the protocol does not check revocation. Reset affected credentials or accounts, and treat the CA server, private key and administrative accounts as compromised if the evidence supports it.
A compromised CA private key changes the response entirely: revoking one end certificate is no longer sufficient. Isolate the server, preserve evidence and invoke the PKI compromise plan, which may require renewing or replacing the CA and redistributing trust chains.
certutil -config "CA01.contoso.com\Contoso Issuing CA" -view `
-restrict "CertificateTemplate=UserAuthentication" `
-out "RequestID,RequesterName,Request.Disposition,CertificateTemplate,NotBefore,NotAfter,SerialNumber"Remediate in waves without breaking Wi-Fi, VPN or sign-in
The goal is not to make four labels disappear from a dashboard. It is to close impersonation paths while preserving legitimate use. Start by unpublishing what is clearly unused and narrowing excessive rights. Changes to subject handling, EKUs, EPA, NTLM or KDC mapping then move through a representative pilot.
Before every wave, back up CA configuration and database, export ACLs, confirm CRL publication and document rollback. Test both initial enrolment and renewal: a still-valid certificate can hide a broken policy for months.
| Wave | Actions | Exit criterion |
|---|---|---|
| 0 — Map | CAs, templates, ACLs, groups, IIS, dependencies and logs | Every use has an owner and test scenario |
| 1 — Immediate reduction | Unpublish unused templates; remove broad Enroll and Write | No ordinary principal can create or modify an authentication path |
| 2 — Templates | Replace ESC1; fix ESC4 owners and ACLs | Wi-Fi, VPN, auto-enrolment and service pilots renew |
| 3 — CAs | Remove ESC6; fix ESC8 with HTTPS, EPA and reduced NTLM | All approved enrolment methods work and old ones are closed |
| 4 — Detection | Centralize events, MDI and configuration baselines | Alerts tested against a request and template change |
| 5 — Evidence | Search for suspect certificates, revoke where required and retest | No unknown certificate; CRL/OCSP and recovery validated |
The checklist that actually closes the engagement
AD CS is unforgiving of incomplete inventories: one legacy template or forgotten CES application can reopen a path to the most privileged accounts. A point-in-time review closes visible gaps; a configuration baseline, centralized logs and accountable PKI ownership keep them from returning silently.
If you need an independent view of the whole chain—CAs, templates, permissions, mapping, logs and dependencies—the Active Directory security assessment is designed to produce that map and a prioritized remediation roadmap.
- Every enterprise, subordinate and offline CA is documented with an owner.
- Every published template has a requirement, owner, enrolment population and review date.
- No broadly enrolable authentication template combines supplied SAN, automatic issuance and no signature.
- No unprivileged principal has GenericAll, GenericWrite, WriteDacl, WriteOwner or WriteProperty over a sensitive template.
- EDITF_ATTRIBUTESUBJECTALTNAME2 is absent or covered by a temporary, isolated and tested exception.
- Unused Web Enrollment and CES roles are removed; the others enforce HTTPS, EPA and reduced authentication.
- Strong mapping is enforced and KDC events 39, 40 and 41 are handled.
- CA and template events are centralized, retained and tied to identities and issued certificates.
- Suspicious certificates were investigated; revocation and CRL publication were tested.
- Critical uses renewed successfully after changes; current operation alone is not accepted as proof.
- CA backup, private-key protection and recovery are part of the continuity plan.