Kerberos, déléguerais-tu vraiment tes credentials à un chien ?

Dans cet article on regarde d’un peu plus près de ce que la délégation Kerberos implique en termes de sécurité dans votre environnement Active Directory. Pourquoi un chien ? Puisqu'après tout, Kerberos n'est qu'un chien à trois têtes 🐶🐶🐶

La délégation Kerberos c’est quoi ?

Déjà il est bon de dire que cela n’a rien à voir avec la délégation des permissions sur les objets dans Active Directory. Donc rien à voir avec la délégation du Helpdesk sur la réinitialisation des mots de passes de tes comptes utilisateurs. D’ailleurs il s’agit en fait de quelque chose de bien plus puissant. L’idée originale c’est autoriser ("déléguer") un compte le droit de demander des tickets en tant que quelqu’un d’autre. En gros tu donnes l’autorisation à un compte de se faire passer pour quelqu’un d’autre. Déjà on peut voir que cela peut être un risque important. Bon, à côté de risques tels que : « j’ai 60 domain admins » ou bien « on utilise le même mot de passe administrateur sur toutes mes machines » on est un peu plus bas dans la liste de priorité. Mais quand même, voyons cela un peu plus en détails car Windows Server 2003 puis Windows Server 2012 R2 apportent des nouveautés dans cet espace.

Un mal nécessaire.

Donner la permission à un compte de se faire passer pour quelqu’un d’autre peut paraitre limite niveau sécurité… Mais cela répond en fait à un problème ancestral des applications multi-tiers. Le double-hop. Avant Kerberos (comprendre NTLM), lorsque tu te connectes à un service web, tu t’authentifies et le service sait qui tu es. Mais lorsque ce service appelle un autre service en arrière-plan (une base de données, d’autre service web…) il le fait avec son identité à lui, pas la tienne. Du coup niveau délégation des accès c’est assez limitant, tous les accès sont faits en tant que le compte de service du service web. Ou bien on peut demander à l’utilisateur de se réauthentifier mais cette fois-ci auprès de cet autre service, résultant la plupart du temps en en pop-up où l’utilisateur exaspéré doit de nouveau rentrer son mot de passe… Grâce à la délégation, si le compte de service du service web a le droit de se faire passer pour toi, et bien les accès aux services en arrière-plan conservent ton identité. Et la ça devient très intéressant en termes de permissions et d’audit ! C’est la délégation Kerberos.

Les 3 façons de faire de la délégation Kerberos.

Dans les trois exemples suivants, je regarde l'onglet Delegation du compte machine VSRV01. Notez que vous ne verrez pas l'onglet Delegation sur un compte utilisateur à moins que le compte en question ait une ou plusieurs valeurs définie dans l'attribut servicePrincipalName (pas de SPN = pas de délégation Kerberos, après tout ça a du sens).

Il y a la façon old school style Windows 2000 Server.

Il y a la façon Windows Server 2003 en mode Kerberos de bout en bout.

Et il y la façon Windows Server 2003 en mode transition de protocole.

L'option Trust this computer for any service (Kerberos only) est l'option datant de Windows 2000 server. En termes de risque cela signifie qu’un attaquant ayant des droits d’administrateur local sur le serveur VSRV01 peut se faire passer pour n’importe quel utilisateur utilisant le service pour lequel on a configuré la délégation. Par exemple, s’il s’agit d’un service web qui tourne dans le contexte machine (en local system par exemple) si Adam se connecte au service l’attaquant peut se faire maintenant passer pour Adam auprès de n’importe quels autres services (par exemple sa boite email, ou ses dossiers partagés). Bien sûr il faut qu’Adam se connecte une première fois au serveur compromis. Si l’attaquant a compromis le serveur Sharepoint, c’est une question de temps, si l’attaquant a compromis un serveur quelconque, un petit courriel d’hameçonnage fera l’affaire pour l’attirer.

Pour les deux autres options sous la section Trust this computer for delegation to specified services only c’est un peu différent puisque cette fois-ci, il faut aussi spécifier la liste des services (SPN, c'est comme cela qu'on identifie les services dans le royaume de Kerberos) pour lesquels VSRV01 a la permission de se faire passer pour quelqu’un d’autre. Donc si le service web n’a accès qu’à une base de données et un serveur de reporting SQL, bon l’attaquant peut toujours se faire passer pour Adam lorsqu’il se connecte au service mais uniquement auprès des services spécifiés. Il s’agit de la délégation contrainte. Donc plus d’accès aux emails ou aux données personnelles (à moins évidemment que ces services fassent partie de la liste des services autorisés…).

Attardons-nous un peu sur la deuxième option de délégation contrainte. Celle avec transition de protocole. Jusqu’à présent, le VSRV01 peut se faire passer pour Adam que si ce dernier s’est déjà connecté au service pour lequel on a configurer la délégation. Avec la transition de protocole, ça change un peu. Le problème de la délégation Kerberos, et excusez-moi de la Lapalissade, c’est que cela nécessite Kerberos. Donc si l’utilisateur ne s’est pas authentifié en utilisant Kerberos auprès du service (soit car Kerberos a échoué, ou bien car l’utilisateur ne peut pas utiliser ce protocole avec son client) et bien tout tombe à l’eau. La délégation Kerberos c’est un peu comme prendre le ticket d’un utilisateur et l’envoyer au contrôleur de domaine en disant « coucou c’est moi Adam ». Dans ce cas, il n’y a pas de ticket car on arrive avec NTLM, ou bien avec un formulaire, ou bien tout autre protocole que Kerberos. Et c’est là que la magie de la transition de protocole opère. Si le service estime que Adam a prouvé qui il était avec une autre protocole que Kerberos, sélectionner l’option Use any authentication protocol va permettre au service de demander au contrôleur de domaine un ticket à la place d’Adam. Mais comme il n’y a plus besoin d’attendre qu’Adam se connecte avec succès avec Kerberos, l’attaquant n’est plus obligé d’attendre qu’Adam se connecte et peut à n’importe quel moment se faire passer pour lui ! Seulement auprès de la liste contrainte de services mais tout de même. En gros, l'attaquant peut se faire passer pour n'importe qui, n'importe quand. Et ce n'est pas un bug ou un détournement. C'est comme ceci que le protocole est conçu et implémenté.

Dans cet exemple je prends un compte machine. Donc cela implique que l'attaquant soit administrateur local de la machine. Si la délégation est active sur un compte utilisateur (cas de compte de service), l'attaquant peut faire la même chose juste et connaissant ou découvrant le mot de passe du compte).

Exemple pratique : se faire passer pour n'importe qui.

Voici la configuration de la délégation Kerberos sur VSRV01:

Je me connecte à VSRV01 avec un compte local membre du groupe local Administrators.

J'ai aucune permission on VFILE01, et si j'essaye de lister le partage administratif C$ je me fais rembarrer :

J'ouvre une console PowerShell en local system avec PSEXEC :

 PSEXEC -i -s -d PowerShell

Puis je décide de changer d'identitée et de me faire passer pour l'administrateur du domaine (dans mon cas piaudonnmsdn@verenatex.com) :

 $u = New-Object System.Security.Principal.WindowsIdentity("piaudonnmsdn@verenatex.com") 
$u.Impersonate()

Et voici le resultat :

Et sur le câble réseau, à quoi cela ressemble-t-il ? Et bien on voit la demande de TGT suivie d'une demande de ticket de service pour CIFS/VFILE01 mais avec un fanion particulier :

Le fanion S4U2Proxy nous indique que ce ticket a été obtenu grâce à la transition de protocole.

Bref, l'attaquant est administrateur du service (ici le service de fichiers). Mais si l'attaquant avait choisi un autre service constraint comme le service SQL de VSQL01 dans mon example, on peut se faire passer pour le compte de service ou un compte administrateur du service en question.

On va tous mourir ! Il faut désactiver la délégation !

Pas si vite ! Encore une fois, la délégation Kerberos et même la transition de protocole, sont des fonctionalités très utiles et nécéssaires pour aussi augmenter le niveau de sécurité d'une application (puisque la connexion d'un utilisateur est authentifiée de bout en bout). Il faut tout simplement s'assurer que vous contrôlez qui est administrateur local des serveurs, et pour les cas des comptes de services, qui connait les mots de passe de ces comptes et/ou qui est administrateur local des machines où ces comptes sont utilisés. Un peu de rigueur suffit pour contrôler ce risque. Et cette rigueur est aussi recommandée même si tu ne fais pas de delegation Kerberos de toutes façons. Par contre, si la délégation n'est pas utilisée, ou est le resultat d'une erreur de configuration, il faut la corriger.

  1. Il faut s'assurer que seulement les administrateurs de domaine peuvent configurer la delegation. C'est un paramètre de sécurité généralement configure dans la Default Domain Controller Policy:
  2. Il faut s'assurer qu'on utilise la délégation sur le bon compte et que c'est bel et bien requis pour l'application. Configurer la delegation peut des fois s'avérer laborieux. On teste plein de possibilités, et puis hop cela marche et on touche plus... Du coup, il est bien possible que certains comptes ait été touchés pour rien. Il faut les corriger.
  3. Il faut s'assurer qu'on utilise la délégation contrainte en spécifiant les services (SPN) plutôt que la méthode old school Windows 2000 Server lorsque la délégation est nécéssaire.
  4. Et enfin securiser les groupes administrateurs locaux des serveurs où les comptes sont utilisés. En utilisant la fonctionalité de groupes restreints des stratégies de groupe par exemple.

On peut aussi désactiver la possibilité pour un compte d'être utilisé dans un scenario de délégation. C'est l'option suivante :

C'est Account is sensitive and cannot be delegated. Il est recommandé d’activer cette option au minimum pour les comptes domain admins et les comptes avec de privilèges élevé et qui n’utilisent pas d'application nécéssitant la délégation Kerberos.  Il est recommandé de faire ça pour tous vos comptes admins AD puisqu'ils n'utilisent pas les applications métiers qui ont la besoin de la délégation (pour etre precis, il y a une situation d'administration AD qui requiert la delegation, c'est bouger un compte d'une domaine vers un autre en intra-forêt avec MOVETREE ou ADMT, mais bon on fait pas ça tous les jours, et on peut juste décocher la case avant de faire le move et la recocher ensuite).

Lister les comptes à risque.

Bon comprendre les comptes à vérifier.

  1. Lister les comptes machines configurés pour la délégation à la mode 2000:

     Get-ADObject -LDAPFilter:"(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=524288))"
    

    Notez que cela retourne aussi les contrôleurs de domaine. Pas de panique, c'est attendu, pas besoin de les modifier.

  2. Lister les comptes utilsateurs configurés pour la délégation à la mode 2000:

     Get-ADObject -LDAPFilter:"(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=524288))"
    
  3. Lister les comptes machines configurés pour la délégation avec transition de protocole :

     Get-ADObject -LDAPFilter:"(&(objectCategory=computer)(objectClass=computer)(userAccountControl:1.2.840.113556.1.4.803:=16777216))"
    
  4. Lister les comptes utilsateurs configurés pour la délégation avec transition de protocole :

     Get-ADObject -LDAPFilter:"(&(objectCategory=person)(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=16777216))"
    

Des questions ? Des commentaires ? C'est en bas !

Merci à Pascal B. pour son aide dans la rédaction de ce billet !