14 techniquesLinux · ActiveDirectory · Windows · macOSWADComsGPL-3.0
Certipy-Account-Create
DÆMON
ExecutionLinuxActiveDirectoryWindows
Certipy account create adds a new computer (or user) object over LDAP when the operator has MachineAccountQuota available or delegated create rights. This is useful for staging RBCD, Shadow Credentials, or ESC-chain victim accounts that the operator fully controls. The subcommand also supports read/update/delete to modify existing objects' attributes (UPN, SPN, DNS hostname). Runs over LDAP, so add -k / -dc-host for Kerberos-only environments.
Command Reference:
Domain: test.local
Username: john
Password: password123
New account: WEBSRV01$
Domain Controller IP: 10.10.10.1
Certipy auth consumes a certificate/private key pair (.pfx) and performs Kerberos PKINIT pre-authentication to request a TGT for the identity in the certificate. It then uses the U2U/UnPAC-the-hash technique to recover the account's NT hash from the PAC, saving a .ccache and printing the hash. This is the final step of most ADCS escalation chains (ESC1/ESC3/ESC6/shadow creds): turn the issued certificate into a usable TGT and an NT hash for pass-the-hash.
Command Reference:
Domain: test.local
PFX file: administrator.pfx
Domain Controller IP: 10.10.10.1
ESC1 abuses a certificate template that allows an enrollee to supply an arbitrary Subject Alternative Name (ENROLLEE_SUPPLIES_SUBJECT) and enables Client Authentication EKU, while granting enrollment rights to low-privileged users. Certipy req enrolls against the vulnerable template and sets -upn to Administrator, producing a .pfx that authenticates as the domain admin. Supply -sid with the target's objectSid so the request also survives the 2022 strong certificate mapping (KB5014754) enforcement. Follow up with certipy auth to obtain a TGT and NT hash.
Command Reference:
Domain: test.local
Username: john
Password: password123
CA host (FQDN): dc.test.local
Domain SID: S-1-5-21-1339291983-1349129144-367733775
ESC3 abuses a template that grants the Certificate Request Agent (Enrollment Agent) EKU. Certipy first enrolls in the enrollment-agent template to obtain an agent .pfx, then makes a second request against a normal client-auth template (e.g. User) with -on-behalf-of set to a privileged account and -pfx pointing at the agent certificate. The resulting certificate authenticates as the impersonated user. Requires enrollment rights on both the agent template and the target template.
Command Reference:
Domain: test.local
Username: john
Password: password123
CA host (FQDN): dc.test.local
# 1) Obtain an enrollment agent certificatecertipyreq-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-template'EnrollmentAgent'# 2) Request a cert on behalf of the Administrator using the agent pfxcertipyreq-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-template'User'-pfxjohn.pfx-on-behalf-of'TEST\Administrator'
ESC4 is a certificate template ACL misconfiguration: the operator has Write/WriteDacl/WriteOwner over a template object. Certipy template with -write-default-configuration overwrites the template's settings with a known ESC1-vulnerable configuration (enrollee-supplied SAN, client-auth EKU, low-priv enrollment), turning any template into an ESC1 path. Use -save-old first to snapshot the original config, exploit ESC1, then restore with -write-configuration <file>.json to reduce footprint. OPSEC: the template change is domain-wide and logged in the config partition.
Command Reference:
Domain: test.local
Username: john
Password: password123
Domain Controller IP: 10.10.10.1
# Back up the template config, then overwrite it with a default vulnerable (ESC1-like) configurationcertipytemplate-ujohn@test.local-ppassword123-dc-ip10.10.10.1-template'ESC4'-save-old# Now abuse it exactly like ESC1 (see Certipy-ESC1), then restore the original config afterwards:# certipy template -u john@test.local -p password123 -dc-ip 10.10.10.1 -template 'ESC4' -configuration ESC4.json
ESC6 occurs when the Enterprise CA has the EDITF_ATTRIBUTESUBJECTALTNAME2 flag set, which lets any requester embed an arbitrary SAN into a certificate regardless of the template's subject settings. Certipy req can therefore enroll in a standard client-auth template (e.g. User) while supplying -upn Administrator to impersonate a privileged account. Include -sid to satisfy strong certificate mapping. Note that post-May-2022 patched DCs ignore the SAN unless the mapping is present, so ESC6 alone is often mitigated on updated environments.
Command Reference:
Domain: test.local
Username: john
Password: password123
CA host (FQDN): dc.test.local
Domain SID: S-1-5-21-1339291983-1349129144-367733775
ESC7 is when a principal holds the ManageCA (or ManageCertificates) right on the Enterprise CA. Certipy ca -add-officer promotes the controlled user to a certificate officer, which lets it approve pending requests. Combined with enabling the built-in SubCA template (-enable-template SubCA), the operator can request a cert that goes pending, then issue it (-issue-request) and retrieve it (-retrieve) as any UPN. This turns CA administrative rights into domain-admin certificate issuance.
Command Reference:
Domain: test.local
Username: john
Password: password123
CA host (FQDN): dc.test.local
# Grant our user the officer right on the CAcertipyca-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-add-officerjohn# Enable the SubCA template so we can request against itcertipyca-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-enable-template'SubCA'# Request (goes pending), then issue and retrieve as an officercertipyreq-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-template'SubCA'-upnadministrator@test.localcertipyca-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-issue-request785certipyreq-ujohn@test.local-ppassword123-dc-ip10.10.10.1-targetdc.test.local-ca'test-CA'-retrieve785
ESC8 abuses the AD CS web enrollment interface (certsrv / certfnsh.asp), which accepts NTLM authentication and is not protected by channel binding or EPA by default. Certipy relay stands up an HTTP-to-ADCS relay server; once a privileged machine account (e.g. a domain controller) is coerced into authenticating (PetitPotam/Coercer), the relay requests a certificate from the DomainController template on its behalf. The resulting .pfx authenticates as the coerced machine. Certipy relay is the modern replacement for ntlmrelayx.py -t http://<ca>/certsrv/certfnsh.asp --adcs.
Command Reference:
CA / web enrollment host IP: 10.10.10.1
Attacker/Listener IP: 10.10.10.2
# Start the ADCS HTTP relay targeting the CA web enrollment endpointcertipyrelay-target'http://10.10.10.1'-template'DomainController'# In another shell, coerce the DC to authenticate to the listener (10.10.10.2), e.g.# coercer coerce -u john -p password123 -d test.local -t 10.10.10.1 -l 10.10.10.2
ESC9/ESC10 abuse weak certificate mapping. When a template has CT_FLAG_NO_SECURITY_EXTENSION (ESC9) or the DC uses weak UPN/SPN mapping (ESC10), an attacker with write access over a victim account can change its userPrincipalName to a target admin's value, enroll a certificate as the victim, then authenticate as the admin because the cert has no SID binding. Certipy account update rewrites the victim's -upn over LDAP; revert it afterwards. This chains with certipy shadow (to enroll as the victim) and certipy auth.
Command Reference:
Domain: test.local
Username: john
Password: password123
Victim account: victim
Domain Controller IP: 10.10.10.1
# Point the controlled victim's UPN at the target admin (no @domain, so it maps by name)certipyaccountupdate-ujohn@test.local-ppassword123-dc-ip10.10.10.1-uservictim-upnadministrator# Enroll/authenticate as victim (now mapping to administrator), then restore:# certipy account update -u john@test.local -p password123 -dc-ip 10.10.10.1 -user victim -upn victim@test.local
Certipy's find command enumerates the AD Certificate Services environment over LDAP and RPC, collecting Enterprise CAs, published certificate templates, and their security descriptors. The -vulnerable flag filters the output to only templates and CA settings that match a known ESC misconfiguration (ESC1-ESC16), and -stdout prints a readable report to the console instead of writing BloodHound/JSON/text files. Run this first with any domain foothold to map which escalation path is available before requesting a certificate.
Command Reference:
Domain: test.local
Username: john
Password: password123
Domain Controller IP: 10.10.10.1
A 'golden certificate' is forged offline once the operator has extracted the Enterprise CA's own certificate and private key (via certipy ca -backup or ESC7, output as a .pfx). Certipy forge signs a brand-new certificate for any UPN with that CA key, so it is trusted by every DC in the forest. Because it never touches the CA and needs no enrollment, it is a durable persistence primitive that survives the target user's password resets. Include -sid to satisfy strong certificate mapping. Feed the forged .pfx to certipy auth.
Command Reference:
Domain: test.local
CA private key (PFX): test-CA.pfx
Domain SID: S-1-5-21-1339291983-1349129144-367733775
Shadow Credentials abuse write access to a target's msDS-KeyCredentialLink attribute (Key Trust). Certipy shadow auto adds an attacker-controlled key credential to the target account over LDAP, uses it to obtain a certificate via PKINIT, recovers the account's NT hash, and then removes the key credential to clean up automatically. Requires GenericWrite/GenericAll (or equivalent) over the target and a KDC that supports PKINIT. Preferred over PyWhisker when you want the full add-authenticate-restore chain in one step.
Command Reference:
Domain: test.local
Username: john
Password: password123
Target account: victim
Domain Controller IP: 10.10.10.1