Authentification Kerberos

Kerberos (en référence au chien à trois têtes qui protège l’accès aux enfers) est un protocole d’authentification développé par le MIT puis repris par Windows et introduit pour la première fois sur Windows 2000 afin de remplacer NTLM.

Kerberos offre plusieurs avantages à NTLM : il est plus rapide dans l’authentification,  ne stocke aucun mot de passe sur la machine, n’envoie aucun mot de passe sur le réseau (hashé ou en clair) et, cerise sur le gâteau,  il permet une authentification Single Sign On.

Pas mal non ?!

Sur chaque contrôleur de domaine (serveur qui héberge l’Active Directory) se trouve un serveur un peu particulier : le KDC (Key Distribution Center). Ce KDC est une entité de confiance absolue sur le réseau. C’est à dire que tous les services/serveurs/utilisateurs/ressources font confiance au KDC.

Ce KDC est divisé en deux rôles. Le premier c’est l’Authentication Service (AS) : c’est le service sur lequel s’authentifie le client. Le second : c’est le Ticket Granting Service (TGS) : celui qui fournit le droit d’accès à la ressource :

kb1.png

La première étape est celle de l’authentification. Généralement, c’est un utilisateur qui va se connecter à une session Windows en entrant un couple identifiant/mot de passe. A partir de ces informations, le client Kerberos présent sur chaque machine va dériver le mot de passe en un hash qui sera utilisé afin de chiffrer, entres autres, un timestamp.

Une première requête, nommée KRB_AS_REQ, sera ainsi émise et contiendra le nom de l'utilisateur en clair ainsi qu'un ensemble de données chiffrées qui contiendra entres autres un timestamp:

 

L’Authentication Service, lorsqu’il va recevoir le message, va directement vérifier que le nom d’utilisateur correspond à un utilisateur dans l’AD. Si c’est le cas, il va récupérer le hash du mot de passe de cet utilisateur puis tenter de déchiffrer le bloc chiffré contenant le timestamp. S'il y arrive c'est que le mot de passe renseigné par le client est valide.

Dans ce là, l’Authentication Service va renvoyer un Ticket Granting Ticket (que l’on abrège TGT) ainsi qu'une clé de session qui sera utilisée pour les futures communiques. Le tout est chiffrée à l'aide du hash NTLM de l'utilisation et émis via la requête KRB_AS_REP:

Mais de quoi est composé un TGT ? Un TGT est composé de deux parties:

  • Une partie non chiffrée qui contient, entres autres, le nom de l'utilisateur ainsi que le nom du domaine
  • Une partie chiffrée qui contient, entres autres, une clé de session, le PAC ainsi que la période de validité du TGT. Cette partie est chiffrée à l'aide du hash NTLM du compte krbtgt. Il n'est donc pas possible pour un attaquant en position de Man in the Middle d'en lire le contenu.

Le PAC, pour Privileged Attribute Certificate, contient tout un tas de données relative à l'utilisateur, à ses droits et à la validité du TGT. Pour information il est possible de déchiffrer un TGT à la volée dès lors que l'on connait le hash NTLM du compte krbtgt. Pour cela on pourra utiliser des outils tels que decryptKerbTicker.py. Vous trouverez ci-dessous un extrait de ticket TGT déchiffré

ticketdecrypted.png

Une fois le TGT acquis, le client pourra faire une demande d’accès à un service auprès du TGS (Ticket Granting Service) du KDC en émettant une requête  KRB_TGS_REP. Cette requête contiendra le TGT de l'utilisateur, le SPN du service qu'il cherche à joindre ainsi qu'un nouveau timestamp chiffré à l'aide de la clé de session précédement émise par l'AS.


Un SPN, pour Service Principal Name, permet d'associer un nom de service à une machine. C'est un identifiant unique sur un réseau. Pour illustrer la suite de cet article nous partirons du principe que notre client veut accéder à un serveur mail donc le SPN est IMAP/mail.whiteflag.local.


 

Comme c’est le KDC qui a chiffré le TGT, il va aussi pouvoir le déchiffrer. Et comme c’est lui qui l’a créé et émis, il va avoir une totale confiance en ce TGT. Si les informations sont correctes alors le TGS va émettre un Service Ticket (ST ou TGS selon les normes) via le requête KRB_TGS_REP. Notez bien que le Ticket Granting Service permet d’authentifier le client mais en aucun cas il ne donne une autorisation d’accès à la ressource.

Encore une fois, ce TGS est partiellement chiffré. Les métadonnées sont utilisables par le client mais le contenu du TGS lui est chiffré à partir du hash NTLM du mot de passe du compte de service relatif à la ressource demandée. Et encore une fois, un clé de session unique sera créée pour un temps limité. Cette clé sera utilisée afin de chiffrer les échanges entre le client et la ressource demandée.

Le client n'aura plus qu'à forwarder son TGS vers la ressource demandée pour s'y voir attribuer (ou non) l'accès:

Vu que le TGS est chiffré à partir du hash NTLM du mot de passe du compte de service du serveur mail, ce dernier sera en mesure de le déchiffrer et donc de donner un accès ou non au client. C’est ici que l’accès est autorisé ou refusé au client.