Kerberos Unlocked (Part 1): The Flow of Authentication

Kerberos is everywhere in Active Directory, but most beginners find it confusing. In this post, we’ll strip it down to the basics.

💡
This will be an series of posts, this is just part 1.

Whenever a domain-joined user tries to log in, the request is sent to the KDC (Key Distribution Center). The KDC is a service that always runs on the Domain Controller. KDC's main job is to securely authenticate users and services on a network by issuing authentication tickets and session keys .

Here is how the process works (Explained Step by Step Below):

The Kerberos authentication process can be broken down into three main phases.

  1. First, the client authenticates to the domain.
  2. Second, the client uses that then request Service Tickets from the KDC, which are required to access specific services.
  3. Finally, in the third phase, the client presents those Service Tickets to the respective services to actually interact with them.
💡
This post covers "Phase 1". Others are covered in next posts

AS-REQ

This is the initial request sent by the client to the KDC. This request is made as soon as the user enters his username and password to login.

This basically says "Hey its me Alice (client in this example) and i want to authenticate".

This is how the request is structured (sent over the network to the KDC):

  1. padata (pre-authentication data):
    1. PA-ENC-TIMESTAMP → Contains the client’s current timestamp, encrypted with the client’s long-term key (the long-term key is explained below [EXPLAINED HERE]). The use of this encrypted timestamp is explained below. [EXPLAINED BELOW]
  2. KDC-REQ-BODY (req-body):
    1. cname / crealm → Client’s principal name + realm (alice@LAB.LOCAL)
    2. sname / srealm → Service requested, always krbtgt/LAB.LOCAL
    3. till → Requested expiration time (how long Alice wants the TGT).
    4. rtime → Requested renew-until time (optional).
    5. nonce → Random number to bind reply to this request.
    6. etype → List of supported encryption types (AES256, AES128, RC4).
Visual representation of the request:
Here is how it looks like in Wireshark:

Long Term Key:

The long-term key is derived from the principal’s plaintext password, usually using AES256 with a salt based on the principal’s username and Kerberos realm name. (it is basically user's password converted into an key using some cryptographic functions).

How the KDC verifies client's identity?

You’ll notice that the user never sends their clear-text password, or even the hash of it, across the network. Instead, the KDC verifies the client through the PA-ENC-TIMESTAMP field. The client encrypts the current timestamp with its long-term key (a secret key derived from the user’s password) and stores it in the PA-ENC-TIMESTAMP field.

The KDC, which has its own copy of that same key, attempts to decrypt the timestamp. If the decryption works and the timestamp is valid (If the decrypted time is outside the allowed window, which by default is ~5 minutes, the KDC rejects it ), the KDC knows it’s really talking to the legitimate client—because no one else should have access to that key (hence no one except the client could have encrypted the timestamp).


AS-REP

The AS-REP is the KDC’s response. It provides the client with a Ticket Granting Ticket (TGT) — essentially a proof token that confirms the client’s identity (this is what the user Alice will use to prove that it is Alice).

Here is how the returned response is structured (sent back over the network, from the KDC):

  1. padata (optional) → Pre-authentication data from the KDC (not smth important for us right now, we’ll revisit later) .
  2. crealm → Client’s realm (e.g., LAB.LOCAL, basically the domain.)
  3. cname → Client’s principal name (e.g., alice).
  4. ticket → The Ticket-Granting Ticket (this is the actual ticket which will be used by the client to prove its identity from now on) [EXPLAINED BELOW]:
    1. realm → Realm of the issuing KDC.
    2. sname → Service name (always krbtgt/REALM).
    3. enc-partEncrypted with the krbtgt account’s key (this is encrypted using the krbtgt account long-term-key, so the user cannot decrypt it):
      1. Flags → The flag field contains properties about how the ticket can be used (But its not important right now, will be explained later, when we see Attacks).
      2. KeySession Key. [EXPLAINED BELOW]
      3. CRealm → client realm (basically the domain)
      4. CName → client name
      5. Transited → field is only relevant in multi-realm (But its not important right now, will be explained later)
      6. authtime → When authentication happened.
      7. starttime (optional) → When ticket validity starts.
      8. endtime → When ticket expires.
      9. renew-till (optional) →Max renewable lifetime — the time until the ticket can be renewed (not important for us right now).
      10. caddr → The idea behind the Client addresses (caddr) field was to prevent reusing the same ticket from a different IP address or machine. In practice, though, this field is usually left empty in Active Directory, which is why tickets can often be used on other systems as well.)
      11. Authorization-data → PAC in AD, with groups/SIDs/privileges [EXPLAINED BELOW]
  5. enc-part → The EncASRepPart, encrypted with the client’s long-term key (so the client can read it):
    1. key → Session key (same as in the TGT). [EXPLAINED BELOW]
    2. last-req → Info about last successful logon (in AD).
    3. noncenonce is just a random number the client included in its AS-REQ (if you remember). The KDC copies it back into the AS-REP. This way, the client knows the reply matches its request and isn’t a replay of some older message
    4. key-expiration (optional) → It tells the client when its password is set to expire (rarely used).
    5. flags → Ticket flags (the same as in the Ticket).
    6. authtime → Same as in the TGT.
    7. starttime (optional) → Same as in the TGT..
    8. endtime → Same as in the TGT.s.
    9. renew-till (optional) → Same as in the TGT..
    10. srealm → Realm of the TGT’s service (KDC realm, basically the domain on which the KDC is running).
    11. sname → Always krbtgt/REALM.
    12. caddr → Same as in the TGT.
💡
There are actually two different enc-part fields in the AS-REP. One belongs to the TGT itself and is encrypted with the krbtgt account’s long-term key (so only the KDC can read it). The other is the EncASRepPart, which sits outside the TGT and is encrypted with the client’s long-term key (so only the client can read it).”
Visual representation of the request:
Here is how is looks like in Wireshark:

TGT:

The TGT is the ticket the client stores in memory. It now serves as proof of identity — essentially saying ‘I am authenticated as Alice in the LAB.LOCAL domain.’ Although the client can’t read its contents (The content of enc-part in ticket to be specific) — because it’s encrypted with the krbtgt account’s long-term key (the special account responsible for encrypting and signing all Ticket Granting Tickets) — the KDC can read it. Whenever the client needs to prove its identity to the KDC, it can simply present the TGT. The KDC decrypts it and, if valid, knows the client is authenticated. (You will see how this will come in handy later on)

💡
No system other than a Domain Controller should ever have access to the krbtgt account’s long-term key.

Session Key:

Alongside the TGT, the client also stores the session key in memory. This session key comes from the enc-part (EncASRepPart) of the AS-REP, which the client can decrypt using its own long-term key. The same session key is also embedded inside the TGT (ticket field) so the KDC has a copy as well. This key is what allows the client and the KDC to securely exchange and encrypt messages — and we’ll see its use in later sections.

The Authorization-data (PAC):

The Authorization-data field of the TGT contains the PAC (Privilege Attribute Certificate). The PAC holds all of the user’s authorization information, such as AD group memberships, user privileges, and policy flags. Services rely on this data to decide what the user is allowed or not allowed to access. (More on this later).


I’ve kept this post short and focused so it’s easier to digest. In the upcoming parts, we’ll dive into how service tickets are requested, how they’re used to access resources, and the different ways Kerberos can be attacked.

I’d really appreciate your feedback and thoughts — they’ll help me improve as I continue this series.

https://x.com/beacon_bytes