Aller au contenu principal
own2pwn
ad/ad-krb.tsx

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

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.

kerberos-vue-ensemble.txt
  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)    |                               |
    |<------------------------------------------------------   |
    |                          |                               |
Vue d'ensemble du flux Kerberos : AS, TGS et AP en un seul schema.

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)
kerberos-phases.txt
  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 ]──          Service
Les trois grandes phases : AS (obtention du TGT), TGS (obtention du ticket service), AP (acces au service). Source : Microsoft docs.

Source : Obtaining a Service Ticket et Kerberos Network Authentication Service (V5) Synopsis

RFC de reference
Pour suivre cet article en detail, munissez-vous de la RFC 4120. Elle definit l'integralite du protocole Kerberos V5.

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-payload.txt
  as-req
  ├── pvno
  ├── msg-type
  └── req-body
      ├── kdc-options
      ├── cname          [OPT]
      ├── realm
      ├── sname          [OPT]
      ├── from           [OPT]
      ├── till
      ├── rtime          [OPT]
      ├── nonce
      ├── etype
      └── addresses      [OPT]
Structure du payload KRB_AS_REQ (RFC 4120, section 5.4.1).
ChampDescription
pvnoVersion du protocole Kerberos, actuellement 5
msg-typeType de message, ici KRB_AS_REQ
kdc-optionsFlags
cnameClient/User Principal Name (CPN / UPN), exemple : utilisateur@domain.com
realmKerberos Principal Name (KPN) / nom de domaine Windows
snameService Principal Name (SPN), ici krbtgt
fromTimestamp : c'est le starttime dont parle la RFC
tillTemps d'expiration de KRB_AS_REQ
rtimeTemps d'expiration pour un ticket RENEWABLE
nonceNombre aleatoire de type uint32_t genere par le client
etypeEncryption Types : methodes de chiffrement acceptees par le client
addressesAdresse du client, contient d'autres adresses si on passe par un proxy
as-req-flux.txt
  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  │    |
    |  └────────────────────────────────┘    |
    |---------------------------------------->
    |                                        |
Flux KRB_AS_REQ : le client envoie cname, etype et nonce au KDC pour obtenir un TGT. Source : HackTricks.

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
Si votre Kerberos en AD utilise un systeme de chiffrement symetrique faible, il sera faillible a plusieurs attaques. Voici les methodes de chiffrement disponibles :
  • DES_CBC_CRC : obsolete (avant Windows Server 2008 R2)
  • DES_CBC_MD5 : obsolete (avant Windows Server 2008 R2)
  • RC4_HMAC_MD5 : faillible Kerberoast
  • AES128_HMAC_SHA1 : recommande
  • AES256_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-payload.txt
  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]
Structure complete du payload KRB_AS_REP avec le TGT imbrique.
ChampDescription
padataPre-Authentication Data
crealmContient le nom du realm ou le client s'est authentifie initialement
ticketStructure de donnee pour un ticket/authenticator
tkt-vnoVersion du format du ticket
realmQuel realm a fourni le ticket
enc-part (TGT)Chiffre symetriquement, uniquement lisible par le KDC
keyCle de session pour etre passee du KDC a l'AP et au Client
transitedKerberos realms qui ont participe a l'authentification du client
authtimeTimestamp de l'auth initiale
starttimeTimestamp a partir duquel le ticket est valide
endtimeTimestamp a partir duquel le ticket est invalide
renew-tillSi RENEWABLE : indique le maximum endtime pour un renouvellement (endtime absolu)
caddrAdresses qui peuvent utiliser le ticket ; si vide, n'importe quelle adresse peut l'utiliser
authorization-dataLe PAC (Privilege Attribute Certificate) : liste des restrictions du ticket
enc-part (outer)Chiffre symetriquement, lisible par KDC et Client
last-reqTimestamp de la derniere requete pour un TGT dans un contexte specifique
lr-typelast-req type : aide a interpreter lr-value (contexte)
lr-valuelast-req value : timestamp
key-expirationTimestamp a partir duquel la cle secrete du client expire
as-rep-flux.txt
  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        |
Flux KRB_AS_REP : le KDC renvoie le TGT (lisible uniquement par le KDC) et la cle de session chiffree avec la cle du client. Source : HackTricks.

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 cname et un ctime

Structure de l'authenticator

authenticator-payload.txt
  authenticator
  ├── authenticator-vno
  ├── crealm
  ├── cname
  ├── cksum          [OPT]
  ├── cusec
  ├── ctime
  ├── subkey         [OPT]
  ├── seq-number     [OPT]
  └── authorization-data [OPT]
Structure de l'authenticator Kerberos, chiffre avec la cle de session du TGT.
ChampDescription
authenticatorChiffre avec la cle de session
authenticator-vnoVersion de l'authenticator
ck-sumChecksum
cusecClient USeconds : microsecondes du timestamp client
ctimeTimestamp du client
subkeyCle a utiliser pour KRB_TGS_REP ; si absent, on utilise la cle de session du TGT
seq-numberDetecte les requetes rejouees, agit un peu comme l'ACK de TCP
authorization-dataRestrictions 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-payload.txt
  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
Structure complete du payload KRB_TGS_REQ.
ChampDescription
enc-authorization-dataPAC desire, chiffre avec la cle de session (ou cle TGT si pas de subkey)
additional-ticketsTickets additionnels a la requete (TGT + authenticator)
tgs-req-flux.txt
  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)       │
    |  └─────────────────────────────────────┘
    |---------------------------------------->
    |                                        |
Flux KRB_TGS_REQ : le client presente son TGT et un authenticator chiffre avec la cle de session pour obtenir un TGS. Source : HackTricks.

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-payload.txt
  tgs-rep
  ├── pvno
  ├── msg-type
  ├── padata         [OPT]
  ├── crealm
  ├── cname
  ├── ticket: TGS
  │   └── enc-part   (chiffre cle du service/AP)
  └── enc-part       (chiffre cle du client)
Structure du payload KRB_TGS_REP.
ChampDescription
ticket:enc-partChiffre symetriquement, lisible par le KDC et le service/AP uniquement
enc-partChiffre symetriquement, lisible par le KDC et le Client

C'est son ticket d'entree pour rentrer dans le service ! Hooray \o/ !

tgs-rep-flux.txt
  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        |
Flux KRB_TGS_REP : le KDC renvoie le TGS chiffre avec la cle du service (opaque pour le client) et la cle de session service chiffree pour le client. Source : HackTricks.

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-payload.txt
  ap-req
  ├── pvno
  ├── msg-type
  ├── ap-options
  ├── ticket: TGS
  └── authenticator    (chiffre avec la cle de session service)
Structure du payload KRB_AP_REQ.
ChampDescription
authenticatorChiffre avec la cle de session du service
ap-req-flux.txt
  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               |
Flux KRB_AP_REQ : le client envoie son TGS (opaque pour lui) et un authenticator chiffre avec la cle de session service. Source : HackTricks.

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.

ap-rep-flux.txt
  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)                   |
Flux KRB_AP_REP : le service confirme l'identite du client. L'acces au service est accorde.
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