Due to the ever-growing use of certificates in modern applications, a large number of Active Directory infrastructures make use of Public Key Infrastructures (PKI) features. These features are provided by Certification Authorities (CA) which are either external to Active Directory or deeply coupled with it.
Similar intricate systems, such as Microsoft Exchange, have highlighted a significant number of ways that someone with a user account on Active Directory and malicious intent can benefit from to take over Active Directory.
Active Directory Certificate Services (ADCS) have never really been under security scrutiny until a few years ago (by C. Falta and later Q&D Security). We will therefore focus today on how similar techniques can be used to gain Domain Admins privileges.
Note: this article assumes that the reader has a correct understanding of Active Directory and/or PKI operation; some sections may be skipped depending on the reader experience and level of expertise.
Table of contents
- Active Directory pentest: mission briefing
- Deep dive into Microsoft ADCS
- Elevating privileges with ADCS
- Current mitigations
Active Directory pentest: mission briefing
This article will tackle Microsoft ADCS and its potential issues under the specific prism of an Active Directory pentest, but the conclusions will be applicable on a broader scope: red team assignments, ADCS hardening, etc.
Context and objectives
An Active Directory pentest is a type of assignment where the sponsor of the audit is asking the pentester to interact with the audit target’s infrastructure to find ways of gaining control of Active Directory. The auditor usually performs this task under the two following approaches:
- The black box approach: it simulates an attacker who already has physical access to the target’s premises (and consequently to network plugs and physical devices); the goal is often to progress towards the grey box approach, leveraging unencrypted hard drives, credential sniffing, guest access and misconfigured applications on vulnerable assets;
- The grey box approach: the pentester acts as a malicious or compromised user, within the context of its domain session, i.e. being able to execute arbitrary code as this user.
In our case, we will focus on the grey box approach, therefore considering a malicious party who already has the ability of interacting with the domain as a standard user with no specific rights. The goal of the pentester would be to find a way to leverage the current rights of the user on the domain to compromise high-privileged principals, frequently the members of the Domain Admins group.
Elevating privileges in an AD environment
From lateral movement …
Historically, Windows has been built as a user-friendly operating system, which means that it will do its best to minimize the number of situations where a user must type its password. In terms of user experience, most users will only type their password to unlock their workstation. System administrators may have to type it another time when using the Remote Desktop Protocol (RDP), but they don’t expect it to type it again when connected to the remote server and/or interacting with domain resources.
Under the hood, it means that Windows offers Single-Sign-On (SSO) features, which allow the system to authenticate as the user to other systems or applications. This sleight of hand is performed by the lsass.exe process, which caches usable credentials for the user in memory. There are two types of credentials that can be cached:
- Authenticators derived from credentials, e.g. the password itself, or its NT hash
- Authenticators retrieved thanks to other means, e.g. Kerberos tickets
The credentials are cached into the memory of the lsass.exe
process running with the System integrity level. Either processes running as SYSTEM
, or processes with SeDebugPrivilege
enabled (which by default can only be enabled by local administrators) would be able to peek into lsass.exe
memory.
Various tools, such as Mimikatz and Windows Password Recovery, allow users with local administration rights to extract the aforementioned authenticators from the memory:
Mimikatz extracting authenticators from lsass.exe process memory
These authenticators in turn can be used to log in onto other workstations and servers, using techniques such as Pass-the-Hash or Pass-the-Ticket. The use of these techniques is included in what is called Lateral Movement and allows progressing from low-privileged assets to high-privileged ones.
… to compromise graphs
In a grey box approach, a pentester would usually be provided with a standard network access, a domain-joined workstation and a basic user account. Assuming local administration rights are somehow obtained, the pentester would then gather:
- The local accounts’ credentials in the SAM database (NT hashes)
- The local and domain accounts’ authenticators which recently logged in (NT hashes and Kerberos tickets, even cleartext passwords under some conditions)
Using this newly found credential, the next objective is to try using them on the other assets in the domain. If this works, the operation can be repeated, each time gaining more and more foothold on the domain.
This progression is quite easily performed by hand in a lab domain a limited number of workstations and servers but cannot be humanly feasible in a real-life domain with hundreds of servers and thousands of users and workstations (without mentioning domain trusts, etc.). This is where graph theory comes into play, with the following equivalents:
- Vertices (nodes) represent domain assets: user objects, computer objects and group objects
- Oriented edges connect two vertices when one has the ability to compromise the other (also called control path)
With such a graph, one would quite easily find (if it exists), the shortest path from a basic user account to a high-privileged principal on the domain. The only remaining task would be to exploit it. A path from one principal to another is called a compromise path, and the set of compromise paths between two principals represent all the means at one’s disposal to compromise the latter starting from the former:
Compromise paths between a user and a member of the Domain Admins group
Drafting the domain compromise graph
In order to build the domain compromise graph, a list of possible edge types has to be defined. Lateral movement using credential dumping is often central, but it is not the only way of compromising principals. The current list includes (but is not limited to):
- Domain group membership
- Being local administrator of a target
- Having an open session on a target
- Ability to connect to a target using RDP (generally implicitly combined with the ease of privilege escalation)
- Domain principal ownership
- Permissive Access Control Entries (ACEs) over domain objects: GenericAll, GenericWrite, WriteProperty, etc.
- “By design” compromise paths from built-in groups: Server Operators, Backup Operators, DNS Admins, etc.
Building domain compromise graphs is particularly difficult to perform by hand, especially on large domains. There exist tools that help building these graphs and adding edges to find compromise paths.
Although many tools exist (Tenable.ad, AD-Control-Paths, PingCastle), the most famous one is BloodHound, and it leverages most of known techniques used to compromise accounts:
Example graph generated by BloodHound
Deep dive into Microsoft ADCS
What is ADCS?
Microsoft Active Directory Certificate Services (ADCS) is a role that can be given to servers who will act as Certification Authorities (CA) in the forest. It integrates naturally within the forest, which means that there are domain objects that represents the different actors involved in a PKI lifecycle, and Access Control Lists regulating the interactions between these actors:
- Certificate template management
- Certificate enrolment
- Certificate revocation
- CRL publication
- etc.
How does ADCS operate?
The ADCS server role is installed on every server that is to act as a CA. When installing the ADCS role, the administrator is presented with twochoices: first, either install a Standalone or an Enterprise CA:
CA setup type choice
Then, in the case of an enterprise CA, it can be positioned as a Root CA or Subordinate CA:
CA type choice
This article will focus on the Enterprise Root CA, for which the configuration is split between two places:
- Active Directory, in which information global to the PKI infrastructure is stored: names and location of CA servers, global rights, etc.
- The Windows servers on which the ADCS role is installed, on which the day-to-day configuration parameters specific to this Certification Authority are stored: CA administration rights, certificate emission parameters, etc.
Active Directory: Public Key Services
In Active Directory, the configuration is stored under the following location (Configuration partition, thus defined at forest-level):
CN=Public Key Services,CN=Services,CN=Configuration,DC=lab,DC=local
The configuration can be viewed using the adsiedit.msc
component in the MMC:
Global PKI configuration in Active Directory
Certificate templates
The CertificateTemplate container has one domain object of type pKICertificateTemplate
for every template to be shared amongst the enterprise Certification Authorities. These templates define, through attributes configured on their domain object, a set of policies that mostly describe and constrain:
- General settings: the validity period of the delivered certificates
- Request handling: the purpose of the certificate and the ability to export the private key (although this can be bypassed if the private key is generated prior to the certificate request, for example with the
certreq
binary) - Cryptography: the Cryptographic Services Provider (CSP) to be used and the minimum key size
- Extensions: the list of X509v3 extensions to be included in the certificate, and their criticality (including the
KeyUsage
andExtendedKeyUsages
) - Subject name, which dictates how the Distinguished Name of the certificate is built: either from a user-supplied value in the request, or from the identity of the domain principal requesting the certificate
- Issuance requirements: the need for a “CA certificate manager” approval in order to deliver the certificate
- Security descriptor: the ACL of the certificate template, including the identity of the principals who have the extended right needed to enroll to the template
Access Control List of a pKICertificateTemplate object
Enrollment services
The Enrollment Services provides domain principals with the list of enterprise ADCS servers with the domain, under the following naming convention:
CN=<CA name>,CN=Enrollment Services,CN=Public Key Services,...
The attributes of these objects describe these Certification Authorities, how the principals can reach them, and what they are authorized to do:
- The
dNSHostName
attribute corresponds to the FQDN (or alias) of the ADCS server - The
certificateTemplates
attribute lists a subset of the Certificate Templates that the principals are allowed to request certificates for from this Certification Authority - The Security Descriptor (available through the “Security” tab) lists the actions that principals are allowed to do on the Certification Authority or the current domain object: enroll, modify the list of certificate templates, etc.
pKIEnrollmentService object
NtAuth enterprise store
The NtAuthCertificates is a domain object which contains a list of CA certificates (in the cACertificate
attribute). This list dictates which certificates will be valid for authentication purposes across the domain, as authentication services will look for the direct issuer CA within this enterprise store:
NtAuth store contents
It is important to note that workstations and servers (including Domain Controllers) keep a local cached version of this store in the Windows Registry, at the following location:
HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\NTAuth\Certificates
Any update will not be replicated unless the following command is issued locally (or after a while when the machine GPO is refreshed):
gpupdate /force
Other enterprise certificate stores
The Certification Authorities and AIA (Authority Information Access) containers correspond respectively to the Root Certification Authorities and Intermediate Certification Authorities certificate stores for the domain. Every object present in these stores has its cACertificate
attribute set to the certificate of said authority. This enterprise store is automatically replicated within the local stores of domain workstations and servers. Additional parameters, such as crossCertificatePair
, can be also set in some cases.
certificationAuthority object
Certificate revocation list
The CDP (CRL Distribution Point) container aims at providing the domain with Certificate Revocation Lists for each enterprise ADCS server installed. Therefore, each sub-container has an object, which contains the CRL (optionally delta CRL) in the certificateRevocationList
(optionally deltaRevocationList
), named as follows:
CN=<CA name>,CN=<ADCS server>,CN=CDP,CN=Public Key Services,...
cRLDistributionPoint object
Miscellaneous objects
The KRA (Key Recovery Agent) and OID containers describe objects and parameters vital to the ADCS servers, but on which focus is not mandatory in this context.
ADCS server: local configuration
In addition to the global configuration stored in Active Directory, each ADCS server can be locally configured to tune its behavior regarding day-to-day operations. These rights allow users and groups to perform various actions linked to the Certification Authority, such as:
- Certificate request validation
- Certificate revocation
- Certificate Revocation List (CRL) publication
- Certification Authority renewal
- etc.
This extensive set of rights is organized under roles, which limits the fine tuning of access rules but provides a Role Based Access Control (RBAC) mechanism. The following matrix summarizes the 4 roles and the main actions associated with them:
Local rights matrix for ADCS servers
The attribution of roles to users and groups can be configured from the “properties” contextual menu of the Certification Authority instance (using the certsrv.msc
MMC component):
Local attribution of roles on the CA server
Access to these configuration parameters and global PKI operation can be mostly performed remotely using Remote Procedure Call (RPC), via the Microsoft Management Console (MMC).
Mixing it all together!
The heart of the day-to-day interactions with ADCS and CA servers resides in the certificate templates and enrollment services:
- Each enrollment service links to a CA server with the ADCS role – additional settings can be configured locally on a per-server basis, mainly stored in the registry
- The enrollment service lists a subset of the certificate templates published:
ADCS operation overview
Finally, in order to request a certificate, the user / computer must:
- Have the enrollment rights on the Enrollment Service
- And have the enrollment rights on the target Certificate Template
- Be able to reach the CA server on port 135 (RPC) and high dynamic ports (usually start at 49152)
Kerberos, smartcard logon and certificate authentication
Kerberos 101
Authentication in Active Directory is mostly performed using one two authentication protocols:
- The NTLM challenge-response, solely based on the NT hash of the principal
- Kerberos – a protocol originally designed by the MIT – which uses tickets and secrets keys
In its most simple form, Kerberos operates as follows:
- An Active Directory principal (user, computer) emits an AS-REQ request to the Authentication Service (AS); this request contains a pre-authentication message that validates the principal’s identity
- If the authentication succeeds, the AS replies with an AS-REP which includes a Ticket-Granting-Ticket (TGT) delivered by the Key Distribution Center (KDC)
- The principal then sends TGS-REQ requests to the Ticket-Granting-Service (TGS), including the TGT, to ask for an ticket built for an Active Directory service – an AD principal whose
servicePrincipalName
attribute is not empty - The KDC replies with an TGS-REP which includes a Service Ticket (ST) encrypted with the service’s secret key (RC4 key (NT Hash), AES-256 key, etc.)
- The principal can authenticate to said service with an AP-REQ request by sending the ST, which will be decrypted by the service to identify the client principal
- If everything is in order, the service replies with an AP-REP message:
Kerberos authentication graphical representation
Introducing PKINIT
The type of pre-authentication to be used is described in the padata-type
field of the AS-REQ
request. The most common value is PA-ENC-TIMESTAMP
, which works by encrypting a timestamp token with one of the user’s secrets (NT hash, AES key, etc.). The complete list of values that can be used within a Microsoft environment is detailed in [MS-KILE].
Kerberos authentication using smartcards relies on the PA-PK-AS-REQ
value and uses the PKINIT [RFC4556] protocol. This protocol defines how public key cryptography can be used as a pre-authentication mechanism in Kerberos, whereas usually it uses symmetric cryptographic protocols (using shared secrets derived from the password).
PKINIT needs to identify the authenticating Active Directory object based on sent elements, as described below:
Global overview of PKINIT operating
Like in the standard mode, a timestamp token is generated that will later ensure the freshness of the authentication. This token is signed with the user’s private key, the corresponding certificate is sent in the AS-REQ packet and, depending on the type of mapping intended (explicit or implicit), either a principal name or hints that can be used to locate the principal. The detailed operating of the implicit and explicit mappings is described below:
Details of PKINIT operating (source)
Once the Active Directory object is located, depending on the path taken, the certificate will have to meet the NT_AUTH policy, i.e. having its direct issuer’s certificate included in the NtAuth enterprise store.
Then, the authentication server will verify that the certificate « Enhanced Key Usage » extension contains either “Client Authentication” (1.3.6.1.5.5.7.3.2
), “Microsoft Smartcard Logon” (1.3.6.1.4.1.311.20.2.2
), “Key Purpose Client Auth” (1.3.6.1.5.2.3.4
) or “Any purpose” (2.5.29.37.0
).
Finally, the KDC will verify that the certificate provided links to a trusted root Certification Authority, is valid (dates and revocation) and that the signature of the timestamp token is cryptographically correct. If all checks pass, the user is provided with a TGT for the located AD object.
Using PKINIT in real life
The PKINIT protocol is automatically used when smartcard logon is performed. The authentication GUI detects that a smartcard can be used, and, if the user provides the correct PIN, uses the embedded private key to sign the pre-authentication data.
By default, only the associated certificate is sent but administrators can enable the use of “name hints” through local policies (Computer Configuration > Administrative templates > Windows components > Smartcard > Allow username hints):
Providing name hints alongside the certificate
It is also possible to use third-party tools to request a TGT using PKINIT and load it alongside legitimate tickets in the user’s session. In the examples below, the current user has two certificates in its store:
- A certificate named “Explicit” with thumbprint
9c7bd7...1ce0b
and mapped to theAPERTURE\GlADOS
domain user via itsaltSecurityIdentities
attribute - A certificate named “Implicit” with thumbprint
f414...000c8
and including theuserPrincipalName
set ascave@aperture.science
With Kekeo
Kekeo is a piece of software developed by Gentilkiwi, the author of the well-known tool Mimikatz. It aims at providing its users with utilities to easily manipulate Windows API related to Kerberos and other protocols. However, if detected, it is hard to compile anew to evade detection due to the use of the commercial ASN.1/C library.
The screenshots below detail how Kekeo provides support for PKINIT:
Using PKINIT with explicit mapping
Using PKINIT with implicit mapping in kekeo
With Rubeus
As described on the tool’s GitHub repository, Rubeus is a C# toolset for raw Kerberos interaction and abuses. Its advantage comes from the fact that it can be easily recompiled to evade detection from security tools.
The screenshots below detail how Rubeus provides support for PKINIT, although username hints are mandatory since the /user switch must be provided:
Using PKINIT with explicit mapping in Rubeus
Using PKINIT with implicit mapping in Rubeus
Elevating privileges with ADCS
The idea behind exploiting ADCS-related control paths is mostly to fraudulently obtain a certificate to authenticate as a privileged principal using PKINIT. Based on the PKINIT decision graph, there are two ways that certificates that can be used to achieve this purpose:
- For explicit mappings, it needs to be configured on the target object as an alternative security identity
- For implicit mappings, it needs to includes the UserPrincipalName (UPN) of the target principal in the Subject Alternative Name extension
The sections below aim at detailing the prerequisites needed to conduct the attack, and how it can be performed.
Exploiting an existing ADCS misconfiguration
In some cases, no additional ACL exploit is needed because there are existing certificate templates that already validate the prerequisites needed to request an authentication certificate for any other principal:
- The template is listed in at least one of the enrollment services, and both grant the enroll rights to one of the assets (user, computer) already compromised
- The server associated to the enrollment service is reachable on port 135 and high ports
- The template lists at least one of the following extended key usages: Client Authentication, Microsoft Smartcard Logon, Key Purpose Client Auth or Any Purpose
- The template allows supplying the subject name in the request
- No additional approval is required for the certificate issuance; such parameter can be configured at the template level – the list of validators is configured at the server-level and can only be determined by users with at least “Read” privileges on the CA
If all conditions are met, there are multiple options to request the certificate (certreq
executable or the X509Enrollment
COM object in PowerShell), but the fastest is to use the certmgr.msc
MMC component:
Requesting a new certificate with the MMC
At the template selection menu, interesting templates will appear with a yellow warning sign, since they need the requester to supply the name of the subject:
Exploitable certificate template
Then, enter a friendly name in the common name of the certificate (since kekeo needs it to select the certificate), and the UPN of the target user in the alternative name section:
Filling the subject name
After enrollment, the certificate will be present in the Personal store and available to Kekeo and Rubeus to perform PKINIT with the identity of the target user (here administrator@lab.local
):
Kekeo # tgt::ask /subject:ItDoesNotMatter
Authentication certificate retrieved
Subsequent sections present cases in which it is possible to exploit additional misconfigurations in Active Directory or on the ADCS servers to fall back to the situation and the exploit described above.
The insidious case of EDITF_ATTRIBUTESUBJECTALTNAME2
One of the most dangerous and misunderstood of the CA servers’ local settings is EDITF_ATTRIBUTESUBJECTALTNAME2
. It was initially proposed as a way to allow for Subject Alternative Name (SAN) selection when using the certreq
binary on command-line, and can locally be checked with:
C:\Users\Administrator>certutil -getreg policy\editflags
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\CertSvc\Configuration\LAB ROOT CA\PolicyModules\CertificateAuthority_MicrosoftDefault.Policy\EditFlags:
EditFlags REG_DWORD = 15014e (1376590)
EDITF_REQUESTEXTENSIONLIST -- 2
EDITF_DISABLEEXTENSIONLIST -- 4
EDITF_ADDOLDKEYUSAGE -- 8
EDITF_BASICCONSTRAINTSCRITICAL -- 40 (64)
EDITF_ENABLEAKIKEYID -- 100 (256)
EDITF_ENABLEDEFAULTSMIME -- 10000 (65536)
EDITF_ATTRIBUTESUBJECTALTNAME2 -- 40000 (262144)
EDITF_ENABLECHASECLIENTDC -- 100000 (1048576)
CertUtil: -getreg command completed successfully.
This setting forces the CA to accept a user-selected SAN for every certificate template listed by this enrollment service. This means that even if the “Build for this Active Directory information” option is selected in the template options, the final SAN to be included in the certificate will be at the hand of the requester. This setting is fortunately disabled by default.
In this case, every authentication certificate template will be vulnerable to the previous exploit. In order to exploit it, create the following policy.inf file:
[Version] Signature="$Windows NT$" [NewRequest] Subject = "CN=TEST" ; will not be taken into account Exportable = FALSE KeyLength = 2048 KeySpec = 1 KeyUsage = 0xA0 MachineKeySet = FALSE ; TRUE if you want it in the machine store ProviderName = "Microsoft RSA SChannel Cryptographic Provider" RequestType = PKCS10 [Extensions] 2.5.29.17 = "{text}" _continue_ = "upn=username@domain.tld" [RequestAttributes] ; If your client operating system is Windows Server 2003, Windows Server 2003 R2, or Windows XP ; and you are using a standalone CA, SANs can be included in the RequestAttributes ; section by using the following text format. SAN="upn=username@domain.tld" CertificateTemplate = YourTemplateName
Then, the certreq binary is again used to build the request and submit it to the CA server, and finally to add the certificate to the store:
C:\> certreq -new policy.inf request.pem C:\> certreq -submit request.pem cert.pem C:\> certreq -accept cert.pem
Local administrator rights on ADCS server
There are multiple ways that domain and local users that are in the local Administrators group of CA servers can compromise the domain.
First, local administrators have full access to the registry, and therefore they can modify the CA policy settings to include the EDITF_ATTRIBUTESUBJECTALTNAME2
attribute mentioned in the previous section. It will allow the exploitation of any authentication certificate template that is listed by the server, which usually is enough to craft a certificate viable for a PKINIT on a privileged user.
Secondly, local administrators are granted access to the machine certificate store, in which the CA private key is located. From there, there are multiple options to issue an authentication certificate, including:
- Use the
certutil -sign
command to re-sign an authentication certificate issued by the same CA, and modify on-the-fly its subject alternative name list - Export the certificate and its private key, if exportable or by patching the private key file “exportability blob”
- Use Mimikatz to patch the CryptoAPI / CNG and export the certificate along with its private key
ACL exploit on user objects (1)
If one has some control on a domain user object, there are several ways that this object may be compromised. For example, its password can be changed (requires AllExtendedRights
or ForceChangePassword
), granting access to the account (watch out for side effects!).
A more silent way would be to modify the logon script by setting the Scriptpath
attribute which only requires GenericWrite
or specific Write
to the attribute. It will execute any executable or script withing the context of the target’s session when it performs a logon.
There is another way of taking control over a user account (which is also fairly silent) by messing with the altSecurityIdentities
attribute. As detailed in the PKINIT diagram, an explicit mapping can be created between a user object and a certificate, which then can be used to authenticate as the user.
Using the Microsoft Management Console (MMC), it can be performed through the “Active Directory Users & Computers” component:
Adding the MMC component
After enabling the “Advanced Features” in the “View” menu, it is possible to configure mappings through the “Name Mappings” option:
Select the name mappings
Then, just select the certificate that will be used to create the explicit mapping. Note that implicit mappings take precedence over explicit ones, so the certificate must not include an UPN, but it still needs to feature the correct Extended Key Usage:
Creating the explicit mapping
Under the hood, the GUI modifies the altSecurityIdentities
attribute of the user in the following way:
Modification of the altSecurityIdentities attribute
The new value of the attribute is a collection of strings, so it may be modified rather easily with the Set-AdUser
cmdlet or another AD editing tool such as adsiedit.msc
or AD Explorer.
Finally, the authentication can take place, using your favorite tool (Kekeo, Rubeus, etc.):
Authenticating as Admin1 with explicit mapping from Administrator’s certificate
ACL exploit on user objects (2)
There exists another way of leveraging write access to user objects on the domain, however being much noisier and with a higher risk of breaking things.
If one already has an authentication certificate which includes the UPN of a low-privileged user, it will basically consist in modifying the userPrincipalName
attribute of the target account to the value of that UPN. Such situations may arise when access to the enterprise Wi-Fi network is configured to be performed with a certificate, and with “user authentication” rather than “computer authentication”. In our case, we have a certificate with a UPN for User1
:
User1 authentication certificate
Using the write access on the Admin1
user account, we modify its UPN to the one of User1
:
Modification of Admin1 UPN
Finally, using our authentication certificate, it is now possible to perform a PKINIT pre-authentication for both user accounts, using either implicit or explicit mappings:
Authentication as both User1 and Admin1 with User1’s certificate
ACL exploit on certificate templates
If one of the already compromised assets in the domain has write access on a certificate template that is listed in one of the usable enrollment services, then the following modifications will allow the issuance of PKINIT-compliant authentication certificates:
- Set the
msPKI-Enrollment-Flag
attribute to0
: it will remove the need for additional approval set by the flagCT_FLAG_PEND_ALL_REQUESTS
- Set the
msPKI-Certificate-Name-Flag
attribute to1
: it will build the subject name based on the information provided by the requester - Add the one of the required OIDs (for example
3.6.1.5.5.7.3.2
) to themsPKI-Certificate-Application-Policy
set to include the Client Authentication extended key usage
Such modifications can be performed through adsiedit.msc
or via the Set-ADObject
cmdlet from the ADDS Remote Server Administration Tools (RSAT) or with PowerView:
$newAttr = @{} $newAttr['msPKI-Enrollment-Flag'] = '0' $newAttr['msPKI-Certificate-Name-Flag'] = '1' $newAttr['msPKI-Certificate-Application-Policy'] = @('1.3.6.1.5.5.7.3.2') # Set new attributes Set-AdObject "CN=TemplateName,CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration,DC=LAB,DC=LOCAL" -Replace $newParams
ACL exploit on enrollment services
Similarly, write access on enrollment services objects can help the issuance of PKINIT-compliant authentication certificates. The attribute to be targeted is certificateTemplates
since it allows the addition (or deletion) of listed certificate templates.
By default, there is only one certificate template with the correct PKINIT prerequisites in Active Directory, which is “Router (Offline request)”, but only Domain Admins can enroll a certificate with it.
However, the longer a PKI infrastructure lives, the higher the chance to find remnants of tests that will most likely be exploitable. As in the previous section, you can use adsiedit.msc
or PowerShell to add a new template:
$object = "CN=LAB ROOT CA,CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,DC=LAB,DC=LOCAL" $templates = (Get-AdObject $object -Properties *).CertificateTemplates $templates.Add("OfflineRouter") Set-AdObject $object -Replace @{'certificateTemplates'=[System.Array]$templates}
Current mitigations
Integration within the Active Directory tiering model
ESAE: Enhanced Security admin Environment
In Active Directory, it is recommended to partition the administrator privileges according to the type of devices they need to interact with. The theory behind this partitioning of Active Directory is called the tiering model and is described by Microsoft in the Enhanced Security Admin Environment (ESAE). Though the ESAE model is now retired and replaced by the Rapid Modernization Plan (RaMP) to tackle the cloud aspects of hybrid information systems, most of its conclusions still apply regarding on-premise assets.
Tier-0
The idea behind the tiering model is built on isolation between assets in the information system. The most critical assets are in the Tier-0 and defined as:
- Any AD object that allows the compromise of the domain, therefore including the Domain/Enterprise Admins and (Enterprise) Domain Controllers groups
- Any AD object that allows taking over another object in the Tier-0, including, but not limited to: the krbtgt user, the OUs in which Tier-0 objects reside, the GPOs that apply to them, etc.
- Any asset in the Information System that can be used to compromise the Tier-0 or its objects: antivirus and EDR console, standalone WSUS servers, backup infrastructure, etc.
The Tier-0 is consequently defined as the set of assets that have control paths over each other but no other control paths from anywhere else: it is a closed loop in the compromise graph, that also includes non-domain-joint assets.
Tier-1 and 2
All the assets that are not present in Tier-0 are distributed in two other tiers. These tiers are built according to the type of objects they contain:
- Tier-2 contains everything closely related to standard users: their accounts, their workstation, but also TSE servers, the administrative layer that controls these assets, etc.
- Tier-1 is dedicated to hosting assets in relation with the applications: servers that host them, service accounts, administrative workstations (excluding Tier-0)
Tier permeability
The risk of intra-tier compromise is part of the tiering model’s design (even if some Active Directory mechanisms – such as the Protected Users domain group or LAPS – will limit it). However, the tiering model aims at protecting the most critical assets by strictly defining which inter-tier connection are allowed. The set of connections and their status is roughly detailed below:
In the previous diagram, the red arrows represent the impossibility for an administrator of a higher level of administration to open a session to a resource of a lower level. In addition, the yellow arrows indicate the need to limit inter-tier connection to user connections only (e.g. a domain user querying the LDAP service on a DC from his workstation).
The dedicated administrative accounts are to be created in each tier, and their session opening must be restricted to that tier to prevent escalation between tiers. Since the source device of a network connection is also susceptible to credential theft (keylogging, malware spying on memory, etc.), it is preferable that the administrative accounts in each tier are used from an administrative workstation only. This behavior needs to be enforced in the Tier-0, with the use of Privileged Access Workstations (PAW).
Moving ADCS objects up one tier!
All the examples of privilege escalation provided in the “Elevating privileges with ADCS” section consequently point towards the fact that the following AD objects need to be included in the Tier-0:
- The servers on which the ADCS role is installed
- The certificate templates that are published to a public accessible enrollment service
- The enrollment services if there are already certificate templates susceptible to exploitation
To facilitate the handling of these objects over time, it is recommended to include every certificate template and every enrollment service in the Tier-0. This means that there must be no control path over the three object types listed above from somewhere outside of the Tier-0:
- The owner and control ACL over the objects must be positioned on Tier-0 principals only
- The local administrator group of the ADCS servers must be restricted to Tier-0 principals only
Proper handling of corner cases
Context example
Even after the application of all of the recommendations listed above (when possible), there are still legitimate use cases of authentication certificates that needs to be issued to a third party. For example, when one wants to deploy Network Access Control (802.1x) with certificate-based authentication, there are four types of devices to consider:
- The domain-joint devices, which will be able to use the enroll / auto-enroll features
- The devices supporting the Simple Certification Enrollment Protocol (SCEP), which will be able to replicate the enroll / auto-enroll features
- The devices supporting certificates with no support for any enroll / auto-enroll feature whatsoever (e.g. printers)
- The devices that don’t support certificates
In the third case, network administrators would need to issue authentication certificates compliant with the NT_AUTH
policy and including the Fully Qualified Domain Name (FQDN) of the device in the Subject Alternative Names (SAN) section. Since these devices are not domain principals and cannot enroll certificates with the ADCS server, the administrators are required to request certificates on behalf of the devices and to specify the name of the subject in the request.
This situation is the exact context in which the administrators would also be able to issue an authentication certificate including the UPN of a domain administrator in the SAN section, therefore being able to perform PKINIT and authenticate as the domain administrator.
Setting the manager approval
To protect against the malicious use, the certificate templates objects include an option to require the approval of a CA certificate manager:
CA certificate manager approval
When the request for a new certificate is issued, it will appear in the “Pending Requests” section of the ADCS instance, using the certsrv.msc
MMC component:
Pending certificate request
The certificate can later be retrieved by the requester with the following commands:
C:\> certreq -retrieve <ID_REQUEST> file.cer C:\> certreq -accept file.cer
Choosing your CA managers
There are multiple strategies to select who should be able to validate the pending requests, at the ADCS server level:
- Since the issuance of a malicious certificate allows the compromise of a Tier 0 principal, the ideal solution would be to only allow Tier 0 principals on this role; however, this may complexify the issuance process at a large scale
- The alternative is to enable Tier 1 administrators to perform this action: in this case, the groups allowed to request the certificate need to be completely disjoint from the groups allowed to approve the requests. Note that even in this situation, control over accounts from both groups is sufficient to take over Tier 0 principals
Alternative to Tier-0 validators only
Adding the detection layer
The extensive guide about adding an ADCS logging facility would not fit in this article. However, there are some useful resources about how to enable logging and what to log:
- An introduction to Golden Certificates (by C. Falta): the “Defending against Golden Certificate” gives very interesting insight on how to monitor the certificate template changes, which would certainly help in detecting some ACL exploits
- Securing PKI: Monitoring Public Key Infrastructure (by Microsoft): this article is the reference regarding the configuration of ADCS logging and provides information on what event IDs are raised when specific events occur
Special thanks to @RémiEscourrou, @ClémentNotin and @Pixis for their help on this subject,
and stay tuned for @harmj0y‘s presentation at Black Hat US on this topic!