Partie 2 – D’ESC2 à ESC8
Introduction
Dans le dernier article, nous avons pu voir le fonctionnement général de l’authentification par certificat dans un environnement Windows ainsi qu’une première vulnérabilité : ESC1.
Maintenant que les bases sont acquises, nous allons pouvoir nous pencher sur la suite des vulnérabilités issues des recherches sur AD CS.
ESC2
ESC2 est similaire à ESC1 quoique moins critique. Un modèle de certificat y est vulnérable lorsqu’il regroupe les conditions suivantes :
- Le modèle de certificat et l’autorité de certification autorisent tous les deux l’enrôlement par un utilisateur non-privilégié. Rien de choquant ici, de nombreux certificats sont utiles aux utilisateurs génériques.
- La requête de certificat ne nécessite pas la validation par un manager ou un nombre non-nul de signatures. Un peu plus problématique mais c‘est le fonctionnement par défaut et donc assez répandu.
- Le certificat obtenu via le modèle possède un champ EKU vide ou configuré sur Any Purpose.
OK, et pourquoi est-ce grave alors ? Eh bien une EKU Any Purpose permet, comme les anglophones auront déjà deviné, de se servir du certificat pour toute opération. En somme, si je compromets les identifiants d’un compte, je peux demander un certificat permettant l’authentification client et serveur ainsi que la signature de binaire, le chiffrement de données, etc…
Une EKU vide, correspondant à une EKU SubCA, permet quant à elle de se servir du certificat pour toute opération et aussi pour signer de nouveaux certificats. Un tel certificat est considéré comme une CA subordonnée et, bien que l’AD CS ne lui fasse pas confiance par défaut, il pourra tout de même être utilisé pour signer tout certificat qui n’est pas lié à une authentification.
Il est alors possible de demander un certificat que l’on utilisera comme Certificate Request Agent1 puisque nous avons le droit de l’utiliser pour n’importe quoi (« AnyPurpose ») :
Grâce à ce Certificate Request, je peux demander un certificat pour agir entant que n’importe quel utilisateur arbitraire. La CA validera la demande car elle la considèrera comme signée par une CA-subordonnée :
Il est ensuite possible de s’authentifier avec le certificat généré pour l’utilisateur que nous avons ciblé :
ESC3
ESC3 est similaire aussi mais nécessite plus de prérequis pour une exploitation réussie. En effet, elle exploite une EKU appelée Enrollment Agent qui permet à l’utilisateur demandant ce certificat de s’en servir pour signer une requête de certificat à la place d’un utilisateur via un modèle autorisant explicitement ce processus.
Pour être précis, il faut donc que deux modèles de certificat distincts soient présents :
- Un modèle qu’un utilisateur peu privilégié peut requérir sans validation particulière et avec l’EKU Enrollment Agent (ou Any Purpose/SubCA, voir ESC2)
- Un modèle qu’un utilisateur peu privilégié peut requérir et qui autorise la demande par la signature via un certificat possédant une EKU Certificate Request Agent. Ce modèle doit également posséder une EKU permettant l’authentification client (Client Authentication ou Any Purpose/SubCA).
Le modèle de certificat ESC3 permet à un utilisateur peu privilégié de demander un certificat sans validation supplémentaire :
Si ces deux conditions sont réunies, il est possible de compromettre tout compte du domaine à nouveau !
La commande suivante permet de récupérer le premier certificat de votre utilisateur au format pfx :
Cette commande-ci permet ensuite d’obtenir le certificat du compte de votre choix au format pfx :
Il est alors possible de l’utiliser pour s’authentifier avec le compte administrator :
ESC4
Là, on arrive sur une vulnérabilité un peu différente. En effet, les modèles de certificats restent au final des objets AD et reprennent donc les notions d’ACL auxquelles nous sommes habitués.
Puisque certaines configurations sont vulnérables, il va de soi qu’avoir certains droits d’écriture sur les modèles permet de modifier leurs paramètres de façon à retomber sur une configuration non-sécurisée, par exemple celle qui permet d’exploiter ESC1 !
C’est donc ça le cœur de la vulnérabilité ESC4 : si mon utilisateur a les droits de modification sur un modèle qu’il peut utiliser et qui permet l’authentification client, je peux par exemple activer le flag CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT et je retombe sur le scénario ESC1.
Les droits en question sont :
- Owner : J’ai tous les droits sur l’objet et je peux donc évidemment modifier ses propriétés.
- FullControl : J’ai également tous les droits.
- WriteOwner : Je peux modifier le propriétaire de l’objet afin de le remplacer par un utilisateur que je contrôle.
- WriteDacl : Je peux modifier les ACL et me donner le droit FullControl.
- WriteProperty : Je peux modifier les propriétés de l’objet.
Voici un exemple de modèle de certificat repéré par Certipy comme étant vulnérable à ESC4.
Certipy, en tant que couteau-suisse de qualité, permet également de très facilement modifier ce dernier tout en sauvegardant l’ancienne configuration pour la restaurer :
Cette commande va configurer le modèle ciblé pour le rendre vulnérable à ESC1 tout en sauvegardant la configuration initiale via l’option save-old.
On peut alors vérifier la configuration du template pour s’assurer de sa modification, on peut facilement voir la différence entre les éléments en bleu dans le modèle précédent et ceux en rouge de ce modèle mis à jour :
Pour l’exploitation de la vulnérabilité ESC1, je vous renvoie directement au premier article de ce corpus.
Une fois l’attaque réussie, l’ancien modèle peut être redéployé via la commande suivante :
ESC5
ESC5 repose quant à elle sur des défauts de configuration plus généraux mais entraînant in fine la compromission de l’ AD CS. Par exemple, si je compromets le compte machine d’un serveur de CA ou si je compromets le serveur COM utilisé par le serveur de la CA pour les appels RPC/DCOM, je peux potentiellement compromettre l’AD CS.
La recherche de Specter Ops n’a pas détaillé d’attaques ESC5 car le sujet est vaste. Cependant, une piste peut être d’utiliser Certify.exe, l’outil développé par SpecterOps pour lister les ACL des différents objets liés à la PKI via la commande suivante :
Si des défauts d’ACL sont constatés, l’AD CS est à risque de compromission. En effet, l’attaque dite du Golden Certificate2 permet à un attaquant ayant des droits d’administration sur un serveur CA d’obtenir un accès persistant pour compromettre le domaine.
L’attaque en elle-même consiste à extraire la clef privée et le certificat de la CA au format .p12, par exemple via une connexion RDP et un accès à l’utilitaire certsrv.msc ou via des utilitaires tels que Mimikatz, Seatbelt, SharpDPAPI ou…Certipy ! Décidément, il est partout. La commande pour extraire le certificat de la CA via un compte ayant des droits d’admin dessus est la suivante :
Une fois ces objets en notre possession, on peut maintenant délivrer nous-même des certificats valides ! Encore une fois, plusieurs utilitaires tels que Mimikatz, ForgeCert ou Certipy peuvent être utilisés.
Sur ce dernier, la commande à faire pour générer un certificat est :
Similairement à ESC1 et ESC3, je suis en possession du certificat de l’utilisateur de mon choix. Je peux alors m’authentifier avec ce certificat et compromettre le compte :
Note :
Si une tentative d’authentification avec le certificat nouvellement généré renvoie une erreur KDC_ERROR_CLIENT_NOT_TRUSTED, cela signifie que le certificat forgé n’est pas correct et, selon Oliver Lyak3, vient d’un écart au niveau de la CRL. Une valeur manuelle peut être passée via -crl ou un certificat valide peut être utilisé comme modèle via l’option -template.
ESC6
Note : ESC6 a été rendue inefficace par un patch Microsoft publié en Mai 2022 mais je laisse les détails d’exploitation ici bien que ça n’arrive jamais qu’un système ne soit pas maintenu à jour (🤨)
Cette vulnérabilité est assez brutale et ressemble fortement à l’exploitation d’ESC1. En effet, là où cette dernière découle d’un modèle de certificat possédant le flag CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT permettant à l’utilisateur de spécifier le subject Alternative Name (SAN) que le certificat permet d’identifier, ESC6 repose plutôt sur le flag EDITF_ATTRIBUTESUBJECTALTNAME2 configuré directement sur la CA.
Ce que cela signifie ? Eh bien plutôt que de restreindre la faille à un seul modèle, ce flag rend tous les modèles de certificat vulnérables à ESC1. Rien que ça !
Voici un exemple de CA vulnérable détectée par Certipy :
Ainsi, si le système n’est pas patché, il suffit de prendre n’importe quel modèle de certificat qui permet l’authentification du client et que notre utilisateur peut requérir afin d’exploiter ESC1 sur ce dernier, c’est notamment le cas du modèle User présent et actif par défaut sur les CA. Pour l’exploitation de ESC1, je vous renvoie directement vers le premier article de notre corpus.
ESC7
Vous vous rappelez d’ESC4 où l’on a vu qu’un modèle de certificat n’est au final qu’un objet AD avec ses ACL ? Eh bien vous ne devinerez jamais ce que sont les CA !
Eh oui, des objets AD avec leurs propres ACL ! Elles sont un peu différentes de celles auxquelles nous sommes habitués mais elles sont assez simples à comprendre. Celles qui nous intéressent sont les suivantes :
- ManageCA – Avec ce droit, je peux modifier les propriétés de la CA, ce qui a deux conséquences. Premièrement, si le patch de Mai 2022 mentionné dans ESC6 n’est pas installé, je peux activer le flag EDITF_ATTRIBUTESUBJECTALTNAME2 pour rendre la CA vulnérable à ESC6. Deuxièmement, je peux attribuer le droit Manage Certificates (la deuxième ACL qui nous intéresse) à un utilisateur que je maîtrise.
Pour se faire, on fait à nouveau appel à Certipy :
- ManageCertificates – Vous vous rappelez la mesure de sécurité Manager approval ? C’est une des recommandations à mettre en place pour protéger les modèles de certificat en requérant la validation manuelle d’une personne habilitée avant de donner un certificat à l’utilisateur. Eh bien le droit ManageCertificates permet, en plus d’activer des modèles potentiellement vulnérables mais désactivés, de valider ces requêtes et donc de contourner cette mesure !
Toujours avec Certipy,voici les commandes qu’on peut utiliser :
Tout d’abord, pour activer un modèle vulnérable à ESC1 par exemple mais nécessitant la validation d’un manager. C’est le cas pour le modèle SubCa présent par défaut sur toutes les CA :
Pour effectuer une requête, ici en exploitant ESC1, et la valider soi-même :
Plusieurs éléments sont importants ici. Tout d’abord, on peut noter l’échec de la requête. Pour autant, on obtient quand même l’ID de notre requête. Grâce à aux droits ManageCA que l’on s’est attribué tout à l’heure, je peux valider ma propre requête :
Maintenant que la requête a été validée par un Manager, soit moi-même, je peux retrouver mon certificat :
Et hop, j’ai réussi à récupérer mon certificat alors que le modèle était désactivé et nécessitait la validation d’un manager ! A nouveau, avec ce certificat je peux compromettre l’intégralité du domaine.
ESC8
Aaaaah, ESC8… Probablement la plus brutale des vulnérabilités liées à AD CS et celle qui peut permettre de compromettre un domaine en moins de 5 minutes.
Sans perdre de temps, commençons par parler de la racine du problème.
Vous vous rappelez plus haut quand j’ai dit que l’enrôlement se faisait généralement par RPC mais parfois par HTTP ? Eh bien un AD CS est vulnérable à ESC8 s’il autorise ce fameux enrôlement HTTP (ouWeb Enrolement) sans mettre en place de protection contre le relai NTLM ce qui, soyons honnête, est le cas 99% du temps si l’enrôlement HTTP est activé.
Pour vérifier, certipy est globalement assez doué pour le remonter lors de la phase de reconnaissance mais il est possible de le confirmer en vérifiant si le contrôleur de domaine expose un port HTTP et si l’interface d’enrôlement est bien présente à l’adresse http(s)://<IP_du_DC>/certsrv (dans le cas de notre lab http://192.168.56.23/certsrv,l ’adresse de notre CA) :
Très bien, maintenant en quoi consiste l’attaque ? Eh bien de façon assez évidente, si un utilisateur peut demander un certificat via le protocole HTTP et que je peux faire du relai NTLM vers le protocole HTTP, je peux relayer une action authentifiée vers le service d’enrôlement d’un certificat permettant l’authentification client afin d’obtenir un certificat permettant d’identifier l’utilisateur relayé.
Ca tombe bien, HTTP est idéal pour le relaying NTLM :
Bon, bon… Compromettre un utilisateur c’est pas mal, surtout que ça permet de pérenniser un accès à partir d’un simple relai NTLM qui est, par définition, unique et éphémère. Mais moi je vous ai promis du sang et des larmes, et je ne vous ai pas menti, on y vient.
La beauté d’ESC8 c’est qu’on est limité que par l’utilisateur qui est relayé et les modèles de certificat qui sont accessibles par cet utilisateur. Ça signifie que si je relaye un compte machine et qu’un modèle de certificat pouvant être demandé par ces derniers permet l’authentification (comme, par exemple, le modèle par défaut Machine, ou nous allons le voir plus tard DomainController), je peux le compromettre également.
Il s’avère qu’un compte machine très sympathique existe sur les environnements AD Windows, c’est celui du contrôleur de domaine qui possède, entre autres, les droits de réplication et donc peut être utilisé pour la fameuse attaque de DCSync4.
Il s’avère également que plusieurs vulnérabilités existent pour forcer l’authentification de comptes machines, heureuse coïncidence ! La plus répandue est PetitPotam5 qui n’est pas complètement patchée par Microsoft et est donc généralement présente même sur un système à jour.
On récapitule :
- J’accède au réseau interne et j’effectue ma phase de reconnaissance sur le réseau. Je découvre ainsi qu’un AD CS est configuré et que l’enrôlement HTTP l’est aussi.
- Je mets en place mon relai NTLM qui va attendre une connexion en tentant ma chance pour le modèle par défaut DomainController :
Lespuristes peuvent utiliser ntlmrelayx.py mais certipy fait très bien l’affaire.
- Je tente ma chance avec PetitPotam :
- Si tout a fonctionné, j’obtiens le certificat du compte machine du contrôleur de domaine, ce qui est notre cas grâce aucertificat meereen.pfx que je peux utiliser pour m’authentifier auprès du DC légitime et compromettre le domaine !
Note de bas de page
2. https://pentestlab.blog/2021/11/15/golden-certificate/
3. https://github.com/ly4k/Certipy/blob/main/README.md
4. https://posts.specterops.io/domain-of-thrones-part-i-c183ee4bf379
5. https://github.com/topotam/petitpotam