Kerberos Unlocked (Part 2): Service Tickets
In the previous post, we explored the AS-REQ and AS-REP messages, where the client obtained its Ticket Granting Ticket (TGT).
In this article, we’ll dive into the next step: Service Tickets. You’ll learn how they’re requested, how the KDC responds with a ticket , and how the client then uses that ticket to access actual services.
Why another ticket (isn’t the TGT enough?)
Since the client now has a Ticket Granting Ticket (TGT), it can prove its identity to the KDC. But that alone isn’t enough to access services like LDAP, CIFS, SMB, or others.
Why? Because the TGT is encrypted with the krbtgt account’s long-term key. A service like LDAP or SMB doesn’t have access to that key, so it can’t decrypt the TGT. In other words, the service can’t verify who the client is or what resources it should have access to.
To solve this, the client needs a different kind of ticket — one that the service can understand. This is where the Service Ticket comes in.
Here is how Service Tickets are requested (step by step below)

TGS-REQ
This is the request the client sends to the KDC to obtain a Service Ticket — the ticket that a service can actually read to verify who the client is and what resources it’s allowed to access.
This is how the request is structured (sent over the network to the KDC):
- padata → Carries the pre-authentication data and is used for authentication purposes here too, just like in the AS-REQ.
- PA-DATA pA-TGS-REQ → This field is one of the most important ones in this request it contains the TGT that the client received earlier and also an Authenticator. This proves to the KDC that the client is authenticated and owns the TGT.
- ap-req → This contains the ticket(TGT) and the Authenticator:
- ap-options → This field is a collection of bit flags that let the client tell the KDC or a service how it wants the authentication to be handled (its enough just to know that at this stage, we will explore later)
- ticket → This is the exact ticket(TGT) that the client received in the AS-REP. The client stored it in memory for this reason and it is needed here to prove the identity of the client to the KDC.
- authenticator → At its core, it contains the client’s identity(name and domain) and the current time, encrypted with the session key (the one obtained earlier in the AS-REP). This prevents ticket replay and proves the request is fresh. [EXPLAINED BELOW]
- Authenticator's Structure explained BELOW.
- ap-req → This contains the ticket(TGT) and the Authenticator:
- PA-DATA pA-TGS-REQ → This field is one of the most important ones in this request it contains the TGT that the client received earlier and also an Authenticator. This proves to the KDC that the client is authenticated and owns the TGT.
- PA-DATA: PA-PAC-OPTIONS → Used to tell the KDC how to handle the PAC (we will explore PAC later on). For example, it can request certain PAC contents (like claims info or branch awareness) or ask the KDC to format it in a particular way (its enough just to know that at this stage).
- req-body → This is the request body:
- cname / crealm (optional here) → The client’s name and realm (e.g.,
alice@LAB.LOCAL). Normally not needed since the KDC can pull this from the TGT, but sometimes present in special cases - sname / srealm → The name and realm(domain) of the service the client wants to access (e.g.,
LDAP,CIFS,SMB,HTTP). This is what the KDC will issue a Service Ticket for. - till → Requested expiration time (how long Alice wants the Service Ticket for?).
- rtime → Requested renew-until time (optional).
- nonce → Random number to bind reply to this request.
- etype → List of supported encryption types (AES256, AES128, RC4).
- enc-authorization-data → A TGT already carries your baseline authorization info (PAC which contains - group memberships, privileges). But sometimes, for a specific service request, the client (or middleware, such as when delegation is involved) needs to attach extra, temporary authorization info — or even override/suppress some of the PAC data already in the TGT. This field is where that extra or modified authorization data is carried. (Don't worry about this now, its not important at this stage and we will cover it later)
- cname / crealm (optional here) → The client’s name and realm (e.g.,
Visual representation of the request:

Here is how it looks like in Wireshark:

This is how an Authenticator is structured:
- authenticator-vno → Version number for the format of the
authenticator. - crealm → The client’s realm (the domain it belongs too).
- cname → the client's name.
- cksum → This is just a hash of any optional “extra data” carried with the request — data that isn’t part of the normal Kerberos fields. Examples include things like delegation info or channel bindings (not important at this stage).
- cusec → contains the microsecond part of the client's timestamp.
- ctime → This field contains the current time on the client's host.
- subkey → This field lets the client propose a new encryption key to use for securing messages. If the KDC (or, in the case of an AP-REQ, the service) accepts it, that
subkeywill replace the original session key for encrypting further communication.(not important at this stage) - seq-number → This field is ignored in a TGS-REQ, but it comes into play in an AP-REQ (when the client talks directly to a service). We’ll cover it in detail later.
- authorization-data → It is optional and will only appear when additional restrictions are to be placed on the use of a ticket. (this is also not important at this stage)
Visual representation of the Authenticator's structure:

Authenticator:
An Authenticator proves to the KDC that the request is really coming from the legitimate client who obtained the TGT earlier, and not from an attacker replaying an old ticket.
It does this by encrypting the client’s name, its realm (the domain it belongs to), and the current timestamp with the client’s session key (the one the client received in the AS-REP, inside the enc-part). When the KDC receives it, it decrypts the Authenticator using its own copy of that session key. It then verifies the timestamp (rejecting the request if it’s outside the allowed clock skew, typically ~5 minutes).
This mechanism confirms two things:
- Only the real client could have created the Authenticator, since only it knows the session key.
- The request is fresh, not a replay, because the timestamp checks out.
TGS-REP
The TGS-REP is the KDC’s response to a TGS-REQ. In it, the KDC issues the client a valid Service Ticket, which the client will use from now on to authenticate to a specific service. The structure of this response is very similar to AS-REP.
This is how the response is structured (sent over the network from the KDC to the client):
- crealm → Client’s realm (e.g.,
LAB.LOCAL, basically the domain.) - cname → Client’s principal name (e.g.,
alice). - ticket → The Service Ticket (this is the actual ticket which will be used by the client to prove its identity to the service from now on) [EXPLAINED BELOW]:
- realm → Realm of the issuing KDC (basically the domain of the KDC).
- sname → Service name, the service this ticket is for (eg.
LDAP,CIFSor others). - enc-part → Encrypted with the service account’s long-term key ( NOT WITH KRBTGT):
- 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).
- Key → Service Session Key. [EXPLAINED BELOW]
- CRealm → client realm (basically the domain)
- CName → client name
- Transited → field is only relevant in multi-realm (But its not important right now, will be explained later)
- authtime → When authentication happened.
- starttime (optional) → When ticket validity starts.
- endtime → When ticket expires.
- renew-till (optional) →Max renewable lifetime — the time until the ticket can be renewed (not important for us right now).
- 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.) - authorization-data → PAC in AD, with groups/SIDs/privileges [EXPLAINED BELOW]
- enc-part → The EncTGSRepPart, encrypted with the client’s session key(so the client can read it):
- key → Service Session Key (same as in the ticket). [EXPLAINED BELOW]
- last-req → Info about last successful logon (in AD).
- nonce →
nonceis just a random number the client included in its TFG-REQ (if you remember). The KDC copies it back into the TGS-REP. This way, the client knows the reply matches its request and isn’t a replay of some older message - key-expiration (optional) → It tells the client when its password is set to expire (rarely used).
- flags → Ticket flags (the same as in the
ticket). - authtime → Same as in the
ticket. - starttime (optional) → Same as in the
ticket. - endtime → Same as in the Ticket.
- renew-till (optional) → Same as in the
ticket. - srealm → Realm of the Service (basically the domain, the service is on eg.
ldap@lab.local). - sname → The Service's Name.
- caddr → Same as in the
ticket.
Visual representation of the request:

Here is how it looks like in Wireshark:

Service Ticket:
The structure of a Service Ticket is identical to that of a TGT. The difference is in who can read it. Instead of being encrypted with the krbtgt account’s long-term key, the enc-part(the one in the ticket) here is encrypted with the service account’s long-term key. This way, the service itself can decrypt the ticket and verify your identity.
Another difference is the key field, in a Service Ticket it holds the Service Session Key [EXPLAINED BELOW], which is different from the session key you had earlier with the KDC.
Service Session Key
This key serves the same purpose as the earlier session key, but with one important difference, it’s used for secure communication between the client and the service, rather than between the client and the KDC. The client can obtain this Service Session Key from the enc-part of the TGS-REP, which it can decrypt using its session key. The service also retrieves this Service Session Key from the Ticket itself, which it can decrypt using its own long-term key.
The Authorization-data (PAC):
The Authorization-data field of the Service Ticket 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 in upcoming post).
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 used to access resources, what a PAC is, 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.