Kerberos, expliqué comme un
parc d'attraction
Décortication du protocole Kerberos en Active Directory : phases AS, TGS et AP, structure des tickets, types de chiffrement et points de friction cote securite.
Maxime Jérôme··15 min de lecture
Prerequis
- Environnement Windows
- Comprehension basique de la cryptographie
- Introduction Active Directory
Hello ! o/
Kerberos est le protocole d'authentification dans Active Directory (AD). Il sert a avoir acces aux services de l'AD. Il est divise en plusieurs etapes :
- Authentification aupres d'une autorite
- Reception d'un ticket pour acceder a d'autres tickets
- Demande a l'autorite un ticket pour acceder a un service specifique
- Reception du ticket pour le service specifique
- Montrer le ticket au service specifique
- Acceder au service specifique
Vous pouvez le voir comme un parc d'attraction vraiment chelou : vous avez plusieurs stands un peu partout dans le parc qui vous permettent d'avoir un ticket pour acceder a des tickets pour les attractions. Donc vous revenez au meme stand de tickets pour demander un ticket pour une attraction grace au ticket qu'on vous a donne juste avant. On vous donne un nouveau ticket pour acceder a l'attraction : vous vous hatez avant qu'il ne soit plus valide, vous le donnez au mec qui gere l'attraction, il le verifie et enfin vous laisse acceder a l'attraction.
Client KDC (Key Distribution Center) Service
| | |
| 1. AS_REQ | |
| (demande de TGT) | |
|------------------------->| |
| | |
| 2. AS_REP | |
| (TGT + cle de session) | |
|<-------------------------| |
| | |
| 3. TGS_REQ | |
| (TGT + sname) | |
|------------------------->| |
| | |
| 4. TGS_REP | |
| (TGS pour le service) | |
|<-------------------------| |
| | |
| 5. AP_REQ (TGS) | |
|------------------------------------------------------> |
| | |
| 6. AP_REP (acces OK) | |
|<------------------------------------------------------ |
| | |Ces etapes sont definies formellement comme suit :
- Authentication Service (AS)
- Kerberos Authentication Service Request (KRB_AS_REQ)
- Kerberos Authentication Service Reply (KRB_AS_REP)
- Ticket-Granting-Service (TGS)
- Kerberos Ticket-Granting-Service Request (KRB_TGS_REQ)
- Kerberos Ticket-Granting-Service Reply (KRB_TGS_REP)
- Authentication Protocol (AP)
- Kerberos Authentication Protocol Request (KRB_AP_REQ)
- Kerberos Authentication Protocol Reply (KRB_AP_REP)
Phase AS (Authentication Service)
─────────────────────────────────────────────────────────────
Client ──[ KRB_AS_REQ : cname + etype + nonce ]──> KDC/DC
Client <──[ KRB_AS_REP : TGT + cle de session ]── KDC/DC
(chiffre avec la cle du client)
Phase TGS (Ticket-Granting-Service)
─────────────────────────────────────────────────────────────
Client ──[ KRB_TGS_REQ : TGT + authenticator + sname ]──> KDC
Client <──[ KRB_TGS_REP : TGS (ticket service) ]── KDC
(chiffre avec la cle du service)
Phase AP (Authentication Protocol)
─────────────────────────────────────────────────────────────
Client ──[ KRB_AP_REQ : TGS + authenticator ]──> Service
Client <──[ KRB_AP_REP : confirmation ]── ServiceSource : Obtaining a Service Ticket et Kerberos Network Authentication Service (V5) Synopsis
RFC de reference
Authentication Service (AS)
La phase AS de Kerberos permet de s'authentifier aupres du KDC (Key Distribution Center) / DC (Domain Controller). En retour, le KDC offre au client un TGT (Ticket-Granting Ticket) et une cle de session. La communication se fait en TCP sur le port 88 (TCP/88) avec le classique 3-way handshake SYN-SYNACK-ACK.
Kerberos Authentication Service Request (KRB_AS_REQ)
En premier lieu, le client se connecte sur le reseau en tapant son login et son mot de passe. Le client Kerberos sur la machine de l'utilisateur convertit le mot de passe utilisateur en cle de chiffrement symetrique.
On peut aussi utiliser une cle publique en guise de mot de passe : c'est un autre mecanisme d'authentification comme pkinit (RFC 4556) (authentification par cle PKI).
Le client Kerberos envoie donc une demande de TGT au KDC avec comme payload :
as-req
├── pvno
├── msg-type
└── req-body
├── kdc-options
├── cname [OPT]
├── realm
├── sname [OPT]
├── from [OPT]
├── till
├── rtime [OPT]
├── nonce
├── etype
└── addresses [OPT]| Champ | Description |
|---|---|
| pvno | Version du protocole Kerberos, actuellement 5 |
| msg-type | Type de message, ici KRB_AS_REQ |
| kdc-options | Flags |
| cname | Client/User Principal Name (CPN / UPN), exemple : utilisateur@domain.com |
| realm | Kerberos Principal Name (KPN) / nom de domaine Windows |
| sname | Service Principal Name (SPN), ici krbtgt |
| from | Timestamp : c'est le starttime dont parle la RFC |
| till | Temps d'expiration de KRB_AS_REQ |
| rtime | Temps d'expiration pour un ticket RENEWABLE |
| nonce | Nombre aleatoire de type uint32_t genere par le client |
| etype | Encryption Types : methodes de chiffrement acceptees par le client |
| addresses | Adresse du client, contient d'autres adresses si on passe par un proxy |
Client KDC (port TCP/88)
| |
| KRB_AS_REQ |
| ┌────────────────────────────────┐ |
| │ pvno : 5 │ |
| │ msg-type : KRB_AS_REQ │ |
| │ req-body │ |
| │ cname : alice@corp.local │ |
| │ realm : CORP.LOCAL │ |
| │ sname : krbtgt │ |
| │ etype : [AES256, RC4, ...] │ |
| │ nonce : 0xCAFEBABE │ |
| │ till : 2024-04-06T00:00Z │ |
| └────────────────────────────────┘ |
|---------------------------------------->
| |Source : Kerberos Authentication - HackTricks
Kerberos Authentication Service Reply (KRB_AS_REP)
Le serveur d'authentification (KDC) recoit les donnees. Il verifie le cname et en extrait les cles respectives (il peut y en avoir plusieurs). Il prend celles definies par le champ etype de KRB_AS_REQ pour selectionner la methode de chiffrement a utiliser pour proteger une partie de KRB_AS_REP. S'il y a plusieurs valeurs dans etype, on prend la premiere valide.
Chiffrement faible = attaques possibles
DES_CBC_CRC: obsolete (avant Windows Server 2008 R2)DES_CBC_MD5: obsolete (avant Windows Server 2008 R2)RC4_HMAC_MD5: faillible KerberoastAES128_HMAC_SHA1: recommandeAES256_HMAC_SHA1: recommande
Le KDC renvoie plusieurs elements :
- La cle de session
- Le TGT (Ticket-Granting Ticket) contenant :
- Nom d'utilisateur
- Periode de validite
- Cle de session
- Le Privilege Attribute Certificate (PAC)
En detail, le payload complet :
as-rep
├── pvno
├── msg-type
├── padata [OPT]
├── crealm
├── cname
├── ticket: TGT
│ ├── tkt-vno
│ ├── realm
│ ├── sname
│ └── enc-part (chiffre par la cle du KDC)
│ ├── flags
│ ├── key
│ ├── crealm
│ ├── cname
│ ├── transited
│ │ ├── tr-type
│ │ └── contents
│ ├── authtime
│ ├── starttime [OPT]
│ ├── endtime
│ ├── renew-till [OPT]
│ ├── caddr [OPT]
│ └── authorization-data [OPT] <- PAC
└── enc-part (chiffre par la cle du client)
├── key
├── last-req
│ ├── lr-type
│ └── lr-value
├── nonce
├── key-expiration [OPT]
├── flags
├── authtime
├── starttime [OPT]
├── endtime
├── renew-till [OPT]
├── srealm
├── sname
└── caddr [OPT]| Champ | Description |
|---|---|
| padata | Pre-Authentication Data |
| crealm | Contient le nom du realm ou le client s'est authentifie initialement |
| ticket | Structure de donnee pour un ticket/authenticator |
| tkt-vno | Version du format du ticket |
| realm | Quel realm a fourni le ticket |
| enc-part (TGT) | Chiffre symetriquement, uniquement lisible par le KDC |
| key | Cle de session pour etre passee du KDC a l'AP et au Client |
| transited | Kerberos realms qui ont participe a l'authentification du client |
| authtime | Timestamp de l'auth initiale |
| starttime | Timestamp a partir duquel le ticket est valide |
| endtime | Timestamp a partir duquel le ticket est invalide |
| renew-till | Si RENEWABLE : indique le maximum endtime pour un renouvellement (endtime absolu) |
| caddr | Adresses qui peuvent utiliser le ticket ; si vide, n'importe quelle adresse peut l'utiliser |
| authorization-data | Le PAC (Privilege Attribute Certificate) : liste des restrictions du ticket |
| enc-part (outer) | Chiffre symetriquement, lisible par KDC et Client |
| last-req | Timestamp de la derniere requete pour un TGT dans un contexte specifique |
| lr-type | last-req type : aide a interpreter lr-value (contexte) |
| lr-value | last-req value : timestamp |
| key-expiration | Timestamp a partir duquel la cle secrete du client expire |
Client KDC (port TCP/88)
| |
| KRB_AS_REP|
| ┌──────────────────────────────────────┤
| │ enc-part (chiffre cle client) │
| │ key : cle de session │
| │ nonce : echo du nonce client │
| │ endtime : validite TGT │
| │ │
| │ ticket: TGT │
| │ enc-part (chiffre cle KDC) │
| │ cname : alice@corp.local │
| │ key : cle de session │
| │ authorization-data : PAC │
| │ endtime / flags │
| └──────────────────────────────────────┤
|<-----------------------------------------
| |
| Client dechiffre enc-part -> cle session
| TGT reste opaque pour le client |Source : Kerberos Authentication - HackTricks
Ticket-Granting-Service (TGS)
Maintenant que notre client a son TGT avec ses droits inscrits dessus, il peut demander au KDC d'acceder aux services du reseau. Pour ca, il demande un TGS (un ticket qui donne acces a un service specifique) sous la forme d'un couple cle de session / TGS.
Kerberos Ticket-Granting-Service Request (KRB_TGS_REQ)
Le client Kerberos demande au KDC un TGS sous la forme d'un KRB_TGS_REQ. Grosso modo, le message consiste a donner :
- Quel service le client veut acceder (SPN via
sname) - Le TGT
- Un authenticator qui contient surtout le
cnameet unctime
Structure de l'authenticator
authenticator
├── authenticator-vno
├── crealm
├── cname
├── cksum [OPT]
├── cusec
├── ctime
├── subkey [OPT]
├── seq-number [OPT]
└── authorization-data [OPT]| Champ | Description |
|---|---|
| authenticator | Chiffre avec la cle de session |
| authenticator-vno | Version de l'authenticator |
| ck-sum | Checksum |
| cusec | Client USeconds : microsecondes du timestamp client |
| ctime | Timestamp du client |
| subkey | Cle a utiliser pour KRB_TGS_REP ; si absent, on utilise la cle de session du TGT |
| seq-number | Detecte les requetes rejouees, agit un peu comme l'ACK de TCP |
| authorization-data | Restrictions additionnelles par rapport a celles du TGT |
Payload complet KRB_TGS_REQ
Ce qui change par rapport a AS_REQ : le flag ENC-TKT-IN-SKEY indique au KDC qu'on ajoute le TGT dans le champ additional-tickets, avec un champ optionnel enc-authorization-data.
tgs-req
├── pvno
├── msg-type
├── padata: PA-TGS-REQ
└── req-body
├── kdc-options: ENC-TKT-IN-SKEY
├── cname [OPT]
├── realm
├── sname [OPT]
├── from [OPT]
├── till
├── rtime [OPT]
├── nonce
├── etype
├── addresses [OPT]
├── enc-authorization-data
└── additional-tickets
├── TGT
└── authenticator| Champ | Description |
|---|---|
| enc-authorization-data | PAC desire, chiffre avec la cle de session (ou cle TGT si pas de subkey) |
| additional-tickets | Tickets additionnels a la requete (TGT + authenticator) |
Client KDC (port TCP/88)
| |
| KRB_TGS_REQ |
| ┌─────────────────────────────────────┐
| │ padata: PA-TGS-REQ │
| │ authenticator (chiffre cle sessn) │
| │ cname : alice@corp.local │
| │ ctime : <now> │
| │ req-body │
| │ sname : http/srv.corp.local │
| │ realm : CORP.LOCAL │
| │ etype : [AES256, ...] │
| │ additional-tickets │
| │ TGT (opaque pour le client) │
| └─────────────────────────────────────┘
|---------------------------------------->
| |Source : Kerberos Authentication - HackTricks
Kerberos Ticket-Granting-Service Reply (KRB_TGS_REP)
Le KDC recoit le KRB_TGS_REQ. Il est traite de la meme maniere que KRB_AS_REQ, mais avec plus de checks : s'il y a plus de donnees, il y a plus de verifications. Par exemple, on compare le TGT et l'authenticator pour s'assurer que le TGT appartient bien au client (comparaison cname et key). Ensuite, on verifie si le client a bien le droit d'acceder au sname grace au PAC (authorization-data du TGT).
tgs-rep
├── pvno
├── msg-type
├── padata [OPT]
├── crealm
├── cname
├── ticket: TGS
│ └── enc-part (chiffre cle du service/AP)
└── enc-part (chiffre cle du client)| Champ | Description |
|---|---|
| ticket:enc-part | Chiffre symetriquement, lisible par le KDC et le service/AP uniquement |
| enc-part | Chiffre symetriquement, lisible par le KDC et le Client |
C'est son ticket d'entree pour rentrer dans le service ! Hooray \o/ !
Client KDC (port TCP/88)
| |
| KRB_TGS_REP|
| ┌──────────────────────────────────────┤
| │ enc-part (chiffre cle client) │
| │ key : cle de session service │
| │ nonce : echo nonce client │
| │ │
| │ ticket: TGS │
| │ enc-part (chiffre cle service) │
| │ cname : alice@corp.local │
| │ key : cle de session service │
| │ authorization-data : PAC │
| └──────────────────────────────────────┤
|<-----------------------------------------
| |
| Client dechiffre enc-part -> cle sessn service
| TGS reste opaque pour le client |Source : Kerberos Authentication - HackTricks
Authentication Protocol (AP)
On y est ! Desormais le but est de creer une communication securisee entre le client et le service. Le service pourra dechiffrer notre TGS grace a sa propre cle. Le TGS permet d'authentifier le client aupres du service.
Kerberos Authentication Protocol Request (KRB_AP_REQ)
Notre client doit faire le premier pas vers le service. Grace a la KRB_TGS_REP, nous avons acces a la cle de session du service. On va donc generer nos nouveaux authentifiants pour le service : un authenticator chiffre avec la cle de session du service. On envoie a la suite notre TGS (qu'on ne peut pas lire, mais que le service peut dechiffrer).
ap-req
├── pvno
├── msg-type
├── ap-options
├── ticket: TGS
└── authenticator (chiffre avec la cle de session service)| Champ | Description |
|---|---|
| authenticator | Chiffre avec la cle de session du service |
Client Service
| |
| KRB_AP_REQ |
| ┌──────────────────────────────────────────────┐ |
| │ ap-options │ |
| │ │ |
| │ ticket: TGS │ |
| │ enc-part (chiffre cle service) │ |
| │ cname : alice@corp.local │ |
| │ key : cle de session service │ |
| │ authorization-data : PAC │ |
| │ │ |
| │ authenticator (chiffre cle session service) │ |
| │ cname : alice@corp.local │ |
| │ ctime : <now> │ |
| └──────────────────────────────────────────────┘ |
|--------------------------------------------------> |
| |
| Service dechiffre TGS avec sa cle |
| Verifie authenticator |Source : Kerberos Authentication - HackTricks
Kerberos Authentication Protocol Reply (KRB_AP_REP)
Enfin, si tout est bon (comparaison entre le TGS et l'authenticator), le client peut acceder au service. Attention : le service peut demander confirmation du PAC au KDC. Dans le cas ou le bit mutual-required(2) est mis dans ap-options, le service renverra bien un KRB_AP_REP.
Client Service
| |
| KRB_AP_REP |
| ┌──────────────────────────────────────────────┐ |
| │ enc-part (chiffre cle session service) │ |
| │ ctime : echo du ctime client │ |
| │ cusec : echo du cusec client │ |
| │ subkey [OPT] : nouvelle sous-cle │ |
| └──────────────────────────────────────────────┘ |
|<-------------------------------------------------- |
| |
| Acces au service accorde ! |
| |
| Note : KRB_AP_REP uniquement si |
| ap-options: mutual-required(2) |En resume : qui lit quoi ?
- TGT enc-part : chiffre avec la cle du KDC (krbtgt). Seul le KDC peut le lire. Le client le transporte sans le voir.
- TGS enc-part (ticket) : chiffre avec la cle du service. Seul le service peut le lire. Le client le transporte sans le voir.
- enc-part (outer, AS_REP et TGS_REP) : chiffre avec la cle du client (ou cle de session). Le client le dechiffre pour recuperer la cle de session.
- Authenticator : chiffre avec la cle de session courante. Prouve que le client possede bien la cle sans la transmettre en clair.
Merci pour votre lecture :)
Liens utiles
- Kerberos en Active Directory (Hackndo)
- Kerberos Authentication - HackTricks
- Obtaining a Service Ticket (Microsoft)
- Authentication Service Exchange (Microsoft)
- Kerberos Network Authentication Service (V5) Synopsis (Microsoft)
- Kerberos Explained (Microsoft)
- Kerberos (protocole) - Wikipedia
- Are there any reasons for Kerberos being based on symmetric cryptography? (Security StackExchange)
- Kerberos authentication explained (Mark Wilson)
- RFC 4120
- RFC 4120 FR