Misconfigurations in Active Directory Certificate Services (ADCS) can introduce critical vulnerabilities into an Enterprise Active Directory environment, such as paths of escalation from low privileged accounts to domain administrator.
In PART ONE of this short ADCS series, we introduced Active Directory Certificate Services at a high level and walked through one of the escalation techniques, ESC1. In this post, we will walk through the escalation technique, ESC4, using Certipy.
This issue occurs when a certificate template can be modified by a non-administrator account. This misconfiguration can occur when unintended users are granted one of the following template security permissions:
In the following example, let’s imagine that we have gained a foothold in our target company FOOBAR’s internal network and have compromised the account of a user with the name “billy”; we have enumerated the ADCS configuration for the internal target domain “foobar.com”.
As shown in the figure below, the “ESC4Certificate_FOOBAR” template was configured to grant the “Domain Users” group with
Write Owner Principals and
Write Property Principals permissions. This means that any foobar.com user has permission to modify any given property in the template.
Our compromised user account “billy” is a part of the “Domain Users” group and therefore is authorized to modify the template configuration.
We can introduce escalation conditions using the following Certipy command:
certipy template -u [email protected] \ -p REDACTED \ -template ESC4Certificate_FOOBAR \ -dc-ip <DC_IP> \ -save-old
As shown in the figure above, the original template was saved in the “ESC4Certificate_FOOBAR.json”. We can use the configuration file to easily revert the template configuration to its original state once we’ve completed this attack. The target template was updated to meet the following ESC1 conditions:
- Client Authentication: True
- Enabled: True
- Enrollee Supplies Subject: True
- Requires Management Approval: False
- Authorized Signatures Required: 0
In addition, the template Validity Period was increased from 4 years to 5 years. Now this vulnerable template can be used by any domain user to request a certificate on behalf of any other domain account. The modified template is shown below.
To demonstrate this, we can request a certificate for “Dan the DA” by setting the user principal name (UPN) to [email protected].
certipy req -u '[email protected]' \ -p 'REDACTED' \ -dc-ip '10.10.1.100' \ -target 'foobar-CA.foobar.com ' \ -ca 'foobar-CA' \ -template 'ESC4Certificate_FOOBAR' \ -upn '[email protected]'
Note: The Certipy results will return the request ID or an Object SID. Note this, as you will need this information to revoke the certificate once the test is completed.
Once we have our certificate, we can use the certificate to obtain the credential hash and a Kerberos ticket of the target DA account using the Certipy
-auth command as shown below:
certipy auth -pfx DA_Dan.pfx
As shown in the figure below, we successfully retrieved the hash for the DA_Dan account. Now we can impersonate DA_Dan!
In summary, the template “ESC4Certificate_FOOBAR” was configured to allow users from the Domain Users group (non-Administrator accounts) to modify the template configuration. This allowed the standard domain user, Billy, to modify the template “ESC4Certificate_FOOBAR” and introduce vulnerabilities that allowed escalation from a normal domain account to a Domain Administrator account.
To restore the template configuration to its original state, use the following template command:
certipy template -u [email protected] \ -p REDACTED \ -template ESC4Certificate_FOOBAR \ -dc-ip <DC_IP> \ --configuration 'ESC4Certificate_FOOBAR.json'
Prevention and Detection
So, what can we do to prevent and detect such attacks? Here are a few steps to harden your certificate templates.
- Take stock of your certificate templates and determine whether all enabled templates are currently in use. Disable all templates that are unnecessary.
- Make sure that template permissions are as restrictive as possible. Only grant necessary groups/users enrollment permissions. Only grant necessary groups/users permission to modify template properties.
- Modify the “Issuance Requirements” to require the manual approval of an issued certificate where possible.
- Disable the “Enrollee Supplies Subject” flag where possible.
- Remove “Client Authentication” where possible.
It’s uncommon for certificate templates to be changed regularly. Detections should be built around unexpected template configuration changes. Event IDs 4900 and 4899 occur when an ADCS object changes and enrollment occurs.
By monitoring certificate change events, an administrator can alert on anomalous behavior, investigate template changes, and revoke certificates that appear to be malicious or suspicious. Some useful event IDs can be found below:
- 4900 – Security permissions for a certificate template changed
- 4899 – Certificate template was updated
- 4886 – Request for certificate
- 4887 – Certificate Issued
- 4768 – Request for Kerberos ticket (TGT)
- “Defensive Guidance” section of Certified_Pre-Owned
- Microsoft PKI defensive guidance: https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/dn786443(v=ws.11)
- PKIAudit: https://github.com/GhostPack/PSPKIAudit
- SpecterOps Whitepaper: https://specterops.io/wp-content/uploads/sites/3/2022/06/Certified_Pre-Owned.pdf
- SpecterOps Blog Post: https://posts.specterops.io/certified-pre-owned-d95910965cd2
- PKINITtools: https://github.com/dirkjanm/PKINITtools
- PyWhisker: https://github.com/ShutdownRepo/pywhisker
- Certi: https://github.com/zer1t0/certi
- Impacket: https://github.com/fortra/Impacket
- Certipy: https://github.com/ly4k/Certipy
- Certify: https://github.com/GhostPack/Certify
Ready to learn more?
Level up your skills with affordable classes from Antisyphon!
Available live/virtual and on-demand