En aidant Andrew Schwartz avec son article sur Kerberos FAST (qui contient plus d'informations sur ce qu'est FAST et comment il fonctionne, alors lisez-le), j'ai remarqué quelque chose d'intéressant. Les AS-REQs pour les comptes machines ne sont pas blindés. L'armure Kerberos est décrite par Microsoft :
Le blindage Kerberos utilise un ticket d'octroi de ticket (TGT) pour le périphérique afin de protéger les échanges de services d'authentification avec le KDC, de sorte que l'échange de services d'authentification de l'ordinateur n'est pas blindé. Le TGT de l'utilisateur est utilisé pour protéger ses échanges TGS avec le KDC.
Je me suis donc demandé s'il était possible de demander des tickets de service (ST) au service d'authentification (AS). La possibilité de demander des ST au service d'authentification a plusieurs conséquences, notamment de nouvelles voies d'attaque, des contournements de détection et un affaiblissement potentiel des contrôles de sécurité. Tous les problèmes évoqués dans ce billet ont été signalés à Microsoft et ont été "considérés comme relevant de la conception"(figure 1).
Lecture associée
Récapitulation de Kerberos
Tout d'abord, voici une vue d'ensemble du flux Kerberos typique(figure 2, tirée d'ADSecurity) :
- Un compte demande un TGT au contrôleur de domaine (DC).
- Le DC répond par un TGT, qui possède sa propre clé de session.
- Le TGT et sa clé de session sont utilisés pour demander un ticket de service (ST) au DC.
- Le DC répond par une ST, qui possède sa propre clé de session.
- Le ST et sa clé de session sont utilisés pour s'authentifier auprès du service final.
- Le service final accorde ou interdit l'accès.
Le fait qu'une clé de session soit émise pour chaque ticket est une caractéristique importante pour les recherches suivantes. Cette clé de session est renvoyée au compte demandeur dans une section cryptée de la réponse ; la clé de cryptage est déjà connue du demandeur.
Par exemple, la clé de session TGT est stockée dans une section qui est cryptée avec la clé utilisée pour prouver l'identité du demandeur lors de la demande de TGT. Cette clé est normalement la clé à long terme (hachage du mot de passe) du compte. Mais dans le cas de la cryptographie à clé publique pour l'authentification initiale (PKINIT) dans le protocole Kerberos, la clé est dérivée du certificat. La clé de session ST est stockée dans une section qui est cryptée avec la clé de session TGT.
La clé de session du ticket est nécessaire pour utiliser le ticket à l'étape suivante du flux Kerberos.
Une demande Kerberos comporte deux parties principales :
- padata (données de préauthentification)
- req-body (corps de la demande)
Le corps de la demande est envoyé principalement en texte clair et contient plusieurs informations :
- kdc-options: diverses options
- cname: nom du compte demandeur (facultatif)
- realm: nom de domaine
- sname: nom du principal de service (SPN) pour le ticket résultant (optionnel)
- à partir de : heure à partir de laquelle le client souhaite que le billet soit valable (facultatif)
- till: durée jusqu'à laquelle le client souhaite que le ticket soit valide
- rtime: l'heure de renouvellement demandée (facultatif)
- nonce: nombre aléatoire
- etype: liste des types de cryptage pris en charge par le client
- adresses: liste des adresses du client demandeur (facultatif)
- enc-authorization-data: diverses sections de données d'autorisation, cryptées avec la clé de session habituellement utilisée pour les privilèges locaux (facultatif).
- additional-tickets: liste des billets requis pour la demande (facultatif)
Une réponse Kerberos comporte plusieurs sections et contient une partie cryptée :
- pvno: numéro de version
- msg-type: type de message (11 AS, 13 TGS)
- padata: données de préauthentification (facultatif)
- crealm: nom de domaine du client
- cname: nom du compte demandeur
- ticket: ticket résultant
- enc-part: données cryptées à l'usage du client
Le problème des tickets de service demandés par les AS
La partie du flux Kerberos sur laquelle ce billet se concentre est AS-REQ/AS-REP, qui est généralement utilisée pour demander un TGT. Dans les opérations normales, un AS-REQ a l'une des deux valeurs suivantes dans son champ sname à l'intérieur du corps de la requête :
- krbtgt/domain.local : utilisé pour demander un TGT initial
- kadmin/changepw: utilisé pour demander un ticket de courte durée, qui peut être utilisé pour réinitialiser les mots de passe à l'aide d'un message KRB-PRIV (défini dans la RFC 3244).
J'ai remarqué qu'avec Kerberos Flexible Authentication Secure Tunneling (FAST), les comptes machines envoyaient toujours leurs AS-REQs non blindés. Je me suis demandé si un AS-REQ pouvait être utilisé pour demander un ST directement, plutôt qu'un TGT. J'ai donc modifié Rubeus pour déterminer si le fait de spécifier un autre SPN dans le sname d'un AS-REQ amènerait le DC à répondre avec un ST pour ce SPN. Il s'avère que la réponse est "oui"(Figure 3).
En utilisant un compte machine, je peux demander une ST sans utiliser l'armure lorsque la FAST est appliquée. Quelles sont les autres possibilités ?
De nouvelles voies pour Kerberoast
Kerberoasting, découvert par Tim Medin, est une méthode permettant de récupérer le mot de passe en clair ou le hachage NT d'un compte de service, généralement un compte d'utilisateur avec un SPN. Le Kerberoasting est possible parce qu'une partie d'un ST est chiffrée avec la clé à long terme du compte de service (hachage du mot de passe). En extrayant la partie chiffrée du ticket, il est possible de former un hachage à partir de plusieurs mots de passe en clair et de tenter de déchiffrer la partie chiffrée. Si le décryptage réussit, le hachage utilisé est la clé à long terme utilisée pour crypter le billet. Cette clé peut ensuite être utilisée pour s'authentifier en tant que compte de service.
En outre, n'importe quel compte peut demander une ST pour n'importe quel service. Par conséquent, la capacité à s'authentifier auprès d'Active Directory (AD) est nécessaire pour réaliser l'attaque. Du moins, c'était le cas auparavant.
Kerberoasting sans pré-authentification
Tout d'abord, j'ai essayé d'utiliser un compte ne nécessitant pas de préauthentification(DONT_REQ_PREAUTH) pour demander un ST. Lorsqu'un compte ne nécessite pas de préauthentification pour s'authentifier, un TGT peut être demandé sans nécessiter de données de préauthentification, qui sont chiffrées à l'aide d'une certaine forme d'identifiant (par exemple, un hachage de mot de passe, un certificat). Si un attaquant n'a pas obtenu de justificatif valable pour un compte, il ne peut pas générer de données de préauthentification valables. Si la préauthentification n'est pas requise, le problème ne se pose pas.
Lorsqu'un billet est demandé sans authentification préalable, le résultat comprend toujours une partie chiffrée. Cette partie chiffrée est chiffrée avec la clé d'identification utilisée pour l'authentification et contient la clé de session pour le ticket inclus dans la réponse. Il s'agit des données chiffrées utilisées dans l'attaque ASREPRoast de Will Schroeder. Le TGT résultant n'est utilisable qu'avec un accès à la clé du compte demandeur, puisque la clé de session du TGT est nécessaire.
Cependant, pour le Kerberoasting, l'accès à la clé de session n'est pas nécessaire. Seule la ST résultante - ou plus précisément, la partie cryptée de la ST, qui n'est pas sécurisée par la clé du compte demandeur - est nécessaire. Par conséquent, si un compte est configuré pour ne pas nécessiter d'authentification préalable, il est possible de procéder à une transmission Kerberoast sans aucun justificatif d'identité. Cette méthode de Kerberoast a été implémentée dans Rubeus dans le cadre de cette PR.
Démonstration
Comme l'accès à un compte valide n'a pas encore été obtenu, il n'est pas possible d'interroger LDAP. Au lieu de cela, une liste de comptes de service potentiels est nécessaire. Des recherches antérieures menées par Arseniy Sharoglazov montrent que les ST peuvent être demandées en utilisant uniquement le nom d'utilisateur du compte de service plutôt que le SPN réel, ce qui est très utile dans le cadre de cette recherche.
Une liste de noms d'utilisateur peut être générée de plusieurs façons, notamment par l'énumération d'utilisateurs à l'aide de sessions nulles sur un DC, par la génération d'une liste de noms d'utilisateur à l'aide de renseignements de source ouverte (OSINT), ou en devinant des noms d'utilisateur potentiels. Toute liste de noms d'utilisateur potentiels peut être facilement vérifiée en envoyant un AS-REQ sans pré-authentification. Un nom d'utilisateur valide qui nécessite une préauthentification reçoit une erreur KDC_ERR_PREAUTH_REQUIRED(Figure 4).
Un nom d'utilisateur valide qui ne nécessite pas de préauthentification reçoit un TGT(figure 5).
Un nom d'utilisateur non valide entraîne une erreur KDC_ERR_C_PRINCIPAL_UNKNOWN(figure 6).
À des fins de démonstration, une liste est générée à l'aide d'une session nulle sur le DC, en utilisant la méthode de cycle RID(-R) de enum4linux-ng, comme le montre la figure 7.
En utilisant cette liste de noms d'utilisateurs, il est facile de déterminer les comptes qui ne nécessitent pas de préauthentification dans AD(Figure 8).
Notez que les AS-REQ sans préauthentification ne sont pas enregistrés comme un événement Windows, sauf si le compte ne nécessite pas de préauthentification.
Avec la liste des noms d'utilisateur et le nom d'utilisateur d'un compte qui ne nécessite pas de préauthentification, l'attaque peut être lancée(Figure 9).
Le résultat obtenu peut ensuite être utilisé pour tenter de craquer un mot de passe hors ligne.
Preuve de concept : Rôtir au milieu
Une autre conséquence intéressante est la possibilité d'effectuer un Kerberoast à partir d'une position de type Man-in-the-Middle (MitM). Ce type d'attaque n'est généralement pas possible avec les TGS-REQ car le champ cksum facultatif de l'authentificateur dans l'AP-REQ protège le corps de la requête et est souvent inclus par les clients Kerberos Windows authentiques. Par conséquent, la modification du sname d'une TGS-REQ sans mise à jour de la somme de contrôle dans l'authentificateur invalide la somme de contrôle de l'authentificateur et renvoie une erreur KRB_AP_ERR_MODIFIED. Mais ce n'est pas un problème pour les AS-REQ car le corps de la requête, et par conséquent le champ sname, ne sont pas protégés.
En testant cette approche, j'ai découvert que les AS-REQ peuvent être rejoués plusieurs fois. Un attaquant n'a besoin de capturer qu'un seul AS-REQ pour envoyer un grand nombre d'AS-REQ avec différentes valeurs de nom (sname).
Démonstration
Pour démontrer cette approche, j'ai écrit une preuve de concept approximative (POC). Ce POC, RoastInTheMiddle, met en œuvre une usurpation ARP entre les DC et les systèmes victimes pour effectuer une attaque MitM. Le POC laisse ensuite passer le trafic tout en écoutant les AS-REQ. Lorsqu'une AS-REQ est trouvée, le POC effectue un Kerberoast. Le POC n'est pas prêt pour l'attaque mais démontre qu'une attaque est possible.
Tout d'abord, le POC lance quatre threads, un sniffer, un ARP spoofer, un re-assembler (pour les requêtes qui sont divisées en plusieurs paquets), et le roaster(Figure 10).
Lorsqu'il voit un AS-REQ, le POC commence à essayer d'envoyer par Kerberoast la liste fournie, qui peut contenir des noms d'utilisateur ou des SPN(figure 11).
Comme le montre la figure 11, cette tentative aboutit à la sortie de toutes les ST reçues au format hashcat, prêtes à être craquées hors ligne.
La possibilité de MitM AS-REQs, puis de les modifier et de les rejouer, pourrait également être utile pour développer d'autres attaques. J'ai tenté de modifier les options de kdc pour inclure l'option proxiable ce qui donne un ticket avec l'option proxiable activée. Cependant, je n'ai pas été en mesure de trouver un chemin d'attaque utilisant ce ticket et ce drapeau. Ce comportement pourrait également permettre l'utilisation d'autres comptes pour effectuer un Kerberoast, ce qui permettrait aux attaquants d'éviter de brûler un compte compromis.
Améliorations
Certaines améliorations pourraient être apportées à ce processus. Tout d'abord, il est possible de forcer un AS-REQ à partir d'un TGS-REQ en l'interceptant et en répondant par une erreur KRB_AP_ERR_BAD_INTEGRITY. Cela oblige le client à se réauthentifier en envoyant un AS-REQ.
Il devrait également être possible de réaliser cette attaque en utilisant l'injection d'un serveur de noms DHCPv6 (comme mitm6 de Dirk-jan Mollema ou Inveigh de Kevin Robertson), en répondant aux requêtes DNS SRV pour le service LDAP et en traitant ensuite la connexion LDAP suivante.
La prise en charge de la modification des types de chiffrement dans la demande permet des attaques par rétrogradation du type de chiffrement lorsque l'environnement le permet, comme le décrit Will Schroeder ici.
Enfin, le POC nécessite l'installation de Npcap sur le système exécutant le POC (qui utilise sharppcap), principalement pour l'usurpation d'adresse ARP. Si vous optez pour IPv6 ou si vous implémentez les réponses ARP en utilisant des sockets brutes, vous pouvez supprimer cette dépendance.
Contournement des détections
De nombreuses détections Kerberos reposent sur des événements 4769(un ticket de service Kerberos a été demandé). Cependant, la demande d'un ticket de service à l'aide d'un AS-REQ ne produit pas 4769 événements mais plutôt 4768 événements(un ticket d'authentification Kerberos (TGT) a été demandé).
La figure 12 montre un événement 4768 lorsqu'une ST est demandée à l'aide d'un AS-REQ.
Par conséquent, les attaquants qui utilisent cette méthode peuvent facilement contourner de nombreuses détections qui s'appuient sur les événements 4769.
Autres conséquences des tickets de service demandés par AS
Bien que je n'aie pas pu demander des tickets S4U2self à l'AS, les STs récupérés de l'AS n'ont pas la somme de contrôle du ticket (introduite pour protéger les tickets S4U2self contre l'attaque du bit de bronze par Jake Karnes).
Enfin, une ST demandée à la TGS est généralement renvoyée avec un PAC(Figure 13).
Il est possible de demander une ST sans PAC au TGS, mais il faut pour cela modifier le bit NO_AUTH_DATA_REQUIRED des comptes de service dans l'attribut useraccountcontrol(figure 14).
Lorsque cette configuration est en place, la ST renvoyée n'a pas de PAC, comme le montre la différence de taille du billet renvoyé(figure 15).
Une ST sans PAC peut être demandée à l'AS simplement en réglant la section de données PA-PAC-OPTIONS PA sur faux en ajoutant le commutateur /nopac à Rubeus(figure 16).
Cette approche pourrait être utilisée comme alternative à la création de tickets d'argent, en demandant une ST sans PAC, puis en injectant un autre PAC en l'incluant dans la section enc-authorization-data de la demande. Elle pourrait également fournir d'autres voies d'attaque potentielles.
Détection des tickets de service demandés par les AS
Microsoft ne jugeant apparemment pas ces problèmes dignes d'être corrigés, la détection au sein de votre organisation est la seule option possible. Comme indiqué précédemment, lorsqu'une ST est demandée à l'AS, l'événement 4768 est enregistré(Figure 17).
Tous les tickets authentiques demandés à l'AS, y compris les tickets kadmin/changepw, ont un nom de service et un identifiant de service de krbtgt(Figure 18) .
La vérification du trafic réseau pour les AS-REQ qui ne concernent pas le domaine krbtgt/domaine ou kadmin/changepw devrait également permettre de détecter ces demandes(figure 19).
Ces recherches, ainsi que la réponse de Microsoft, démontrent la nécessité d'une surveillance continue et de mesures de renforcement appropriées. La capacité de contourner les détections actuelles et de mener des attaques efficaces, comme le Kerberoasting, à partir d'une position non authentifiée est un problème sérieux qui ne doit pas être ignoré. Les recherches décrites ici pourraient déboucher sur d'autres attaques inédites, exposant potentiellement les organisations à des risques plus élevés.
Veillez à ce que des détections soient mises en place lorsque ces types de demandes de tickets sont effectués.
Remerciements
J'aimerais remercier les personnes suivantes pour leur contribution à cette recherche :
- Andrew Schwartz pour m'avoir envoyé sur cette voie avec son article Kerberos FAST (que vous devriez également lire).
- Elad Shamir pour m'avoir permis de lui soumettre ces idées.
- Will Schroeder pour avoir écrit Rubeus
- Tomer Nahum, Sapir Federovsky et Andrea Pierini pour la relecture et la critique de cet article.
Chronologie
- 25 mai 2022 : Rapport au CSEM
- 27 mai 2022 : Le CSEM a changé le statut en Examen/Repro.
- 13 juillet 2022 : le CSEM a répondu que le comportement était "intentionnel"
- 27 septembre 2022 : divulgation publique