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_).
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.
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.
One particular certificate template stands out. Three (3) attributes that make this template interesting:
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.
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.
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:
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.
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.
Several high-level strategies that could be used to remediate or alert on activity performed in the described scenario are below.
For additional information on Fortalice Solutions service offerings, contact the team via email at email@example.com