
Kerberos est un protocole d’authentification notamment utilisé dans un contexte « Microsoft Active Directory ». La méconnaissance de son fonctionnement peut permettre l’introduction de vulnérabilités exploitables par un attaquant.
Dans cet article, nous expliciterons le principe et le fonctionnement du protocole d’authentification Kerberos.
Kerberos est un protocole d’authentification réseau, principalement utilisé pour permettre aux utilisateurs et aux services d’un réseau de vérifier leur identité.
Il repose sur le concept de « tiers de confiance », c’est-à-dire qu’il utilise un serveur d’authentification centralisé pour valider les identités et distribuer des tickets qui permettent d’accéder à des services.
Ci-dessous les éléments clés de Kerberos, que nous détaillerons dans les prochaines sections :
Le protocole Kerberos fonctionne selon trois acteurs.

Déjà au niveau des acteurs et de leur fonctionnement dans un « Active Directory », il y a des notions subtiles qui méritent éclaircissement.
Concernant le client, il peut être n’importe quelle entité du domaine disposant d’un secret connu du KDC. Cela inclut tous les utilisateurs et les machines du domaine.
Par ailleurs, n’importe quel client peut faire une demande d’accès Kerberos à n’importe quel service. En outre, le protocole Kerberos n’a pas pour rôle de vérifier si le client est autorisé à accéder au service demandé. Cette responsabilité est laissée au service.
Concernant le service, il est une entité du domaine (utilisateur ou machine) qui dispose d’un secret connu du KDC.
Il doit disposer également d’un ou plusieurs « Service Principal Name » (SPN) enregistré auprès du contrôleur de domaine. Cet enregistrement consiste à inscrire les services proposés sur la propriété « ServicePrincipalName » de l’objet « Active Directory » de l’entité.
Le secret associé à ce service est utilisé par le KDC pour fournir un ticket au client. Ce comportement peut avoir à une conséquence sur la confidentialité du secret du service dans certains cas.
Concernant le KDC, son secret est celui du compte utilisateur par défaut « krbtgt ».
De fait, la sécurité du protocole kerberos repose sur la confidentialité du secret de krbtgt. La fuite de ce secret compromet toute la logique de sécurité du protocole.
Le protocole Kerberos utilise la notion de tickets. Il en existe deux types qui interviennent à des étapes différentes du protocole. Ces tickets sont générés par le KDC à destination du client en utilisant les secrets à disposition du KDC.
Dans la suite de l’article, la manipulation des tickets va s’illustrer avec les outils « impacket » et « Rubeus ». Ces deux outils sont très utiles pour effectuer manuellement les étapes individuelles du protocole Kerberos.
En revanche, il faut garder à l’esprit que pour un utilisateur sur une machine rattachée au domaine Active directory, ces étapes sont totalement transparentes.
Concernant les outils en eux-mêmes, Rubeus s’utilisera sur une machine Windows et impacket sur les autres systèmes d’exploitation.
Le premier type de ticket est le « Ticket-Granting Ticket » (appelé TGT par la suite). Ce ticket est obtenu lors de la phase « authentication service » qui consiste à démontrer auprès du KDC la connaissance du secret du client.
Voici les commandes permettant d’effectuer la phase « authentication service ».
En utilisant la librairie « impacket » et son script « getTGT.py » :
getTGT.py -dc-ip <IP KDC/DC> <domain>/<user>:<password>
Un fichier “.ccache” sera créé par le script.
En utilisant l’outil « Rubeus » :
Rubeus.exe asktgt /user:<user> /password:<password> /domain:<domain> /dc:<IP KDC/DC> /outfile:<user>_tgt.kirbi
Un fichier « .kirbi » sera créé par le programme.
La figure animée ci-dessous montre le fonctionnement de cette phase.

Ainsi, à la fin de la phase « authentication service », le client dispose d’une clé de session et d’un ticket « TGT ». Ces deux éléments serviront à justifier l’identité du client lors de la phase suivante.
Il est possible de consulter ces éléments à l’intérieur des fichiers créés par les commandes ci-dessus. Notons que le contenu du TGT est en partie chiffré avec le secret du KDC. Le client est donc dans l’incapacité de modifier ou consulter cette partie.
Pour être plus précis, la répartition des informations reçues lors de l’étape « authentification service » est la suivante :

La partie chiffrée du TGT contient des informations sur le ticket (flags, durée de vie, etc.) mais aussi les informations d’identité du client (nom, groupe, UAC, etc.) et une copie de la clé de sessions.
Ainsi, le client ne peut falsifier son identité, car la modification du TGT requiert le secret du KDC.
Le ticket de service (ST) est le second ticket obtenu par le client. Il s’obtient lors de la phase « Ticket-Granting Service » (TGS).
Lors de cette phase, le client va demander l’accès à un service en utilisant le TGT et la clé de session précédemment obtenus et en ciblant un « Service Principal Name » (SPN) existant.
Voici les commandes permettant d’effectuer la phase « Ticket-Granting Service » en donnant explicitement le ticket obtenu lors de la phase précédente.
En utilisant la librairie « impacket » et le script d’exemple « getST.py » :
KRB5CCNAME=<TGT_ccache_file> getST.py -dc-ip <IP KDC/DC> -spn <Target_SPN> <domain>/<user> -no-pass -k
En utilisant l’outil « Rubeus » :
Rubeus.exe asktgs /ticket:<TGT_kirbi_file> /service:<Target_SPN> /dc:<IP KDC/DC> /outfile:<user>_st_<SPN>.kirbi
La figure animée ci-dessous montre le fonctionnement de cette phase :

NB : Impacket peut être utilisé pour enchainer l’étape AS et TGS de sorte à récupérer un ticket de service en fournissant directement le secret du client.
getST.py -dc-ip <IP KDC/DC> -spn <Target_SPN> <domain>/<user>:<password>
À la fin de cette phase, le client reçoit un ticket de service (ST) et une clé de session de service. Une partie du ticket de service est chiffrée avec le secret du service ciblé. Cette partie contient notamment les informations d’identité du client, le SPN ciblé, ainsi qu’une copie de la clé de session de service.
En somme, le contenu d’un ST est similaire à un TGT excepté que le champ associé au « Service principal Name » (SPN) contiendra la référence à un service déclaré. Dans le cas d’un TGT ce champ fait référence au service « krbtgt » du KDC.

Après l’obtention du ticket de service (ST), le client est maintenant en mesure de s’authentifier auprès du service.
Cette étape est connue sous le nom de « application request » (AP) et peut être illustrée par la figure suivante :

Selon que vous utilisiez impacket ou Rubeus, la démarche d’accès aux services sera différente.
La plupart des outils basés sur la librairie impacket intègrent l’utilisation de Kerberos dans leurs options. Ici, on suppose qu’un fichier « .ccache » a été généré lors d’une des étapes précédentes. Ce fichier « .ccache » peut tout aussi bien contenir un TGT qu’un ST, la démarche reste la même. Dans le cas d’un TGT, l’outil effectuera de lui-même l’étape TGS.
L’intégration de ce fichier « .ccache » se fera en renseignant le chemin vers ce fichier dans la variable d’environnement « KRB5CCNAME », puis en spécifiant les options dédiées à Kerberos pour le script utilisé.
Notons que dans l’écosystème de impacket, il existe autant de scripts que de services avec lesquelles interagir (smbclient-ng.py, dnstool.py, wmiexec.py, etc.).
Voici un exemple d’interaction sur le service SMB avec le script smbclient-ng.py.
$ export KRB5CCNAME=/path/to/user.ccache
$ smbclient-ng.py --kdcHost=<kdc FQDN> -d <domain> -u <user> --host <FQDN of server> -k --nopass
La démarche pour interagir avec les tickets générés par Rubeus est différente. Elle consiste à appliquer le ticket généré directement dans une « logon session ».
Cette action peut être réalisée de différente façon en fonction du niveau de privilège.
Si l’utilisateur de Rubeus n’est pas administrateur de la machine, il peut se servir de l’option « /ptt » pour appliquer le ticket généré à la session courante. Mais cela aura pour défaut d’écraser la session et donc de modifier les accès de l’utilisateur actuel de la machine.
Rubeus.exe asktgt /user:<user> /password:<password> /domain:<domain> /dc:<IP KDC/DC> /ptt
# or
Rubeus.exe ptt /ticket:<path/to/ticket.kirbi>
Pour éviter cet inconvénient, il est possible, dès lors que l’on est administrateur sur la machine Windows, de créer un « sacrificial process » sur lequel on appliquera nos tickets générés. Les options « /ptt » et « /createnetonly » peuvent être utilisées dans cette optique.
Rubeus.exe asktgt /user:<user> /password:<password> /domain:<domain> /dc:<IP KDC/DC> /ptt /createnetonly:C:PathtoProgramtolaunch
Il est possible de lister les tickets Kerberos de la session active avec la commande « klist ».

Dès lors que la « Logon Session » est configurée, il sera possible d’interagir de façon transparente avec le service cible.
NB : Avec l’option « createnetonly », il est important de comprendre que seules les interactions réseau de ce programme seront effectuées avec l’identité injectée. Dans le cadre des interactions locales avec le système, le programme utilisera l’identité de l’utilisateur d’origine.
La plupart des opérations de chiffrement ou de déchiffrement dans le protocole kerberos utilisent une clé symétrique considérée comme un secret associé à un acteur. Ce secret, aussi appelé clé kerberos, est calculé en appliquant une fonction de hachage au mot de passe du compte de l’acteur (utilisateur ou machine).
À titre d’illustration, voici comment calculer les clés kerberos dérivées du mot de passe d’un compte avec le programme « Rubeus ».
Rubeus.exe hash /password:<password> /user:<username> /domain:<domain>

Plusieurs fonctions de hachages sont applicables et chacune d’elles permettra de générer une clé différente pour un même mot de passe. Afin d’identifier quelle clé est utilisée dans le cadre d’un chiffrement, la propriété « encryption-type » ou « etype » est toujours précisé lorsqu’un élément chiffré est transmis.
Dans un environnement Active Directory, deux des algorithmes de hachage proposés se distinguent :
Ce mode de fonctionnement a une conséquence. Bien que les clés Kerberos utilisées soient toutes des dérivés du mot de passe d’un compte, il n’est techniquement pas nécessaire de connaître la valeur réelle du mot de passe. Seule la connaissance des clés est nécessaire pour user du protocole kerberos.
C’est la raison pour laquelle les outils comme impacket ou Rubeus proposent une option pour l’utilisation directe de ces clés plutôt que l’utilisation du mot de passe.
Avec impacket :
getTGT.py -hashes :<NTHASH> <domain>/<username> -no-pass
# or
getTGT.py -aes <aeskey> <domain>/<username> -no-pass
Avec Rubeus :
Rubeus.exe asktgt /rc4:<NTHASH> /user:<username> /domain:<domain>
# or
Rubeus.exe asktgt /aes256:<aeskey> /user:<username> /domain:<domain>
Ces clés Kerberos peuvent être récupérées en cas de compromission d’une machine sur laquelle ces secrets sont stockés. Dans ce sens, la plupart des outils d’extraction de secrets proposent l’affichage de telles clés.

Avec l’ensemble des éléments présentés dans cette première partie, nous espérons que vous serez en mesure d’appréhender le fonctionnement global du protocole Kerberos.
Nous reviendrons dans un autre article sur les principes de la délégation Kerberos. Nous explorerons également sur les vulnérabilités et attaques courantes sur ce protocole; en présentant des exemples d’exploitations critiques rencontrés lors de nos pentests de réseaux intégrant un Active Directory.
Auteur : Benoit PHILIPPE – Pentester @Vaadata