Menu
Resource-Based Constrained Delegation - Risques

Resource-Based Constrained Delegation - Risques

Cet article montre comment abuser de la délégation contrainte basée sur les ressources (resource-based constrained delegation) afin de prendre le contrôle de machines.

Il repose sur du contenu d’excellente qualité. J’ai tenté de résumer avec des mots simples une petite partie du travail de Elad Shamir. Son article Wagging the Dog: Abusing Resource-Based Constrained Delegation to Attack Active Directory est incroyable de par ses recherches. D’autres articles ont suivi, notamment celui de Dirk-jan (The worst of both worlds: Combining NTLM Relaying and Kerberos delegation ) ou celui de Harmj0y (A Case Study in Wagging the Dog: Computer Takeover), me permettant d’assembler toutes les pièces et de rédiger cet article.

Vous êtes prêts ? Let’s dive in.

Rappels : Resource-Based Constrained Delegation

Dans cet article, le terme “Resource-Based” sera utilisé pour parler de cette délégation.

Contrairement à la délégation complète, la délégation Resource-Based est un poil plus compliquée. L’idée générale est que ce sont les ressources de fin de chaine qui décident si oui ou non un service peut s’authentifier auprès d’elles en tant qu’un autre utilisateur. Ces ressources ont donc une liste de comptes en lesquels elles ont confiance. Si une ressource fait confiance au compte WEBSERVER$, alors quand un utilisateur s’authentifiera auprès de WEBSERVER$, il pourra lui même s’authentifier auprès de cette ressource en tant que l’utilisateur.

En revanche, si un autre utilisateur s’authentifie auprès d’un compte qui ne fait pas partie de la liste de confiance du service (par exemple FILESERVER$ ou Sql_SVC dans le schéma ci-dessous), ce compte ne pourra pas se faire passer pour cet utilisateur auprès du service.

Resource Based Constrained Delegation

Concrètement, comme expliqué dans l’article sur la délégation, la ressource finale, à droite sur le schéma, a un attribut appelé msDS-AllowedToActOnBehalfOfOtherIdentity qui contient la liste des comptes en lesquels elle a confiance.

Par ailleurs, pour que cette délégation fonctionne, l’attribut ADS_UF_NOT_DELEGATED de l’utilisateur ne doit pas être positionné. C’est un attribut qui permet d’interdire la délégation en vue de protéger le compte des attaques liées à la délégation.

Notons également que pour relayer l’authentification d’un utilisateur, le compte de service “relais” (WEBSERVER$ dans le schéma) doit avoir un ticket de service provenant de l’utilisateur.

Si l’utilisateur s’authentifie via Kerberos, aucun soucis, le service “relai” est en possession du ticket de service de l’utilisateur, donc le mécanisme (S4U2Proxy) est simple, le compte de service envoie le ticket de service de l’utilisateur au contrôleur de domaine pour que celui-ci lui renvoie un ticket de service valide pour accéder à la ressource désirée (si bien sûr le compte de service fait partie de la liste de confiance de la ressource).

Resource Based Constrained Delegation Detailed

En revanche, si l’utilisateur s’authentifie d’une autre manière (NTLM par exemple), le compte de service n’a pas reçu de ticket de service. Il va alors devoir faire une première demande pour avoir un ticket de service transférable au nom de l’utilisateur, c’est le mécanisme S4U2Self, puis il utilisera ce ticket de service transférable pour faire le processus expliqué juste avant, S4U2Proxy.

S4U2Self

Comportement “by design”

Maintenant que ces rappels sont faits, il est intéressant de creuser un peu. En effet, on se rend compte que le mécanisme S4U2Self peut être assez dangereux, parce qu’un service peut finalement demander un ticket de service au nom de n’importe quel utilisateur. Dans le processus normal, il demande un ticket de service au nom de l’utilisateur qui s’est authentifié auprès de lui, mais rien ne l’oblige à se limiter à ce compte.

Heureusement, cette possibilité de demander des tickets de service transférables au nom de n’importe qui (S4U2Self) n’est possible que pour les comptes ayant l’attribut TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION de positionné, c’est à dire les compte pouvant faire de la délégation contrainte avec transition de protocole. Ce n’est donc pas un attribut positionné par défaut.

Plus précisemment, tous les comptes de service peuvent faire un S4U2Self, mais seuls ceux avec l’attribut TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION recevront un ticket de service transférable, condition à priori nécessaire pour S4U2Proxy (cf. la documentation Microsoft).

Ainsi, par exemple, lors d’une délégation contrainte (pas Resource-Based) avec transition de protocole, si un compte machine demande un ticket de service via S4U2Self, comme cette machine est en délégation contrainte avec transition de protocole, elle possède bien le drapeau TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION. Ce compte recevra un donc ticket de service transférable, et lors de la demande de ticket de service pour une des ressources pour lesquelles il peut faire de la délégation (S4U2Proxy), il pourra transférer ce ticket de service.

En revanche, et c’est là que c’est super incroyable, dans le cas de la délégation Resource-Based, si de la même manière un compte machine demande un ticket de service via S4U2Self, cette fois-ci le compte n’a pas l’attribut TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION, ce compte recevra donc un ticket de service qui sera non transférable, mais lors de la demande de ticket de service pour une ressource (S4U2Proxy), cette demande SERA ACCEPTÉE (cf. encore la documentation Microsoft).

S4U2Self without transferable

Dans cet exemple, le SERVEUR1$ n’a pas l’attribut TRUSTED_TO_AUTHENTICATE_FOR_DELEGATION de positionné, mais il est déclaré dans la liste de confiance de Service B. Lors de sa demande de ticket de service pour un utilisateur lambda via S4U2Self, le contrôleur de domaine lui envoie un ticket de service non transférable, cependant en passant ce ticket de service à la requête S4U2Proxy afin de récupérer un ticket de service pour utiliser le Service B, il n’y a aucun soucis, ça fonctionne, et SERVEUR1$ peut utiliser Service B en tant que l’utilisateur choisi.

Au cas où ce n’est toujours pas clair, ça veut dire que SERVEUR1$ peut s’authentifier auprès de Service B en tant que n’importe quel utilisateur.

Et ouais.

Attribut Machine-Account-Quota

Pour pouvoir décrire un chemin d’attaque complet, il faut également parler de l’attribut msds-MachineAccountQuota qui est positionné sur le domaine. Cet attribut décrit le nombre de comptes machine qu’un utilisateur du domaine peut créer. Cet attribut vaut 10 par défaut. Cela signifie que, par défaut, un utilisateur peut joindre 10 machines au domaine, ou qu’il peut créer 10 comptes machine, en choisissant notamment leur nom et leur mot de passe.

Ce comportement peut être modifié par GPO, mais voilà, par défaut, c’est 10.

Cet ajout peut être fait directement dans les paramètres d’une machine Windows, mais également via LDAP. Cette fonctionnalité est notamment disponible dans l’outil Powermad de Kévin Robertson.

New-MachineAccount -MachineAccount NOUVELLEMACHINE -Password $(ConvertTo-SecureString "Hackndo123+!" -AsPlainText -Force)

Cette fonctionnalité est importante parce que dans les histoires de délégation, les comptes concernés sont des comptes de service, c’est à dire des comptes avec un ou plusieurs SPN. Un utilisateur du domaine n’a pas d’attribut SPN, mais il peut créer un compte machine qui lui possède par défaut plusieurs SPN.

Exploitation

Nous avons maintenant tous les éléments en main pour décrire un chemin d’attaque. Il en existe d’autres, bien sûr, mais ce chemin permet d’assembler toutes les pièces du puzzle.

Nous nous plaçons dans le cas d’une position man-in-the-middle en utilisant le fait que IPv6 est majoritairement activé dans les réseaux d’entreprise, et que d’un point de vue OS, c’est ce protocole qu’il faut utiliser en priorité, avant IPv4. Un attaquant peut alors se positionner en serveur DHCP IPv6 et répondre aux équipements environnants.

MITM6 Wpad

Par ailleurs, il est possible de relayer une authentification HTTP d’une machine en une authentification LDAPS vers une autre. Nous relaierons les connexions vers le contrôleur de domaine.

Lorsque la machine DESKTOP-01 va se connecter au réseau (reboot, branchement du cable réseau), le compte DESKTOP-01$ va se connecter en HTTP à notre machine du fait de notre position man-in-the-middle. C’est à ce moment que le relai va être effectif.

Deux actions vont être effectuées via LDAPS, en utilisant cette authentification relayée, en tant que DESKTOP-01$.

  1. Un compte machine HACKNDO$ va être créé, puisque le compte DESKTOP-01$ est un compte du domaine, et a le droit d’ajouter 10 comptes machine au domaine, par défaut.
  2. Le compte machine DESKTOP-01$ a le droit de modifier certains de ses attributs, dont l’attribut msDS-AllowedToActOnBehalfOfOtherIdentity, qui est la liste des machines de confiance pour la délégation “Resource-Based”. On va donc modifier cet attribut pour ajouter HACKNDO$ à cette liste de confiance.

Relai LDAP

Maintenant, nous avons la main sur le compte HACKNDO$, puisque nous avons choisi son nom et son mot de passe lors de la création, et ce compte a la confiance de DESKTOP-01$.

Il suffit alors de se connecter en tant que HACKNDO$, faire une demande de ticket de service au nom d’un administrateur via S4U2Self. Le contrôleur de domaine va nous répondre avec un ticket de service non transférable. Nous demandons ensuite un ticket de service pour utiliser le service CIFS de DESKTOP-01 (CIFS/DESKTOP-01) en fournissant le ticket de service précédemment demandé (S4U2Proxy). Comme nous l’avons vu au début, bien qu’il ne soit pas transférable, il est tout de même accepté, et le contrôleur de domaine nous envoie un ticket de service en tant qu’administrateur pour utiliser le service CIFS de DESKTOP-01.

Voici un petit schéma récapitulatif :

Processus complet

Il est possible de répéter l’opération pour demander un ticket de service en vue de pouvoir gérer les services. Ainsi, en envoyant un exécutable de type “reverse-shell” sur la machine avec le ticket CIFS, puis en créant et démarrant un service utilisant cet executable à l’aide d’un ticket SCHEDULE, il est possible de prendre la main sur la machine en tant que SYSTEM.

Résumé

L’opération étant un peu complexe, voici les différentes étapes résumées :

  1. Ajouter une machine M au domaine (via un relai d’authentification, via un compte de domaine déjà possédé, …)
  2. Ajouter cette machine M à la liste de confiance de la cible C (i.e. l’ajouter à l’attribut msDS-AllowedToActOnBehalfOfOtherIdentity en relayant l’authentification de la machine cible, puisqu’elle a le droit de changer son propre attribut)
  3. Faire une demande de ticket de service pour un ticket au nom d’un administrateur via S4U2Self
  4. Une fois en possession de ce ticket, l’envoyer au contrôleur de domaine pour demander un ticket de service vers la cible C via S4U2Proxy.
  5. Enjoy ce nouveau ticket valide, en tant que l’administrateur choisi. D’autres tickets peuvent être demandés avec l’étape 4.

Conclusion

La délégation “Resource-Based” est un procédé complexe, tellement complexe que des problématiques de sécurité sont introduites dans l’implémentation de la fonctionnalité.

Ce qu’il faut finalement retenir, c’est qu’il est possible de prendre la main sur une machine lorsqu’on a la possibilité de modifier sa liste de confiance dans le cadre de la délégation basée sur les ressources.

Pour s’en prémunir, plusieurs actions sont possibles. Tout d’abord, il faut implémenter le channel binding au niveau de LDAP afin d’empêcher le relai vers LDAPS. Ensuite, il faut limiter la possibilité de création de comptes machine sur le domaine à des groupes définis d’utilisateurs. Enfin, en lien avec cet exemple, IPv6 devrait être désactivé dans les réseaux d’entreprise, puisqu’il ne répond à aucun besoin.

Cet article étant relativement dense, il serait tout à fait normal que des points ne soient pas tout à fait clairs. Si vous avez des questions, n’hésitez pas à les poser en commentaire ou sur Discord. Vous pouvez toujours suivre la sortie de nouveaux articles sur mon twitter @hackanddo.

Enfin, n’hésitez pas à faire un tour sur les ressources citées, notamment l’article de Elad Shamir qui est un travail de recherche complet et super intéressant.

Ressources


hackndo logo
Auteur : Pixis
Créateur du blog, suivez-moi sur twitter ou discord