Au cœur du protocole Kerberos
Sommaire
Dans cet article, je vous convie au cœur d’un protocole réseau très largement utilisé depuis des années et pourtant si mal cerné : Kerberos. En effet, au cours de mes discussions professionnelles, je me rends souvent compte que s’il est très présent, Kerberos est assez mal compris sur son fonctionnement. En outre, la plupart des articles que j’ai pu trouver restent un peu trop vagues et approximatifs à mon goût concernant son fonctionnement, contrairement à la Request for Comments (RFC, document décrivant une spécification technique d’Internet et émanant de l’Internet Engineering Task Force ou IETF) mais qui est longue et fastidieuse à lire, bien que très exhaustive. C’est pour cela que j’ai souhaité clarifier les choses avec cet article.
Introduction
Sur les réseaux informatiques circulent de nombreuses demandes d’accès à des services pour lequels il est essentiel de vérifier l’identité des utilisateurs souhaitant les consommer. On peut citer par exemple des demandes d’accès aux annuaires comme l’Active Directory (AD) de Microsoft, de la navigation Web via des proxys, des accès à des serveurs de bases de données, etc. Pour parvenir à cela sans perturber l’expérience utilisateur, des solutions transparentes existent comme Kerberos, un protocole s’appuyant sur la cryptographie symétrique avec des secrets partagés. Pour plus d’informations sur ce qu’est la cryptographie, je vous invite d’ailleurs à consulter cet article. D’abord, nous verrons les fondements de Kerberos, puis ses composants et comment ils intéragissent entre eux afin de délivrer un service d’authentification. Puis j’introduirai le concept de délégation dans Kerberos et enfin je présenterai les attaques les plus célèbres sur ce protocole.
Origines et objectifs de Kerberos
Le terme Kerberos (en français Cerbère) provient du grec ancien et de la mythologie grecque. Il s’agit d’un chien à trois têtes gardant l’entrée des enfers, empêchant les morts de s’y échapper. L’analogie provient du fait que Kerberos repose sur un modèle avec trois composants principaux. Nous y reviendrons.
Le protocole réseau Kerberos fut développé par le Massachusetts Intitute of Technology (MIT) en 1988 dans le cadre d’un projet d’informatique ditribuée. Il repose sur le protocole Needham–Schroeder qui permet à des tiers de prouver leurs identités respectives en utilisant du chiffrement symétrique. La première version publique du protocole Kerberos fut la version 4, sortie en 1989. En 1993, la version 5 fut publiée avec des améliorations principalement sur les aspects de sécurité.
Les objectifs du protocole sont de fournir des moyens de vérifier des identités sur un réseau considéré non sécurisé ou de non confiance. Pour cela, Kerberos permet l’authentification, unidirectionnelle ou bidirectionnelle (mutuelle), d’un utilisateur ou d’un serveur de manière transparente. Ainsi, Kerberos se catégorise comme un système d’authentification unique ou Single Sign-On (SSO), qui consiste à ne réaliser qu’une seule authentification du point de vue de l’utilisateur en propageant les informations de cette authentification pour plusieurs services. Dans le cas de Kerberos, des tickets sont distribués et réutilisés.
Il est temps de rentrer plus dans le détail de Kerberos.
Composants et fonctionnement de Kerberos
Kerberos est donc un chien à trois têtes. Je dirai même bien plus en l’occurence. En effet, il y a plusieurs composants participant à ce protocole :
- Le principal, qui est une entité unique (e.g. un utilisateur) qui participe à une communication réseau et consomme des services sur lesquels il doit s’authentifier.
- Le client, qui permet l’usage de services réseaux pour le compte du principal.
- Le serveur d’authentification ou Authentication Server (AS), qui est un serveur maintenant une base de principals et leurs clés secrètes, dérivées du mot de passe. Son rôle est d’échanger des identifiants contre des tickets à utiliser par la suite pour obtenir d’autres tickets de services.
- Le serveur d’attribution de tickets ou Ticket-Granting Server (TGS), qui est un serveur en charge de fournir des tickets permettant la consommation de services applicatifs donnés.
- Le centre de distribution de clés ou Key Distribution Center (KDC), qui est le regroupement de l’AS et du TGS, ces derniers étant généralement installés sur le même serveur.
- Le serveur d’application, qui héberge un service consommable par le principal via le client et contrôle l’accès à ce service.
Nous allons voir maintenant comment ces composants intéragissent tous ensemble pour permettre la vérification d’identités dans le but de consommer un service applicatif disponible sur le réseau.
Le fonctionnement de Kerberos repose sur plusieurs principes :
- L’échange de tickets :
- un ticket, appelé le Ticket-Granting Ticket (TGT) pour demander des tickets de services ;
- un ticket de service ou Service Ticket pour demander l’accès au service en question.
- L’utilisation et parfois partage de clés de chiffrement :
- une clé de session, que je note $S_{s}$, transmise par le TGS au client.
- une clé de session, que je note $S_{c}$, transmise par l’AS au client et servant notamment à chiffrer ou déchiffrer $S_{s}$.
- une clé secrète, que je note $K_{c}$, dérivée du mot de passe du pricipal, partagée entre le client et l’AS et servant notamment à réaliser la pré-authentification et à chiffrer ou déchiffrer $S_{c}$.
- une clé secrète, que je note $K_{k}$, connue seule de l’AS et servant à chiffrer ou déchiffrer le TGT. Dans les environnements Windows, par défaut un compte de service prédéfini appelé krbtgt existe car son mot de passe est utilisé sur le KDC pour dériver la clé de chiffrement $K_{k}$.
- une clé secrète, que je note $K_{a}$, partagée entre le TGS et le serveur d’application, servant notamment à chiffrer ou déchiffrer le Service Ticket. Sur le serveur d’application, cette clé est généralement stockée dans un keytab (raccourci pour key table ou table de clés).
Rien de tel qu’un schéma pour bien comprendre le déroulement du protocole, qui peut se résumer par trois grandes étapes :
- Le principal se connecte sur le client qui demande alors un TGT à l’AS. Ce dernier vérifie l’identité et lui renvoie un TGT chiffré.
- Le client, avec son TGT, demande au TGS un Service Ticket pour le service donné. Le TGS vérifie le TGT et lui renvoie un Service Ticket.
- Le client, avec son Service Ticket, demande au serveur d’application l’accès au service donné.
Bon, maintenant, pour les plus passionnés d’entre vous, voici ce qui se passe dans les détails.
0
. Le principal se connecte sur le client.
1
. Le client émet un message $AS$_$REQ$ pour demander un TGT à l’AS pour le principal donné. Ce message contient notamment un horodatage ou timestamp chiffré avec la clé $S_{c}$. L’AS vérifie dans sa base de données la présence du principal et déchiffre puis vérifie le timestamp pour réaliser ce qu’on appelle alors la pré-authentification. Puis, à l’aide de la clé $K_{c}$, il chiffre la clé de session $S_{c}$ et chiffre également un TGT à l’aide de sa clé $K_{k}$.
2
. L’AS émet un message $AS$_$REP$ contenant la clé de session et le TGT chiffrés qui sont ainsi envoyés au client. Le client déchiffre la clé de session avec la clé $S_{c}$ qu’il utilise pour génèrer un Authenticator $A_{c}$, qui est un élément permettant de certifier la connaissance de $S_{c}$ par le client.
3
. Le client émet un message $TGS$_$REQ$ avec son TGT chiffré et $A_{c}$ tout en indiquant l’identifiant du service ou Service principal Name (SPN) afin de demander au TGS un Service Ticket pour le service donné. Le TGS vérifie le TGT, $A_{c}$ et prépare un Service Ticket qu’il chiffre avec la clé $K_{a}$, ainsi qu’une nouvelle clé de session $S_{s}$ qu’il chiffre avec $S_{c}$. Il est à noter que dans le Service Ticket se trouve un Privileged Attribute Certificate (PAC) qui contient notamment le nom d’utilisateur, le Security IDentifier (SID, identifiant unique sous Windows) et les groupes de l’utilisateur. Cela permet au serveur d’application de vérifier des droits spécifiques de l’utilisateur sans effectuer une requête au KDC.
4
. Le TGS émet un message $TGS$_$REP$ vers le client pour lui envoyer le Service Ticket chiffré et la clé $S_{s}$ chiffrée. Le client déchiffre $S_{s}$ avec $S_{c}$ et prépare un Authenticator $A_{a}$ qu’il chiffre avec $S_{s}$.
5
. Le client émet un message $AP$_$REQ$ vers le serveur d’application à qui il envoie le Service Ticket chiffré et $A_{a}$. Le serveur d’application déchiffre et vérifie $A_{a}$ et le Service Ticket grâce à $K_{a}$.
6
. Si tout est valide, le serveur d’application émet un message $AP$_$REP$ pour confirmer au client l’accès au service.
L’algorithme de chiffrement utilisé par Kerberos est aujourd’hui Advanced Encryption Standard (AES) qui est venu remplacer Data Encryption Standard (DES) et Rivest Cipher 4 (RC4), déployés initialement mais moins sécurisés car sensibles aux attaques par force brute ou brute force attacks. C’est le mode CipherText Stealing (CTS) qui est utilisé pour AES afin de permettre d’éviter l’utilisation de bourrage dans les chiffrements par blocs et de donner une taille de message chiffré égale à la taille du message clair. Pour assurer l’intégrité des messages chiffrés avec AES, c’est la fonction de hachage cryptographique keyed-Hash Message Authentication Code (HMAC) SHA1-96 qui est généralement utilisée. Cela génère une empreinte de 160 bits alors tronquée à 96 bits. Les fonctions de hachages à clé HMAC SHA-256 et SHA-384 (générant des empreintes plus longues donc plus sécurisées) ont également été standardisées mais leur utilisation est moins répandue.
En outre, il est à noter que Kerberos permet des extensions où la cryptographie asymétrique est employée, c’est-à-dire que des paires de clés publiques et privées sont utilisées en lieu et place des clés symétriques partagées.
Je vous redirige vers cet article pour revoir toutes ces notions de cryptographie.
Kerberos utilise le protocole de transport User Datagram Protocol (UDP) sur le port 88 (par défaut) mais peut aussi s’établir sur le protocole Transmission Control Protocol (TCP) sur le port 88 (par défaut) notamment lorsque de larges tickets doivent être transférés. Il est à noter aussi que les communications Kerberos sont parfois encapsulées dans d’autres protocoles. C’est le cas par exemple lors d’une communication Web entre un client et un proxy qui demande une authentification Kerberos sur le protocole HyperText Transfer Protocol (HTTP).
Délégation dans Kerberos
Microsoft a développé une approche pour permettre de déléguer l’accès avec authentification à des serveurs d’application sans impliquer le client. Le cas d’usage fréquent concerne des applications distribuées où un client va d’abord s’authentifier auprès d’un premier service applicatif (e.g. un serveur Web) qui a besoin d’accéder à un autre service applicatif (e.g. une base de données) au nom du client.
Dans ce contexte, le premier modèle de délégation proposé dans Windows 2000 fut la délégation sans contrainte ou unconstrained delegation où le TGT du client est inséré dans le Service Ticket afin que le serveur d’application puisse le déchiffrer (car il possède la clé pour) et donc le réutiliser au nom du client afin d’obtenir un Service Ticket pour accéder à l’autre serveur d’application. Ce modèle a de nombreux défauts : pas de granularité sur la délégation, risque de compromission du TGT entraînant la génération malveillante de Service Tickets…
Vint alors avec Windows 2003 la délégation contrainte ou constrainted delegation, où on indique les services pour lesquels un serveur d’application peut authentifier l’utilisateur en son nom. Le serveur d’application peut alors demander des Service Tickets au KDC pour le client. Les Service Tickets supplémentaires associés au services identifiés peuvent alors être demandés via un Service Ticket (utilisé dans une requête $TGS$_$REQ$) pouvant être retransmis grâce à l’extension S4U2Proxy. Dans certains cas où le client n’effectue pas de Kerberos et donc n’a pas de TGT, un service peut vouloir demander un Service Ticket au nom du client pour autoriser ce client à accéder à ce même service. Ceci est possible avec l’extension S4U2Self. Bien qu’une amélioration dans l’approche de délégation d’authentification, la délégation contrainte expose encore de sérieux risques de mouvement latéraux si le service avec les droits pour faire de la délégation contrainte est compromis.
Dans Windows 2012, Microsoft a introduit la délégation contrainte par ressource ou resource-based constrained delegation permettant aux services de configurer quels comptes sont autorisés à déléguer vers eux. Cela demande malgré tout une vigilance accrue dans la configuration.
Attaques sur Kerberos
Il existe plusieurs attaques décrites autour du protocole Kerberos. On peut citer notamment :
- Le Kerberoasting : cette attaque nécessite en pré-requis d’avoir récupéré un TGT valide ou d’avoir la capacité d’écouter ou sniffer le trafic réseau de type Kerberos. Avec le TGT, l’attaquant peut demander des TGS ou bien s’il a la capacité de sniffer le trafic, il peut extraires des Service Tickets. Les Service Tickets sont en partie chiffrés avec une empreinte ou hash du mot de passe du compte de service associé avec le SPN : la clé secrète $K_{a}$. Si un algorithme de chiffrement faible comme RC4 est utilisé et que le mot de passe n’est pas complexe, une attaque par brute force pourrait assez facilement déchiffrer le Service Ticket et retrouver le mot de passe du compte de service.
- L’ASReqroast : dans cette attaque, un attaquant écoute le trafic réseau à la recherche de paquets $AS$_$REQ$ utilisant l’algorithme RC4 afin de brute-forcer le timestamp inclus pour trouver la clé de chiffrement $K_{c}$ et ainsi retrouver le mot de passe du compte associé.
- L’ASReproast : dans cette attaque, si la pré-authentification Kerberos n’est pas configurée, un attaquant peut envoyer des messages $AS$_$REQ$ qui seront traités sans vérification. L’attaquant écoute alors le trafic réseau à la recherche de paquets $AS$_$REP$ de réponse et si utilisant l’algorithme RC4 pour le chiffrement, il peut brute-forcer le message pour retrouver la clé de chiffrement $K_{c}$ et le mot de passe du compte associé.
- Le Silver Ticket : à partir de la clé $K_{a}$ du compte de service, un attaquant peut forger un Service Ticket appelé Silver Ticket qui donne accès à une application donnée. L’attaque par Silver Ticket requiert donc la compromission d’un compte de service.
- Le Golden Ticket : à partir de la clé $K_{k}$ du KDC, un attaquant peut forger des TGT donnant accès à n’importe quel service. L’attaque par Gold Ticket requiert la compromission du compte de service du KDC.
- La Skeleton Key : après avoir compromis l’administration locale du KDC, un attaquant peut installer une porte dérobéée ou backdoor en modifiant la configuration de Kerberos avec RC4 (algorithme faible sans salage, c’est-à-dire sans ajout de données aléatoires lors d’un hachage) et en ajoutant une clé de chiffrement dite Skeleton Key valide pour tous les comptes du domaine. Cela permet alors à un attaquant de s’authentifier pour n’importe quel compte lors de l’envoi de messages $AS$_$REQ$ car ces derniers contiennent l’empreinte chiffrée du timestamp déterminée à partir de la Skeleton Key.
La prévention des attaques énumérées ci-dessus repose principalement sur l’utilisation de mots de passe complexes, d’algorithmes de chiffrement forts et sur le renouvellement régulier des mots de passes et clés de chiffrement.
Conclusion
Nous avons plongé ensemble au cœur du protocole d’authentification Kerberos, très largement utilisé pour vérifier des identités désirant consommer des services sur un réseau. Reposant sur le chiffrement symétrique et l’échange de tickets, malgré certaines attaques décrites, il reste aujourd’hui suffisamment robuste, si correctement utilisé, pour être préféré à d’autres protocoles comme New Technology LAN Manager (NTLM) car ne transferant pas directement de mots de passe ou empreintes de mots de passe. Enfin, retenez qu’il existe d’autres protocoles SSO (comme par exemple Security Assertion Markup Language ou OpenID Connect) qui sont plus adaptés que Kerberos pour être utilisés sur Internet, sans nécessiter un KDC déployé dans un réseau local.
Sources
- Steve on Security - Kerberos Explained in a Little Too Much Detail: https://syfuhs.net/a-bit-about-kerberos. Consulté le 24/09/2023.
- Medium - Kerberos v5 Related Specs and RFCs : https://medium.com/@robert.broeckelmann/kerberos-v5-related-specs-and-rfcs-281c7b088025. Consulté le 05/09/2024.
- IETF - RFC 4120 - The Kerberos Network Authentication Service (V5) : https://datatracker.ietf.org/doc/html/rfc4120. Consulté le 24/09/2023.
- Wikipedia - Kerberos (protocol) : https://en.wikipedia.org/wiki/Kerberos_(protocol). Consulté le 24/09/2023.
- Thibaut Probst - Choisir le mode d’opération pour chiffrement par bloc - Cryptographie et chiffrement : https://thibautprobst.fr/posts/block-cipher/#cryptographie-et-chiffrement. Consulté le 1er décembre 2023.
- Massachusetts Institute of Technology - MIT Kerberos Documentation - keytab : https://web.mit.edu/kerberos/krb5-devel/doc/basic/keytab_def.html. Consulté le 24/09/2023.
- IETF - RFC 3962 - Advanced Encryption Standard (AES) Encryption for Kerberos 5 : https://datatracker.ietf.org/doc/html/rfc3962. Consulté le 24/09/2023.
- Stanford University IT - Kerberos and Firewalls : https://uit.stanford.edu/service/kerberos/firewalls. Consulté le 24/09/2023.
- hackndo - Délégation Kerberos - Fonctionnement : https://beta.hackndo.com/constrained-unconstrained-delegation/. Consulté le 05/09/2024.
- netwrix - What Is Kerberos Delegation? An Overview of Kerberos Delegation : https://blog.netwrix.com/2021/11/30/what-is-kerberos-delegation-an-overview-of-kerberos-delegation/. Consulté le 05/09/2024.
- netwrix - Unconstrained Delegation : https://blog.netwrix.com/2022/12/02/unconstrained-delegation/. Consulté le 05/09/2024.
- netwrix - Resource-Based Constrained Delegation Abuse : https://blog.netwrix.com/2022/09/29/resource-based-constrained-delegation-abuse/. Consulté le 05/09/2024.
- MITRE - ATT&CK - Steal or Forge Kerberos Tickets : https://attack.mitre.org/techniques/T1558/. Consulté le 05/09/2024.