Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ESC15/EKUwu PR #228

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open

ESC15/EKUwu PR #228

wants to merge 4 commits into from

Conversation

dru1d-foofus
Copy link

@dru1d-foofus dru1d-foofus commented Oct 7, 2024

Initial PR of ESC15 attack discovered and disclosed by Justin Bollinger from TrustedSec (https://x.com/Bandrel)

Edit: Here are some additional details about the attack.

As other people have noted, this is essentially ESC1 without the need to have a "Client Authentication" EKU. I didn't RE all of the binaries/libraries associated with Windows ADCS (I tried, but it's a lot) - so I don't have a clear picture on all of the internals that lead to this specific edge case. I am able to surmise that this is possible for a few different reasons:

  1. Schema Version 1 templates do not contain a populated msPKI-Certificate-Application-Policy (https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-crtd/44012f2d-5ef3-440d-a61b-b30d3d978130) attribute whereas templates with version 2+ have it populated automatically. If you delete that attribute on a version 2+ template, you'll actually find it vulnerable to multiple ESC bug classes.
  2. Only templates where enrollee supplies SAN are vulnerable (in my testing). It appears that you can only supply the application policies extension on a request where you are already providing a SAN. While trying to supply EKU on certificate templates that do not support enrollee supplied SAN, the supplied application policy extension does not stay populated on the requested certificate.
  3. These requested certificates do not support PKINIT out of the box. However, you can essentially conduct an ESC3-style attack by just supplying the Certificate Enrollment Agent EKU via ESC15 and request a User certificate template to address that hurdle.

This is not something that is vulnerable default, like many other ADCS vulnerabilities. You have to go out of your way to create a vulnerable condition. Microsoft's own documentation does not recommend ever configuring a certificate in this way and they actually would advise against it. However, other vendors/third-parties are not as scrupulous. Here are a few interesting examples I found during my research into this vulnerability:

I've had over a month working with this fork and during the testing of several client organization, found instances where a vulnerable certificate template was available - typically the WebServer template and I believe it because of the proliferation of bad third-party vendor documentation.

Honorable mentions: TrustedSec released their internal BOF that also exploits this vulnerability. You can snag it from https://github.com/trustedsec/CS-Remote-OPs-BOF

@daddycocoaman
Copy link

Crazy that you snitched. 😭

@dru1d-foofus
Copy link
Author

Crazy that you snitched. 😭

Hello, @daddycocoaman/Ohm-I!

I have published my fork of Certipy for several reasons:

  1. Details about the attack have already been publicized.
  2. Other people have already figured out how to replicate it.
  3. Due to the overwhelming amount of bad vendor documentation encouraging people to misconfigure templates, a way to test and validate this vulnerability needed to be brought to light.

I wrote this code based on information that was made public over a month ago and have provided credit to the original researcher who discovered it. It's still their work and I'm not taking that away from them. However, this is my work and I have a right to publish it.

Thanks!

@daddycocoaman
Copy link

Crazy that you snitched. 😭

Hello, @daddycocoaman/Ohm-I!

I have published my fork of Certipy for several reasons:

  1. Details about the attack have already been publicized.
  2. Other people have already figured out how to replicate it.
  3. Due to the overwhelming amount of bad vendor documentation encouraging people to misconfigure templates, a way to test and validate this vulnerability needed to be brought to light.

I wrote this code based on information that was made public over a month ago and have provided credit to the original researcher who discovered it. It's still their work and I'm not taking that away from them. However, this is my work and I have a right to publish it.

Thanks!

You do you. Many of us have implementations but I just hope that you discussed the impact on the researcher and their company before dropping this specifically for public consumption because some things go beyond technical implications.

PR looks great though!

@linuxkd
Copy link

linuxkd commented Oct 7, 2024

First off, this is awesome. Wanted to point out though that the PR has some comments removed that are links to the official documentation related to the functionality, specifically in req.py. Probably worth sticking those back in.

Adding back initial comments explaining how certipy handles requests.
@dru1d-foofus
Copy link
Author

First off, this is awesome. Wanted to point out though that the PR has some comments removed that are links to the official documentation related to the functionality, specifically in req.py. Probably worth sticking those back in.

@linuxkd - I have added those comments back. That was a Copilot thing as I was trying to ensure my additions were in the style of the original project.

@network-node
Copy link

Justin Bollinger (https://github.com/Bandrel) is smart as hell. Not shocked he figured it out. Credit to him for finding this <3

@spyr0-sec
Copy link

After playing around with this, I've noticed there are currently false positives in regards to the identification of ESC15 templates as there is no check against the msPKI-Certificate-Application-Policy attribute values.

In this example I have a template which is reporting as vulnerable:

Pasted image 20241009224519

Pasted image 20241009224630

However, when requesting a certificate, authentication does not work as the application policy overrides any additional polices:

Pasted image 20241009224735

Pasted image 20241009224800

This is confirmed in the issued certificate:

Pasted image 20241009224913

Pasted image 20241009224931

Removing the application policies from the certificate results in obtaining a certificate with the requested client authentication policy

Get-ADObject "CN=ESC15,CN=Certificate Templates,CN=Public Key Services,CN=Services,$((Get-ADRootDSE).configurationNamingContext)" -Properties * | Set-ADObject -Clear 'msPKI-Certificate-Application-Policy', 'pKIExtendedKeyUsage'

Pasted image 20241009225209

@daddycocoaman
Copy link

daddycocoaman commented Oct 9, 2024

@spyr0-sec It's known that requesting the cert with Client Authentication can't be used for PKINIT client auth (it works for SChannel, so you can use that original cert with certipy auth -ldap-shell), so that's not a false positive.

However, you might have just solved the PKINIT issue by removing the pKIExtendedKeyUsage and policies all together.

@spyr0-sec
Copy link

spyr0-sec commented Oct 9, 2024

Thats what I get for jumping in with two feet before getting to the end of the blog post!

I've just tried -ldap-shell and I get an error 😕

LDAPS is definitely configured in the lab and this is with a certificate where it just has EFS application policies

image

image

image

I've tried with all the different options available. Will have to come back to it tomorrow

@daddycocoaman
Copy link

@spyr0-sec Just to clarify, you still need the cert to have Client Auth app policy (from your second screenshot). It cannot be used for PKINIT but it can be used with -ldap-shell.

@evilmog
Copy link

evilmog commented Oct 10, 2024

You can also request a certificate enrollment agent certificate and then direct request a certificate on behalf of any other user which can pkinit

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants