Experts Blog

PKINIT FTW - Chaining Shadow Credentials and ADCS Template Abuse
September 8, 2021
Matthew Creel

On a recent red team engagement, our team was tasked with focusing on Active Directory Certificate Services (ADCS) exploitation. The objective was to identify certificate template misconfigurations and potentially achieve privilege escalation by abusing them. The concepts and attacks used were based around the work and whitepaper by Will Shroeder (@harmj0y) and Lee Christensen (@tifkin_).

While many organizations with ADCS implementations are uncovering extremely compromising misconfigurations as a result of the ADCS research, we did not find any certificate template configurations that offered instant privilege escalation opportunities. In other words, the Domain Users group and other low-privilege, high-member groups were not granted enrollment rights to any certificates. Upon deeper examination, we did identify several certificates that appeared to open the door to privilege escalation through the ENROLLEE_SUPPLIES_SUBJECT flag.

However, compromising an account with enrollment rights to one of these certificates was going to require serious account compromise efforts by our offensive team.

Eventually, compromise of a mid-tier administrative account allowed us to incorporate the Shadow Credentials attack, described by Elad Shamir (@elad_shamir), to aid in completion of privilege escalation through a vulnerable certificate template. I have set-up my lab environment in a very similar configuration to showcase the combined capabilities of several recently released tools, all of which relate to PKINIT authentication.

Scenario

I have a Cobalt Strike beacon running as a standard user on a Windows 10 box in the lab environment:

We can perform an initial check for vulnerable templates with Certify from beacon. Ultimately, no vulnerable certificates are found – the one vulnerable template, VULN, is not published by the CA.

Let’s gather information on all the published templates. To do this, we can simply remove the /vulnerable flag from the previous certify command.

One particular certificate template stands out. Three (3) attributes that make this template interesting:

  1. The ENROLLEE_SUPPLIES_SUBJECT flag is present. This allows the enrollee to specify a subject alternative name (SAN), essentially allowing a certificate to be requested for another user.
  2. Authentication is enabled via the CLIENT AUTHENTICATION extended key usage (EKU).
  3. Enrollment rights contains the normal domain/enterprise admins, but also an additional group, REDANIA\TIER 1 ADMINS.

Compromise of an account belonging to the Tier 1 Admins group could allow us to request this certificate for an arbitrary user, including a domain admin. Checking BloodHound for group members shows two targets:

Both of these accounts are solely members of the Domain Users and Tier 1 Admins groups. In theory, these accounts are significantly privileged, but not as privileged as Domain Admins. Using BloodHound again, we can do some pathfinding to see if we have any ways to compromise one of these accounts. Similar to our position during the real engagement, assume we have already used our initial access to compromise Kerberos ticket-granting-tickets (TGTs) for a handful of users, including REDANIA\philippa:

Seeing that we have control over an account with GenericAll permissions over one of our targets through the Tier 2 Admins group, we can lay out our plan. Everything below will be performed using beacon’s SOCKS proxy feature to help limit EDR insight into our actions.

Abusing Shadow Credentials

With GenericAll permissions over Ori’s AD account, previous methods of exploitation may have included resetting the account’s password or setting a SPN and kerberoasting the account. These methods are either disruptive or do not guarantee account takeover. However, following Elad’s research, we can use GenericAll/WriteOwner/WriteDACL permissions over the user object to set the msDS-KeyCredentialLink attribute. This attribute holds data including a public key, which allow the account to perform Kerberos pre-authentication using a public-private key pair. By setting this attribute with a key pair we control, we can request a TGT (using PKINIT!) for the target account, guaranteeing account compromise without disrupting its use. Boiled down to one sentence, PKINIT is the asymmetric key method of Kerberos pre-authentication (with the symmetric method being reliant on the client’s password). PKINIT is not possible out of the box in every Windows network – I recommend reading Elad’s research for full details and requirements related to the attack.

PyWhisker will be used to perform the Shadow Credential attack from Kali through the SOCKS proxy – which we need to setup.

After ensuring proxychains configurations are set, I will start off by setting the KRB5CCNAME environment variable to the location of the previously stolen TGT for REDANIA\philippa. In the subsequent command, Kerberos authentication is used with PyWhisker’s add action to authenticate to a domain controller (Oxenfurt) and add a KeyCredential to Ori’s user object:

In the output, we can see the DeviceID corresponding to the new KeyCredential and the new PFX certificate file (and password for the PFX file). We can verify that the KeyCredential has been set by using PyWhisker’s list action:

After the Shadow Credentials have been set, we can use the PKINITtools suite to request a TGT as REDANIA\Ori. The gettgtpkinit.py script used with references to the PFX file and password generated with PyWhisker will result in a valid TGT for Ori:

Exploiting the Certificate Template Configuration

Returning to our main objective, ADCS, we have now compromised an account belonging to the Tier 1 Admins group, which can enroll in the certificate identified earlier. Certi will be used to perform ADCS exploitation through the SOCKS proxy. Again, start by exporting the latest Kerberos TGT we obtained. The certi.py arguments are specifying my lab’s CA server (Tretogor, which doubles as a CA and DC), Kerberos authentication, the SAN (we want a certificate for REDANIA\Administrator) and the vulnerable template to enroll in:

In the output we can see the certificate was successfully issued and saved in a file. (This escalation vector corresponds to ESC1 in the white paper.) The previous process for requesting a TGT using PKINIT can be repeated to obtain a TGT for REDANIA\Administrator, but this time pass in the certificate issued by the CA in the arguments:

I will verify the validity of the TGT by opening a wmiexec shell on one of the lab DCs as REDANIA\Administrator:

Success! We’ve found a way to obtain domain admin rights using multiple PKINIT based exploitation methods. Most of these concepts and tools have only been recently published (at least publicly) and after gaining familiarity with them, I believe they will be strong tactics in the offensive arsenal moving forward.

Cleaning Up the Shadow Credentials

The last important note is that the KeyCredential we set with PyWhisker can be safely be removed using the remove action in conjunction with the DeviceID corresponding to the KeyCredential we generated. After removal, we can verify it no longer exists with the list action.

Mitigation and Detection Strategies

Several high-level strategies that could be used to remediate or alert on activity performed in the described scenario are below.

ADCS:

  • Removal of the ENROLLEE_SUPPLIES_SUBJECT flag will prevent certificates from being obtained as any domain account.
  • If the ENROLLEE_SUPPLIES_SUBJECT flag cannot be removed, requiring certificate manager approval before a certificate is issued will help mitigate the risk posed by the presence of the flag.
  • Restrict enrollment rights to only users and groups that absolutely require access.Monitor certificate enrollments (event ID 4886) – Important to note here that the event logs do not contain all data related to the certificate, such as the SAN.

Shadow Credentials:

  • Perform attack pathfinding using BloodHound and remove unneeded ACL abuse avenues, specifically GenericAll, WriteOwner and WriteDACL relationships.
  • Monitor for Kerberos TGTs requested(event ID 4768) using PKINIT authentication, if the behavior is not standard for the network environment or account.
  • Monitor for AD object modifications (event ID 5136) where the attribute being modified is msDS-KeyCredentialLink.

References

  • https://specterops.io/assets/resources/Certified_Pre-Owned.pdf
  • https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab
  • https://www.thehacker.recipes/ad-ds/movement/kerberos/shadow-credentials
  • https://twitter.com/_nwodtuhs/status/1422304102915182593/photo/1
  • https://github.com/GhostPack/Certify
  • https://github.com/eladshamir/Whisker
  • https://github.com/ShutdownRepo/pywhisker
  • https://github.com/GhostPack/Rubeus
  • https://github.com/dirkjanm/PKINITtools
  • https://github.com/eloypgz/certi
  • https://github.com/BloodHoundAD

For additional information on Fortalice Solutions service offerings, contact the team via email at watchmen@fortalicesolutions.com

Let's Talk
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.