AD-ADCS-019: HTTPS enrollment endpoints where EPA is not verified¶
low Certificate services MITRE ATT&CK T1649, T1557.001 Reads: HTTP probe, LDAP
AD CS web enrollment or CES offers Windows authentication over HTTPS, and the scan cannot tell whether Extended Protection is enforced.
Also known as: esc8-https, epa-unknown
Why it matters¶
HTTPS on its own does not stop an NTLM relay: the attacker opens their own TLS session to the endpoint and passes the coerced authentication through it, as in AD-ADCS-010. What stops it is Extended Protection for Authentication (EPA), which ties the authentication to the TLS channel. The same goes for the Certificate Enrollment Web Service (CES), which issues certificates like web enrollment does.
Three settings look the same from outside. Require stops the relay. Off leaves it open. Allow also leaves it open, because a client that sends no channel binding is still let in.
How ad-doctor detects it¶
ad-doctor sends one unauthenticated GET over TLS to /certsrv/ on each enterprise CA (the
port given by --https-port, default 443) and to each HTTPS URL in msPKI-Enrollment-Servers.
The endpoint is reported when the server answers 401 and the WWW-Authenticate headers
offer NTLM or Negotiate.
For /certsrv/, which is only a guess, a refused connection or another status means no such
endpoint. A URL in msPKI-Enrollment-Servers exists because the directory says so, so a refused
connection or any status but 401 gives a note that EPA and NTLM were not judged, not a clean
result. A 401 that offers neither scheme, such as Basic on a user name and password endpoint,
is a real answer and is not listed. Any other error is noted as not probed.
The probe sends no credentials, so it does not determine EPA: a server shows EPA only to
a client that authenticates, by accepting the authentication with a channel binding and
refusing it without one. Every endpoint that offers Windows authentication is therefore
listed, whatever its setting. The server certificate is not checked, since nothing secret is
sent. Each object is the endpoint URL. With --no-probes or --https-port 0 the check does
not run, and a note says so.
Attributes and probes read
dNSHostName and msPKI-Enrollment-Servers (on pKIEnrollmentService)HTTPS GET /certsrv/ and each CES URL: status and WWW-Authenticate
Severity¶
Always low: this is a gap in what the scan knows, not a proven weakness. An endpoint without EPA is as serious as AD-ADCS-010, so check it by hand.
False positives and limits¶
- EPA is set to Require. The endpoint is fine and the scan cannot see it. Confirm with the commands below, then accept the finding for that URL (accepted risks).
- Negotiate restricted to Kerberos. If IIS offers
Negotiatebut NTLM is disabled for the site, the NTLM relay fails; the header alone does not show this. - Not found at all: endpoints at a non-default path that the directory does not publish.
Fix¶
Read the setting on the server that hosts the endpoint. Use CertSrv for web enrollment and
the application name in the URL for CES:
Import-Module WebAdministration
Get-WebConfigurationProperty -PSPath 'IIS:\' -Location 'Default Web Site/CertSrv' `
-Filter 'system.webServer/security/authentication/windowsAuthentication/extendedProtection' `
-Name tokenChecking
Get-WebConfigurationProperty -PSPath 'IIS:\' -Location 'Default Web Site/CertSrv' `
-Filter 'system.webServer/security/authentication/windowsAuthentication/extendedProtection' `
-Name flags
Require is what KB5005413 asks for. If it says None or Allow, treat the endpoint like
AD-ADCS-010: set Require after review and restart IIS, or remove the role
if nobody uses it. Clients on old systems may stop working, so test first.
Require alone does not settle it:
- Flags. With the
Proxyflag IIS checks SPNs and not the channel binding, sotokenCheckingproves nothing. A client connecting straight over TLS needsNonehere. - CES needs more. KB5005413 also asks for
<extendedProtectionPolicy policyEnforcement="Always" />in theWeb.configthe CES role created (Alwaysgoes withRequiredin IIS), and for Require SSL on the application. Accept the finding for a CES URL only when all three are in place.
Verify¶
To accept the risk instead, add an entry to the file passed with --accept (see accepted risks):
[[accept]]
check = "AD-ADCS-019"
objects = ["..."] # optional; without it the whole check is accepted
reason = "..."
expires = 2027-03-31
Related checks¶
References¶
Microsoft and vendors
- KB5005413: Mitigating NTLM relay attacks on Active Directory Certificate Services (AD CS)
- IIS: Windows Extended Protection (extendedProtection)
Tools
MITRE ATT&CK
Available since 0.1.3.