Skip to main content

Module esc8

Module esc8 

Source
Expand description

ESC8 scanner, Web Enrollment HTTP/HTTPS probe + EPA (Channel Binding) detection.

Detects whether a CA exposes the /certsrv/certfnsh.asp endpoint over HTTP (always vulnerable to NTLM relay) or over HTTPS without Extended Protection for Authentication (EPA / Channel Binding), which is also vulnerable.

The EPA check works by sending a minimal NTLM Type 1 (Negotiate) message to the HTTPS endpoint and parsing the server’s NTLM Type 2 (Challenge) response. If the MsvAvChannelBindings AvPair (AvId 0x000A) is absent from the challenge’s TargetInfo, EPA is not enforced and the endpoint is relay-able.

This approach requires a single HTTP round-trip, no credentials, no full NTLM handshake, no relay attempted.

Three outcomes are distinguished per endpoint, matching SharpHound’s JSON shape:

SituationJSON
TCP port closed / unreachableCollected: true, NotVulnerable_PortInaccessible
Port open, HTTP request failedCollected: false + FailureReason
Port open, status determinedCollected: true + the matching status

A closed port is a result, not a collection failure: the CA was successfully determined not to expose web enrollment there. A 404 on an open port is the opposite, the probe could not conclude, so it is reported as not collected. The two /certsrv/ endpoints (HTTP + HTTPS) are ALWAYS emitted, so an empty HttpEnrollmentEndpoints array now only ever means “the module did not run”.

In addition to classic Web Enrollment, the Certificate Enrollment Web Service (CES) is probed at <CAName>_CES_<AuthType>/service.svc/CES over both HTTP and HTTPS, for each auth type in [CES_AUTH_TYPES]. CES is a second NTLM relay surface to AD CS; HTTPS reuses the same EPA/Channel-Binding logic as certsrv, and an HTTP-exposed CES is flagged outright. These endpoints carry Type: CertificateEnrollmentWebService and are only added when the CA short name is known. Ref: https://adhdmurky.github.io/posts/post4/

Module path: src/modules/adcs/esc8.rs Required Cargo dependency: reqwest = { version = "0.12", default-features = false, features = ["blocking", "rustls-tls-ring"] }

Structs§

Esc8Result
Full ESC8 probe result for a CA host.

Enums§

ProbeOutcome
Outcome of a single probe, mapped 1:1 onto the three JSON shapes.
WebEnrollmentStatus
Status of a single web-enrollment endpoint (HTTP or HTTPS).

Constants§

STATUS_NOT_VULN_EPA
STATUS_NOT_VULN_PORT
STATUS_VULNERABLE_HTTP
STATUS_VULNERABLE_HTTPS

Functions§

check_esc8
Run the full ESC8 probe against a CA host.
parse_epa_channel_bindings
Parse an NTLM Type 2 (Challenge) token and return true if MsvAvChannelBindings (AvId 0x000A) is present with a non-zero length. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/34a9417d-7cc0-43b0-b61c-1f19740df66f