AD CS – The ‘Certified Pre-Owned’ Attacks


This post will cover the attacks detailed in the white-paper produced by SpecterOps. The most well-known of which is the ‘ESC8’ attack – where a standard domain user can escalate to Domain Admin, given a vulnerable environment. If AD CS is a new concept to you, then I have a post covering the basics, as well as what can be misconfigured in an AD CS environment.

Before we begin with the main ‘Domain Escalation’ attacks (p. 54-81), we will quickly cover the THEFT5 attack, which is a technique we can use to obtain the current NTLM hash of a user, so long as we have a valid certificate.

All of the examples covered here will use either the WADE_PARKS or LAURI_ROTH users to represent low-privilege users within my test domain. (Thanks to davidprowe for the excellent BadBlood project which I used to populate an AD environment).

  1. Overview
  2. Attacks
    1. THEFT5 – Obtaining An NTLM Hash From A Certificate
    2. ESC1 – Misconfigured Templates
    3. ESC2 – More Misconfigured Templates
    4. ESC3 – Enrolment Agent Templates
      1. ESC3a – The ‘Certificate Request Agent’
      2. ESC3b – Domain Authentication
    5. ESC4 – Vulnerable Template ACE Permissions
    7. ESC7 – Misconfigured CA Object
      1. PSPKI Import: HRESULT: 0x80131515
    8. ESC8 – NTLM Relay & HTTP Enrollment


This post will show how we can make an AD CS environment vulnerable to the following attacks.

THEFT5 – Obtaining An NTLM Hash From A Certificate

Assuming we have managed to steal a certificate, or requested one through the default User template, then we can use Kekeo to request the NTLM hash of the target account. This is covered on page 49.

For example, say we have managed to steal a certificate for WADE_PARKS. We can then use LAURI_ROTH‘s account to request Wade’s NTLM hash, with just his certificate!

To perform this, we must import the stolen certificate into our certificate store (i.e. via MMC). Kekeo will use the imported certificate and request the NTLM hash from the KDC via PKINIT. This is a pretty technical exploit, and takes a while to fully get your head around! From Lauri’s machine, the command to perform this attack is:

tgt::pac /caname:forest /subject:WADE_PARKS /castore:current_user /

As we can see, Wade has a very strong password here:

A nice strong 10 character password from Wade

The key part of this attack is that we can continue to obtain passwords for Wade, so long as the certificate is valid. By default this is for 1 year from the certificate being issued.

ESC1 – Misconfigured Templates

Requirements: VULN1, VULN2, VULN3, VULN4, VULN5, VULN6

With this attack, we will request a certificate through MMC as normal. With this specific misconfiguration, we can specify a User Principal Name (UPN) to request the certificate for. For example, as a low privilege user we could request a certificate for the Domain Admin. In this example, we will request a certificate for Wade using Lauri’s account as a demonstration.

To set the UPN we want to target, use the Alternative Name section of the wizard, using the User Principal Name field.

Requesting a certificate for WADE_PARKS

After completing this wizard, we get a certificate for Wade added to our certificate store (On Lauri’s computer!).

We now have a certificate for Wade, even though we aren’t on his machine!

Using Rubeus, we can use this certificate to obtain a TGT as Wade now, which expands what we can do with this attack. To do this, we will use the following command. Note that the password below is the password we applied to the exported certificate.

Rubeus.exe asktgt /\WADE_PARKS /certificate:wade_upn.pfx /password:a /ptt
We now have a TGT as Wade

ESC2 – More Misconfigured Templates

Requirements: VULN1, VULN2, VULN3, VULN4, VULN5 (See below)

This misconfiguration is similar to ESC1, but two settings are changed:

  • The ability to supply any UPN in the request is removed (VULN6)
  • The EKU OID is either set to ‘Any Purpose’ or ‘None’

The ‘Any Purpose’ OID is interesting, as it allows for a certificate to make use of any of the potential uses of certificates. For example, it could be used for Domain Authentication or signing code. This is obviously seriously bad news if it is used by a skilled attacker. One of the potential OIDs which could be leveraged is the SubCA (i.e. A child certification authority) OID.

In theory the SubCA OID could allow a machine to create a child CA, which an attacker would have full control over. This could lead to an attacker enabling dangerous settings such as VULN3, VULN6 or VULN7. In reality, it is unlikely an attacker could do this, as the SubCA certificate would not be trusted by the root CA by default (Page 62).

We can configure a template with the Any Purpose policy by editing a Certificate Template on the AD CS server.

As a PoC, we can then obtain a TGT as the requesting principal. This is because the Domain Authentication policy would be included within the Any Purpose policy.

We can also do the same by removing all the Application Policies from the template, as shown in the ESC2a template below:

ESC2a template configuration

ESC3 – Enrolment Agent Templates

This attack relies on being able to get a certificate as an Enrollment Agent. This will allow us to approve requests for certificates. For this, we will create 2 vulnerable templates which must be used together:

ESC3a – The ‘Certificate Request Agent’

Requirements: VULN1, VULN2, VULN3, VULN4, VULN5 (See below)

This template will have the Certificate Request Agent policy enabled.

The vulnerable template

ESC3b – Domain Authentication

Requirements: VULN1, VULN2, VULN3, VULN5 (See below)

This template will allow the Client Authentication policy to allow us to sign in as the requesting user.

A standard Client Authentication template

Notably, this ESC3b template can require a signature before issuance – as we can leverage the certificate from ESC3a to sign the request.

To perform this attack, we will request a certificate for ESC3a. This certificate needs to be added to our certificate store – something which MMC will do by default. You could always import a stolen Request Agent certificate if you find one on the estate.

To obtain a certificate for ESC3b, we will need to use the ‘Enroll on Behalf of’ option in MMC.

Starting to leverage the ESC3a certificate

Thanks to ESC3a, we can choose that certificate when requesting ESC3b.

We can then set our user details in the wizard

The wizard will allow for multiple requests, so click on Cancel when you have obtained your ESC3b certificate. We can now see both of our certificates in the certificate store.

ESC4 – Vulnerable Template ACE Permissions

Requirements: VULN2

This attack relies on poor access control to the template object in AD. This will be based on the User template, but I have enabled the ability to specify an arbitrary SAN to demonstrate the risk posed by this attack. This would require an extra step of misconfiguration, and is slightly different to how ESC4 is described in the whitepaper. Without this, we could still perform an attack such as ESC2, where we can get a certificate for the current principal.

In this example, we will remove the Enroll permission, and instead enable the ‘Write‘ permission. By default we will not be able to enroll in this certificate, but we can edit the object to grant ourselves the Enroll permission.

When we go to our standard domain user, we are unable to enroll in ESC4 due to a permissions error.

Using PowerView, we can find our permissions on the ESC4 template

Get-DomainObjectAcl -SearchBase "CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=forest,DC=com" | ? {$_.ActiveDirectoryRights -like '*Write*'} | Select-Object SecurityIdentifier,ActiveDirectoryRights

Recall that *-513 is the Domain Users SID. This SID now has GenericWrite, WriteDacl and WriteOwner permisisons. We will use the Add-DomainObjectAcl in PowerView to grant us all permissions on the object. This is pretty noisy and not especially subtle, but it demonstrates the risk! The command used for my environment is below:

Add-DomainObjectAcl -TargetSearchBase "CN=ESC4,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=forest,DC=com" -Rights All -PrincipalIdentity 'S-1-5-21-4011496586-3104324443-3246812018-513'

We can run the Get-DomainObjectAcl command from above to check we have successfully gained additional privileges.

Going into MMC we can now enroll on the ESC4 template. Remember we set this one up to have a vulnerable SAN – so we could now get a cert as DA. Being able to set a SAN is not a requirement of this attack.

We can now enroll on ESC4

This gets granted, as expected.

And oh dear oh dear, we can now be DA


Requirements: VULN7

This was a fairly tricky one to get working with built in Windows tooling, and will probably be easier with Certify!

To start this off, we will query the registry using the following command. This will show us the current configuration:

reg query \\\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\forest-DC01-CA\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy /v EditFlags
As we can see, the 0x11014e value is the default (Secure) configuration

We run the command below to enable the misconfiguration. This will certainly need Administrator privilege and might have to be run on the DC.

certutil -config "DC01\forest-DC01-CA" -setreg policy\EditFlags +EDITF_ATTRIBUTESUBJECTALTNAME2
We can see that the setting was successfully changed.

If we run the reg query command from above, we can see the flag has changed to 0x15014e.

Exploiting this is slightly different from VULN6 and ESC1, where we could specify a SAN in the request. This attack relies on specifying the SAN via a certificate attribute, rather than a certificate extension (Such as in ESC1). Therefore, we need to use certreq rather than MMC, this is described on page 71 in more detail.

To do this, we must create a .req file for us to create a CSR from. To do this, we can use MMC to create a ‘Custom Request’

Click through the wizard, and select the template you want to abuse, I will use the User template as it allows for domain authentication.

Export the file as a .req file. This might officially be a .inf file – either way, certreq will be happy with either extension!

Then save your file – I will use the filename esc6.req.

Now we have a .req file, we can alter this CSR to add a SAN in our certificate request. At this point we have to set the SAN via a certificate attribute, rather than a certificate extension (Like we abused in ESC1). To do this, we must use certreq with the -attrib parameter. For my environment, we would use the following command from a low-privilege command line:

certreq.exe -submit -attrib "" esc6.req esc6.cer

We now have a .cer (Public certificate only), which we will import into MMC. The private key is stored on the computer – when we import into MMC it will join them together and allow us to form our .pfx file (Public and Private key).

Requesting our certificate with certreq.

Double click on the .crt file we just got via certreq and we can install it by clicking on Install Certificate.

Click through the wizard, I personally select it to be installed to an automatically chosen location. We now have a certificate for ‘WADE_PARKS’, but if we look closer we can see it is actually valid for the Administrator account

MMC showing that we have a certificate for ‘WADE_PARKS’, but it really is for the Domain Admin!

If we double click on the certificate in MMC, we can view the Subject Alternative Name field within the Details tab, showing who we can authenticate as with this certificate.

Here is the proof it is for the Domain Admin

After exporting, we can now get a TGT for the Administrator user with Rubeus.

Lets reset our value for EDITF_ATTRIBUTESUBJECTALTNAME2 so we don’t accidentally leverage it later on!

certutil -config "DC01\forest-DC01-CA" -setreg policy\EditFlags -EDITF_ATTRIBUTESUBJECTALTNAME2

ESC7 – Misconfigured CA Object

Requirements: VULN1

First off, lets check the permissions on the CA object, by using certsrv. Right click on the CA, then Properties, then Security

Lets enable the ‘Manage CA’ option on the Authenticated Users group. Obviously this is a really bad idea in the real world!

We can use PSPKI 3.7.2 to edit this value, as shown on page 76 of the whitepaper. This can be downloaded from the PSPKIAudit repo. We will use a built in PSPKI PowerShell function here, rather than editing DCOM as shown in the whitepaper.

Now we need to install RSAT. this isn’t very stealthy and requires local admin privileges to install. I believe that Certify doesn’t require these privileges.

Run DISM.exe /Online /Get-Capabilities to get the DISM images

Here is the CertificateServices.Tools image we want to install

We can then install the image with the following code:

DISM.exe /Online /add-capability /CapabilityName:Rsat.CertificateServices.Tools~~~~

Now we have RSAT, we can run PSPKI. The following commands will get the current setting for EDITF_ATTRIBUTESUBJECTALTNAME2 and then configure it to be vulnerable.

$configReader = New-Object SysadminsLV.PKI.Dcom.Implementations.CertSrvRegManagerD ""


$configReader.GetConfigEntry("EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")

$configReader.SetConfigEntry(1376590, "EditFlags", "PolicyModules\CertificateAuthority_MicrosoftDefault.Policy")

reg query \\\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\forest-DC01-CA\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy /v EditFlags

As we can see, EditFlags is now set to 0x15014e which is 1376590. From ESC6, we know this means we have set EDITF_ATTRIBUTESUBJECTALTNAME2  to be true.

From this point, we can follow ESC6 to gain further access.

PSPKI Import: HRESULT: 0x80131515

I had issues getting PSPKI to run, as it often threw “Exception from HRESULT: 0x80131515” errors. To solve this, refer to StackOverflow! It turns out that the DLL is being blocked by Defender. If we navigate to the PSPKIAudit folder, we can run the following command to unblock all the files.

Get-ChildItem *.* -Recurse | Unblock-File

Whilst testing this, I found the code from this site was handy for checking which DLLs we have successfully imported into our PowerShell session. The code for checking this is as follows:

[System.AppDomain]::CurrentDomain.GetAssemblies() | Where-Object Location | Sort-Object -Property FullName | Select-Object -Property FullName, Location, GlobalAssemblyCache, IsFullyTrusted | Out-GridView

For instance, a normal PS session has these assemblies imported:

Following importing PSPKI, we see the DLLs are loaded!

ESC8 – NTLM Relay & HTTP Enrollment

This exploit is really well documented, and tools such as BatS3c’s ADCSPwn have automated this process even further. In particular, I relied on the guide from ExAndroidDev when performing this attack. This relies on a branch of Impacket which adds support for attacking AD CS. To install this, run:

git clone --single-branch --branch ntlmrelayx-adcs-attack

Due to my lab setup, there were issues getting PetitPotam and the NTLM relaying working to the AD CS HTTP Endpoint. This is due to DC’s requiring message signing for all requests, which breaks the attack from what I can tell.

To bypass this, I have created another AD CS server (CAServer) and demoted my old one (DC01) used in ESC1-7. This is a standalone AD CS server, leaving DC01 to perform DC duties.

Details of the new CAServer (

Using PetitPotam we can elicit an NTLM hash from a target, then use Responder to take that NTLM hash and attempt to gain a cert. I used the following commands to do this:

python3 -u 'WADE_PARKS' -p 'Password1!' -d

sudo -t -smb2support --adcs

On my environment, this would trigger an NTLM relay (Showing PetitPotam is working), but I could not obtain a certificate.

Thanks to a tweet by Fragsh3ll, it looks like we might have to manually specify the ‘Domain Controller’ certificate. We can do this with the --template 'Domain Controller' argument in impacket. As shown below, this will return a certificate.

We can then import this base64 encoded certificate onto our low privilege user’s account. This certificate can then be used with Rubeus, using the /certificate: parameter.

Rubeus.exe asktgt /user:DC01$ /certificate:MIIRbQIBAzCCETcGCSqGSIb3....##BASE64 ENCODED CERTIFICATE##.. /ptt

This then returns a TGT for the krbtgt account!

We can then combine this with a DCSync attack to obtain the hash of the Administrator account. This can be performed from a medium integrity session.

AD CS – What Can Be Misconfigured?


The aim of this post is to go into more detail on the attacks described within the excellent ‘Certified Pre-Owned’ blog post & whitepaper produced by SpecterOps. This post will show how to configure a test environment which is vulnerable to the attacks they describe. If you are unfamiliar with AD CS, I have a separate post which covers the basics.

In summary, the attacks which are possible within a default installation of AD CS are terrifying. The now ubiquitousESC8‘ attack can lead to DC compromise from a low-priv user, and the other attacks are impressive in their own right. To learn more about how to perform the attacks, I have another post covering that.

  1. Introduction
  2. What Can Be Vulnerable In AD CS?
    1. VULN1 – “The Enterprise CA Grants Low-Priv Users Enrollment Rights”
    2. VULN2 – “An Overly Permissive Certificate Template Security Descriptor Grants Certificate Enrollment Rights To Low-Privileged Users.”
    3. VULN3 – “Manager Approval Is Disabled”
    4. VULN4 – No Authorized Signatures Are Required
    5. VULN5 – “The Certificate Template Defines EKUs That Enable Authentication.”
    6. VULN6 – The Certificate Template Allows Requesters To Specify A SubjectAltName (SAN) in the CSR
  3. Conclusion

What Can Be Vulnerable In AD CS?

This section will cover some of the misconfigurations covered within the whitepaper, showing how we can create a vulnerable AD CS environment. The ‘VULN’ numbers used below are something I used whilst researching into these attacks and made the configuration a little easier for myself.

In summary, the vulnerabilities can be shown in the table below:

 ESC1 (p.56)ESC2 (p.63)ESC3.1 (p.64)ESC3.2 (p.64)ESC4 (p.68)ESC5 (p.70)ESC6 (p.71)ESC7 (p.74)
VULN1 – Enterprise CA ACE✔️✔️✔️✔️✔️(*)
VULN2 – Template ACE✔️✔️✔️✔️ ✔️(1)
VULN3 – Manager Approval Disabled✔️✔️✔️✔️
VULN4 – No signature required✔️✔️✔️
VULN5 – Vulnerable EKU OID✔️✔️(2)✔️(3)✔️
VULN6 – SAN in CSR✔️
VULN7 – EDITF_* attribute✔️(*)
1 – Requires write permissions, 2 – Requires either ‘Any Purpose’ or no OID, 3 – Requires ‘Certificate Request Agent’ OID, * – Not relevant if ESC6 or ESC7 is possible

For example, to perform ESC6, we need VULN7 to be present in the estate. Likewise, if VULN4 is present on a given certificate, then ESC1, 2 or 3 could be possible should the other conditions be met.

One key point for this table, is that if ESC6 or ESC7 is possible, then ESC1-4 can be performed against any principal!

VULN1 – “The Enterprise CA Grants Low-Priv Users Enrollment Rights”

The Enterprise CA must be configured to allow our target user to request a certificate. This setting can be found via certsrv by right clicking on the CA object, then Properties then Security. A vulnerable server will have an ACE containing the target user (Such as Domain Users) allowing that user to request certificates. (Figure 8, Page 23)

By default, the Authenticated Users group is able to request certificates

This setting is enabled by default, as we can see above. This allows any authenticated user to request certificates from the AD CS server. In order to obtain a certificate, we will also need a certificate template to be (mis)configured to allow us to enrol on it. This is covered in VULN2 below.

These ACEs are also involved in VULN7, where we have the ‘Manage CA‘ or ‘Issue and Manage Certificates‘ ACE enabled for our user.

VULN2 – “An Overly Permissive Certificate Template Security Descriptor Grants Certificate Enrollment Rights To Low-Privileged Users.”

Despite the mouthful of a title, this is another ACE misconfiguration, which allows our standard user account to enroll on a certificate template. As we can see below, the default User template allows the Domain Users group to enroll on it.

The standard User certificate template

There are several permissions which can be abused here, for example the Enroll and AutoEnroll permissions are specific to certificate template objects.

We also have the more ‘traditional’ permissions such as Full Control and Write, which should be familiar from BloodHound. Either of these permissions would allow us as an attacker to edit the template, granting our user the Enroll or AutoEnroll permissions to enroll on it.

The Enroll and AutoEnroll permissions

VULN3 – “Manager Approval Is Disabled”

Following the same steps as VULN2, we can view details on the certificate templates. On the ‘Issuance Requirements‘ tab, we can see the authorisations required before a certificate is issued. If CA Certificate manager approval is not required, then we can request a cert and it will be automatically created for us.(Assuming we meet the other criteria such as those in VULN1 and VULN2.)

This is understandably quite risky, as there is no peer reviewing of these certificates, so an Administrator would not be aware of their issuance.

A template which does not require CA Certificate Manager approval

VULN4 – No Authorized Signatures Are Required

In a very similar method to VULN3, we can check if any authorized signatures are required. This is another pre-requisite which can make the process of issuing certificates better protected.

VULN5 – “The Certificate Template Defines EKUs That Enable Authentication.”

Using the method detailed in VULN3, we then go to the ‘Extensions‘ tab to view the EKUs which are set on the template.

The EKU OIDs which have been found to allow client authentication are on Page 19 of the whitepaper:

EKU UsageOID Value
Client Authentication1.
PKINIT Client Authentication1.
Smart Card Logon1.
Any Purpose2.
“SubCA”No EKUs

We can view this by selecting the ‘Application Policies‘ extension. By clicking on ‘Edit’ and then ‘Edit’ we can view the EKU value. As we can see below, the ‘Client Authentication‘ OID is included in the template below.

Example plaintext EKU OIDs for an example template

We can also view this using PowerView with the following query:

Get-DomainObject -SearchBase "CN=<TEMPLATE_NAME>,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=forest,DC=com" | Select-Object -ExpandProperty PKIExtendedKeyUsage
Getting the OIDs for a template with PowerView

VULN6 – The Certificate Template Allows Requesters To Specify A SubjectAltName (SAN) in the CSR

As a reminder here, a CSR is the request we send to an AD CS server to obtain a certificate. A SAN is an option we can set to obtain a certificate to authenticate as another user.

This misconfiguration allows for an attacker to request a certificate for any(!) target user for a given, vulnerable certificate template. Typically certificates can only be requested for the requestor, so this misconfiguration is very powerful.

With this setting enabled, we can request a certificate as any valid user on the domain. There is more detail on this on page 58.

This value is set via the CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT flag, which is a bitmask. We can find its value on the MSPKI-Certificate-Name-Flag value on the template. This can be requested with the following PowerView query:

Get-DomainObject -SearchBase "CN=<TEMPLATE_NAME>,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=forest,DC=com"

Or we can view it in the GUI if we have access to the AD CS server by going on the Properties of the certificate template, then onto the Subject Name tab.

A vulnerable certificate template


According to Microsoft:

If this flag is set on the CA, any request (including when the subject is built from Active Directory) can have user defined values in the subject alternative name.

This is a slightly different request as the SAN must be passed as an attribute, instead of a certificate extension, as with VULN6. This is still a very easy attack, even with this small change. Page 70 of the whitepaper contains more information on this.


Now we have looked at the misconfigurations, this post will show more detail on how we can attack a vulnerable environment.

AD CS – The Basics


This post will cover the basics of Active Directory Certificate Services (AD CS) and how we can use certificates for offensive security. I have two other posts on this subject. The first of which covers some of the dangerous misconfigurations. And secondly, how we can actually perform the attacks.

For those unfamiliar, AD CS is the server role used to issue and manage digital certificates within a server estate. This is a role which can have massive security implications if it is incorrectly configured. Certificates can be used for a large number of uses, from HTTPS through to authenticating to a domain.

All of the page references in this post refer to the white-paper produced by SpecterOps.

  1. Introduction
  2. Installation
  3. Core Concepts
    1. Certficates
    2. Certificate Template
    3. Certificate Signing Request (CSR)
    4. Extended Key Usages (EKU) Object Identifiers (OIDs)
    5. Subject Alternative Names (SANs)
  4. Interacting with AD CS
  5. Dealing With Certificates
    1. Requesting a Certificate
    2. Exporting a Certificate
    3. Importing a Certificate
  6. Conclusion
  7. Common Errors
    1. CRL Server is not reachable (CRYPT_E_REVOCATION_OFFLINE)
    4. The requested certificate template is not supported by this CA
    5. Other KRB-ERROR codes


We will assume we already have Server 2019 installed and running as a domain controller. Dinika-15 on Medium has made a great guide to follow for the installation of AD CS.

For our purposes, we will add the ‘Active Directory Certification Services‘ role to the server. Optionally, will can install ‘CA Web Enrollment‘ to have some fun with NTLM relays as part of the ‘ESC8’ attack. This is shown below:

If we do want to perform the ESC8 attack, ensure that you install AD CS on a server that isnt operating as a domain controller, due to their enhanced SMB signing protection. I didnt realise this for a few days and so most of my screenshots will reference my DC (DC01)!

Click through the wizard until we get to the confirmation screen. By default, I allow it to restart as needed! It didn’t seem to need it, but I have seen other server roles require several restarts.

Now we have it installed!

I would then recommend a restart to ensure the server is more predicable.

Then run certutil.exe on the CS server to show AD CS details & confirm we have it installed.

Core Concepts


Certificates in AD can be used for many different functions, but this research focuses on those certificates which allow for domain authentication. In effect, a certificate which allows for authentication has a lot of similarities with an SSH private key – as you can authenticate without knowing the current password and the credentials are stored in a single file.

Certificate Template

A certificate template is effectively a blueprint for a certificate. Each certificate request must use a template, and so the settings of a template will dictate the resulting certificate. For example, a vulnerable template might allow any AD user to authenticate to AD with it. (Page 16)

Certificate Signing Request (CSR)

A CSR is the request made by a client to the AD CS server, in order to obtain a certificate. For example, Joe Bloggs will submit a CSR to the AD CS server in order to obtain a certificate.(Page 15)

Extended Key Usages (EKU) Object Identifiers (OIDs)

Despite the incredibly complex name (EKU OIDs), these are a reasonably straight-forward concept at a high level. These values dictate what a certificate template can be used for. These uses can be things such as authenticating to the domain to signing code.

As described on page 18, the OID can be used for Client Authentication. This means if we can obtain a certificate which includes that OID, we can use the certificate to authenticate to the domain. We will cover these more later on!

Subject Alternative Names (SANs)

On a certificate template, there is an option to allow the requester to specify which principal the certificate can be used as. For example, if the SAN option is set on a template, and the template allows for client authentication then you could leverage the certificate to log in as any user. This is as bad as it sounds, and is covered in more detail within ESC1 (Page 54).

Interacting with AD CS

There are a number of tools which can be used to interact with AD CS, the table below lists a number of them:

Tool NameDescriptionUsage
MMCMMC can be used to request, import and export certificates from a device. Run -> mmc
ADSI EditThis can show us the raw AD information on the certification services. This is handy for debugging issues and the various ACEs and ACLs we will encounter! On a DC, search for ADSI Edit
Certification AuthorityThis tool will show details on the Certificate Templates, issued certificates and failed requests.On the CS server, Run -> certsrv
Certificate Templates ConsoleShows more detail on Certificate Templates.Right click on Certificate Templates within certsrv
Certify Automates a large part of this work, used for interacting with AD CS via CLI.Download from GitHub
ForgeCert If you manage to steal a CA certificate, this will allow ‘Golden Certificate’ attacks. Covered under DPERSIST1.Download from GitHub

For ADSI Edit, we must use the ‘Configuration’ naming context. To do this, open ADSI edit and right click on the ‘ADSI Edit’ entry at the top of the navigation tree.

Then click on Connect To and select the ‘Configuration’ option in the dropdown.

Click on ok and we can view information on AD CS at CN=Services -> CN=Public Key Services. We should now be able to see the container for Certificate Templates and other configuration items.

Dealing With Certificates

Requesting a Certificate

For this guide, we will use MMC to request our certificates. At the time of writing, Certify and ForgeCert were yet to be released. Therefore, we will focus on using built-in Windows tooling to achieve these attacks, which has the added advantage of living off the land! certreq can be used to perform these attacks via the CLI if desired.

On your domain-joined low-privilege machine, open up mmc by searching for it in the search bar.

Click on File -> Add/Remove Snap-in, then select the ‘Certificates’ option and click ok. We will now have loaded in the Certificates snap-in, which we can use to request certificates. To request a certificate, right click on the Personal entry, then All Tasks and then Request New Certificate.

Click through the wizard and then we will select the default User template.

Then click on Enroll and we will get a certificate in our ‘personal’ folder.

This is effectively the ‘PERSIST1‘ attack within the whitepaper (Page 49).

Exporting a Certificate

We will often want to export a certificate in order to maintain persistance over an account or machine. For example, if we abuse ESC1 or ESC2, we can login as a user or machine without having valid credentials for the account – so long as we have a valid certificate.

To export a certificate, go to the Personal folder within mmc and right click on the certificate to export. Select Export, at the wizard we will export the private key as well.

Export the certificate
And we must include the private key in order to use it on other systems!

Because we are exporting the private key, we must password protect the exported certificate file. Oddly there are no password restrictions here, so we will use a password of ‘a‘.

Importing a Certificate

Importing a certificate is very straight-forward. Right click on the ‘Personal’ folder within MMC, we will then select ‘Import’.

Click through the wizard, on the file selector make sure you select ‘All Files’ as it will default to .cer and *.crt files. You will need to put in your password from when you exported it.


Hopefully this very brief introduction was of use! To put this knowledge into action, I have posts on both how to configure a vulnerable AD CS environment and how to perform the various AD CS attacks here. Below are some errors which I encountered, which didnt have very simple explanations on Google!

Common Errors

CRL Server is not reachable (CRYPT_E_REVOCATION_OFFLINE)

To get around this error, we can disable CRL checking by running the following on the DC:

certutil -setreg ca\CRLFlags +CRLF_REVCHECK_IGNORE_OFFLINE

This will commonly show the “The revocation function was unable to check revocation because the revocation server was offline” or CRYPT_E_REVOCATION_OFFLINE error


This error typically appears when you haven’t imported the Domain Controller Authentication certificate onto the Domain Controller. This process is covered in more detail by Citrix here.

In short, go onto your DC and open MMC. In MMC add the Certificates add-on for the computer account and request the Domain Controller Authentication certificate.


Thanks to a tweet from GentilKiwi, we can fix this by running the following on a Domain Controller.

certutil -pulse

I found I had to reinstall the Domain Controller Authentication certificate again, as shown in KRB-ERROR(16) above, but this will depend on your environment!

The requested certificate template is not supported by this CA

This error occurs when you attempt to request a certificate template which has not been enabled. A template can be enabled within certsrv by selecting ‘Certificate Template to Issue’. Select the certificate you want to issue and click OK.

Other KRB-ERROR codes

If you encounter other error codes, is a great resource to explain what they mean. Often the codes are fairly self-explanatory!