What is Kerberos?
Kerberos is an authentication protocol that works on the basis of tickets that allows clients to connect to services over an insecure network and still allow clients to prove their identity in a secure manner.
The steps described below are a compilation of what I found when reading on Kerberos. Feel free to share your comments!
Key Distribution Center (KDC)
The authentication server in a Kerberos environment, based on its ticket distribution function for access to the services, is called Key Distribution Center or more briefly KDC. Since it resides entirely on a single physical server (it often coincides with a single process) it can be logically considered divided into three parts: Database, Authentication Server (AS) and Ticket Granting Server (TGS).
Database
The database is the container for entries associated with users and services. We refer to an entry by using the principal (i.e. the name of the entry) even if often the term principal is used as a synonym for entry. Each entry contains the following information:
- The principal to which the entry is associated;
- The encryption key and related kvno;
- The maximum validity duration for a ticket associated to the principal;
- The maximum time a ticket associated to the principal may be renewed (only Kerberos 5);
- The attributes or flags characterizing the behavior of the tickets;
- The password expiration date;
- The expiration date of the principal, after which no tickets will be issued.
In order to make it more difficult to steal the keys present in the database, the implementations encrypt the database using the master key, which is associated with the principal K/M@REALM. Even any database dumps, used as backups or for propagation from the KDC master towards the slave, are encrypted using this key, which it is necessary to know in order to reload them.
Authentication Server (AS)
The Authentication Server is the part of the KDC which replies to the initial authentication request from the client, when the user, not yet authenticated, must enter the password. In response to an authentication request, the AS issues a special ticket known as the Ticket Granting Ticket, or more briefly TGT, the principal associated with which is krbtgt/REALM@REALM. If the users are actually who they say they are (and we'll see later how they demonstrate this) they can use the TGT to obtain other service tickets, without having to re-enter their password.
Ticket Granting Server (TGS)
The Ticket Granting Server is the KDC component which distributes service tickets to clients with a valid TGT, guaranteeing the authenticity of the identity for obtaining the requested resource on the application servers. The TGS can be considered as an application server (given that to access it it is necessary to present the TGT) which provides the issuing of service tickets as a service. It is important not to confuse the abbreviations TGT and TGS: the first indicates a ticket and the second a service.
Auth Service: Authentication Server.
Tkt Granting service: Ticket Granting Service.
Centos's HTTP: The service the user wants to access.
Black Smile: User (user principle)
Black Spider Web: Service ID (http service principle)
Black key: User hashed password.
Green key: TGS Secret Key.
Red key: Client/TGS Session Key.
Blue key: Service secret key (HTTP)
Orange key:: Client/Server Session Key.
Black chest: Contain Session Key
Green chest: Ticket-Granting-Ticket.
Blue chest: Client-to-server Ticket.
Purple chest: Unencrypted service id and timestamp
Kerberos Packets:
Note unencrypted data in round brackets (), and encrypted data in curly brackets {}: ( x, y, z ) means that x, y, z are unencrypted; { x, y, z }K indicates that x, y, z are encrypted all together using the symmetrical key K.
AS_REQ is the initial user authentication request (i.e. made with kinit) This message is directed to the KDC component known as Authentication Server (AS);
AS_REQ = ( PrincipalClient , PrincipalService , IP_list , Lifetime )
AS_REP is the reply of the Authentication Server to the previous request. Basically it contains the TGT (encrypted using the TGS secret key) and the session key (encrypted using the secret key of the requesting user);
TGT = ( PrincipalClient , krbtgt/REALM@REALM , IP_list , Timestamp , Lifetime , SKTGS )
AS_REP = { PrincipalService , Timestamp , Lifetime , SKTGS }KUser { TGT }KTGS
TGS_REQ is the request from the client to the Ticket Granting Server (TGS) for a service ticket. This packet includes the TGT obtained from the previous message and an authenticator generated by the client and encrypted with the session key;
Authenticator = { PrincipalClient , Timestamp }SKTGS
TGS_REQ = ( PrincipalService , Lifetime , Authenticator) { TGT }KTGS
TGS_REP is the reply of the Ticket Granting Server to the previous request. Located inside is the requested service ticket (encrypted with the secret key of the service) and a service session key generated by TGS and encrypted using the previous session key generated by the AS;
TService = ( PrincipalClient , PrincipalService , IP_list , Timestamp , Lifetime , SKService )
TGS_REP = { PrincipalService , Timestamp , Lifetime , SKService }SKTGS { TService }KService
AP_REQ is the request that the client sends to an application server to access a service. The components are the service ticket obtained from TGS with the previous reply and an authenticator again generated by the client, but this time encrypted using the service session key (generated by TGS);
Authenticator = { PrincipalClient , Timestamp }SKService
AP_REQ = Authenticator { TService }KService
AP_REP is the reply that the application server gives to the client to prove it really is the server the client is expecting. This packet is not always requested. The client requests the server for it only when mutual authentication is necessary.
AP_REP = Authenticator { PrincipalService, Timestamp }SKService
How does Kerberos work?
These are the steps necessary for a client to obtain an authenticated and verified request to a service (for example a web HTTP service).
Step 1: Login
The user enters the username and password. In some cases you only have to enter the password in step 5. The client will then transform the password into a client secret key(KUser).
Step 2:
Initial authentication request, the client (kinit) asks the KDC (more specifically the AS) for a Ticket Granting Ticket.
The client sends a plaintext message to the authentication server. This message contains
- username;
- the name of the requested service (in this case this is the Ticket Granting Server – TGS);
- the network address;
- the requested lifetime of the TGT.
Note that no secret information (client secret key or password) is sent).
Step 3:
Server checks if the user exists
The server receives the message and will check if the username exists in the Key Distribution Center – KDC. Again this is not a credential check but only a check to verify that the user is defined. If all is OK the server proceeds.
Step 4:
Server sends TGT back to the client
The server generates a random key called the session key( SKTGS) that is to be used between the client and the TGS.
The authentication server then sends back two messages (i.e the chest boxes )to the client
- Message A is encrypted with the client secret key(KUser). The client secret key is not transferred but is retrieved from the password (more to speak the hash) found in the user database. This happens all on the server-side. The message contains
- TGS name;
- timestamp;
- lifetime;
- the TGS session key (the key generated at the beginning of this step( SKTGS)).
- Message B is the Ticket Granting Ticket, encrypted with the TGS secret key(KTGS), that contains
- your name;
- the TGS name;
- timestamp;
- your network address;
- lifetime;
- the TGS session key ( SKTGS)(same as in message A).
Step 5:
Enter your password
The client receives both messages and then requests the user for the password. In some cases, this is already done in the first step. The password is then converted (hash) to the client secret key(KUser). Note that this key was also generated on the server-side in the previous step.
Step 6:
Client obtains the TGS Session Key
The client now uses the client secret key(KUser) to decrypt message A. This gives the client the TGS Session key( SKTGS).
The client can not do anything with message B (the TGT) for the moment as this is encrypted with the TGS secret key(KTGS) (which is only available at the server-side). This encrypted TGT is stored locally in the credential cache.
Step 7:
Client requests server to access a service
The client now prepares two messages (i.e the chest boxes )to be sent to the server
- Message C( Wireshark trace has a more elaborate explanation) is an unencrypted message that contains
- the service that the client wants to access;
- the lifetime;
- message B or the TGT (this TGT itself is encrypted and included in the unencrypted message send to the server).
- Message D is a so-called Authenticator encrypted with the TGS session key( SKTGS) and contains
Step 8:
Server verifies if service exist
The server first verifies if the requested service exists in the KDC. If this is the case, it will proceed.
Step 9:
Server verifies request
The server now extracts the content of message B (the TGT) from message C and then decrypts that message B (the TGT) with its TGS secret key(KTGS). This will give the server the TGS session key( SKTGS). This is a shared key between the client and the server.
With this TGS session key( SKTGS), the server is now able to also decrypt the message D.
The server now has your name and timestamp from message D and a name and timestamp from message B. The server will then
- Compare both name and timestamp in both values;
- Check if the TGT is expired (the lifetime field in the TGT);
- Check that the Authenticator is not in the cache (to prevent replay).
If all checks turn out OK, the server continues.
Step 10:
Server generates a service session key(SKService)
The server generates a random service session key(SKService). It will then send two messages to the client.
- Message E: the service ticket that is encrypted with the service secret key(KService) and contains
- your name;
- the service name;
- timestamp;
- your network address;
- lifetime;
- the service session key(SKService).
- Message F: encrypted with the TGS session key( SKTGS) containing
- service name;
- timestamp;
- lifetime;
- service session key(SKService).
Step 11:
Client receives a service session key
Because the client has the TGS session key( SKTGS) cached from previous steps it can now decrypt message F to obtain the service session key(SKService). It is however not possible to decrypt the service ticket (message E) because that one is encrypted with the service secret key(KService).
Step 12:
Client contacts service (HTTP server)
Now it’s time for the client to contact the service. Again two messages are send
- Message G: a new authenticator message encrypted with the service session key(SKService) that contains
- Message E: the previously received message E, that is still encrypted with the service secret key(KService)
Step 13:
Service receives the request
The service then decrypts the message E with its service secret key(KService) to obtain the service session key(SKService)
The service will then use that newly obtain service session key(SKService) to decrypt the authenticator message G.
Step 14:
Service verifies the request
Similar to step 9, the service then does some verification
- Compare the user name from the authenticator (message G) to the one in the ticket (comparing message E);
- Compare the timestamp in message G with the timestamp in the ticket (message E);
- Check if the lifetime (message E) is expired;
- Check that the authenticator (message G) is not already in the cache, to prevent replay attacks.
If all checks turn out OK, the service continues.
Step 15:
Service confirms identity to the client
The service will then confirm its identity to the client
- Message I: an authenticator message encrypted with the service session key(SKService) that contains
- the id of the service;
- timestamp.
Step 16:
Client receives confirmation
The client then receives the authenticator message I and decrypts its with the cache service session key(SKService) (obtained in step 11). This allows the client to know the id of the service and if the timestamp is valid. If everything is OK the client can proceed.
Step 17:
Client communicates with the service
The authentication and verification are finished. The client can now talk to the service. Note that this only involves the authentication and verification of a service. This process will not decide if the client is actually allowed to do the requested service. This is something that is decided by the ACLs within the server that provides the service. This is not part of Kerberos.
Kerberos packets analysis
Assumptions
- As always, we’ll start with a bunch of assumptions to make sure we are in the same chapter (mostly given up trying to be on the same page).
- There is a lot going on with Kerberos in Windows Domains. Some of it involves proprietary details beyond the scope of the Kerberos 5 protocol that we do not care about in this post. Here we are only interested in the pure-Kerberos details.
- I skip most of the details of what each actor is doing and instead focus on the messages exchanged by the protocol here.
- The network traces captured for this post were generated with Windows Pro 10 running on AWS.
- No effort was made to obfuscate any of the information in these screenshots. All traffic was generated in a test environment that will no longer exist by the time this post is published.
Structure of a Kerberos Ticket
A Kerberos Ticket includes the following information:
- Unencrypted Part:
- Version number of ticket format.
- Service realm
- Service principal
- Encrypted Part:
- Ticket flags*
- Session key
- Client realm
- Client principal (username)
- List of Kerberos realms that took part in authenticating the user to whom this ticket was issued.
- Timestamp and other meta data about last initial request.
- Time client was authenticated.
- Validity period start time (optional).
- Validity period end time.
- Ticket Granting Server (TGS) Name/ID
- Timestamp
- Client (workstation) Address
- Lifetime
- Authorization-data — used to pass authorization data from the principal on whose behalf a ticket was issued to the application service ( see Section 5.3 of RFC4120 for more information)
*The following flags can be used in a ticket:
- reserved(0)
- forwardable(1)
- forwarded(2)
- proxiable(3)
- proxy(4)
- may-postdate(5)
- postdated(6)
- invalid(7)
- renewable(8)
- initial(9)
- pre-authent(10)
- hw-authent(11)
- transited-policy-checked(12)
- ok-as-delegate(13)
We will see two tickets in this example: Ticket Granting Ticket (TGT) and Service Ticket.
Structure of a Kerberos Authenticator
A Kerberos Authenticator contains the following information (all encrypted):
- Timestamp
- client ID
- application-specific checksum
- initial sequence number KRB_SAFE or KRB_PRIV messages)
- session sub-key (used in negotiations for a session key unique to this particular session)
Authenticators must not be re-used. A server that encounters a replayed authenticator must reject the message.
We will see one authenticator in this request: the authenticator sent with the TGT-REQ message.
Domain User Sign-On
The following network packets shows the initial TCP connection between the domain-joined Windows and the domain controller when the user “OFFICE\UserNameX” tried to login. Note, the domain in question is called OFFICE(its DNS name is OFFICE.COMPANY.COM); the domain user we are tracing the sign-in of is called UserNameX”.
Authentication Service Exchange
The first three packets are the typical SYN-SYNACK-ACK handshake that happens for any TCP connection.
The forth packet that is sent from the windows Client to the domain controller (KDC/Authentication Service) is the AS-REQ message (which is a type of KRB_KDC_REQ message). The AS-REQ message looks like the following:
Kerberos
Record Mark: 213 bytes
0 ... .... .... .... .... .... .... .... = Reserved: Not set
. 000 0000 0000 0000 0000 0000 1101 0101 = Record Length: 213
as-req
pvno: 5
msg-type: krb-as-req ( 10 )
padata: 1 item
PA-DATA PA-PAC-REQUEST
padata-type: kRB5-PADATA-PA-PAC-REQUEST ( 128 )
padata-value: 3005a0030101ff
include-pac: True
req-body
Padding: 0
kdc-options: 40810010 (forwardable, renewable, canonicalize, renewable-ok)
0 ... .... = reserved: False
. 1 .. .... = forwardable: True
.. 0 . .... = forwarded: False
... 0 .... = proxiable: False
.... 0 ... = proxy: False
.... . 0 .. = allow-postdate: False
.... .. 0 . = postdated: False
.... ... 0 = unused7: False
1 ... .... = renewable: True
. 0 .. .... = unused9: False
.. 0 . .... = unused10: False
... 0 .... = opt-hardware-auth: False
.... 0 ... = unused12: False
.... . 0 .. = unused13: False
.... .. 0 . = constrained-delegation: False
.... ... 1 = canonicalize: True
0 ... .... = request-anonymous: False
. 0 .. .... = unused17: False
.. 0 . .... = unused18: False
... 0 .... = unused19: False
.... 0 ... = unused20: False
.... . 0 .. = unused21: False
.... .. 0 . = unused22: False
.... ... 0 = unused23: False
0 ... .... = unused24: False
. 0 .. .... = unused25: False
.. 0 . .... = disable-transited-check: False
... 1 .... = renewable-ok: True
.... 0 ... = enc-tkt-in-skey: False
.... . 0 .. = unused29: False
.... .. 0 . = renew: False
.... ... 0 = validate: False
cname
name-type: kRB5-NT-PRINCIPAL ( 1 )
cname-string: 1 item
CNameString: UserNameX
realm: OFFICE
sname
name-type: kRB5-NT-SRV-INST ( 2 )
sname-string: 2 items
SNameString: krbtgt
SNameString: OFFICE
till: 2037 - 09 - 13 02 : 48 : 05 (UTC)
rtime: 2037 - 09 - 13 02 : 48 : 05 (UTC)
nonce: 919532771
etype: 6 items
ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
ENCTYPE: eTYPE-AES128-CTS-HMAC-SHA1- 96 ( 17 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5 ( 23 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5- 56 ( 24 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-OLD-EXP (- 135 )
ENCTYPE: eTYPE-DES-CBC-MD5 ( 3 )
addresses: 1 item COMP-LAP- 470 < 20 >
HostAddress COMP-LAP- 470 < 20 >
addr-type: nETBIOS ( 20 )
NetBIOS Name: COMP-LAP- 470 < 20 > (Server service)
|
This is AS_REQ (in my original protocol description). You can see the following fields in the trace above:
- pvno — Kerberos protocol version (5).
- msg-type — Application class tag number (10)
- padata — Pre-Authentication data that contains a PA-PAC-REQUEST structure. This is mentioned briefly in RFC4120, but this goes into much more detail
- kdc-options — flags requested for the resulting ticket (forwardable, renewable, canonicalize, renewable-ok).
- cname — contains the user name being authenticated
- realm — contains the Kerberos realm (a.k.a. Windows domain name)
- sname — the service name being requested (in this case, it is again the windows domain name)
- till — The requested expiration time of the ticket being requested.
- rtime — If a renewable ticket was requested, this field contains the desired absolute expiration time for the ticket
- nonce — the message nonce
- etype — Requested encryption types
- addresses — the client IP address
The domain controller (authentication service) wants pre-authentication data to be provided. So, it returns the following Kerberos Error:
Kerberos
Record Mark: 186 bytes
0 ... .... .... .... .... .... .... .... = Reserved: Not set
. 000 0000 0000 0000 0000 0000 1011 1010 = Record Length: 186
krb-error
pvno: 5
msg-type: krb-error ( 30 )
stime: 2019 - 08 - 19 00 : 36 : 59 (UTC)
susec: 405988
error-code: eRR-PREAUTH-REQUIRED ( 25 )
realm: OFFICE
sname
name-type: kRB5-NT-SRV-INST ( 2 )
sname-string: 2 items
SNameString: krbtgt
SNameString: OFFICE
e-data: 305e303ba103020113a234043230303027a003020112a120…
PA-DATA PA-ENCTYPE-INFO2
padata-type: kRB5-PADATA-ETYPE-INFO2 ( 19 )
padata-value: 30303027a003020112a1201b1e4f46464943452e53594d42…
ETYPE-INFO2-ENTRY
ETYPE-INFO2-ENTRY
PA-DATA PA-ENC-TIMESTAMP
padata-type: kRB5-PADATA-ENC-TIMESTAMP ( 2 )
padata-value: <MISSING>
PA-DATA PA-DASS
padata-type: kRB5-PADATA-PK-AS-REQ ( 16 )
padata-value: <MISSING>
PA-DATA PA-PK-AS-REP
padata-type: kRB5-PADATA-PK-AS-REP- 19 ( 15 )
padata-value: <MISSING>
|
Kerberos error messages are defined in RFC 4120, Section 5.9. The fields contained in this message are:
- pvno — Kerberos protocol version number (5)
- msg-type — Application class tag number(30)
- stime — Current time on the server at the time this message was generated.
- susec — This field contains the microsecond part of the server’s timestamp.
- error-code — The error that occurred (pre-authentication data required, in this case)
- realm — the realm in which this error occured.
- sname — the service identifier (krbtgt@OFFICE, in this case, the Ticket Granting Ticket)
- e-data — additional data about the error for use by the application to help it recover from or handle the error.
At this point, the TCP connection is closed.
You can see the FIN, ACK, and RST (reset) packets that are exchanged as part of the standard connection termination.
Using the user’s secret key derived from the windows password, a current timestamp is encrypted by the client (windows workstation or server) and used to populate the Pre-Authentication data with a KRB5-PADATA-ENC-TIMESTAMP message in the request below.
A new connection is established. I’m going to skip the connection stand-up and tear-down details this time around.
A new AS-REQ message is sent to the KDC Authentication Service:
Kerberos
Record Mark: 293 bytes
0 ... .... .... .... .... .... .... .... = Reserved: Not set
. 000 0000 0000 0000 0000 0001 0010 0101 = Record Length: 293
as-req
pvno: 5
msg-type: krb-as-req ( 10 )
padata: 2 items
PA-DATA PA-ENC-TIMESTAMP
padata-type: kRB5-PADATA-ENC-TIMESTAMP ( 2 )
padata-value: 3041a003020112a23a0438e86fb8cffb6dc79eb30461707b…
etype: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
cipher: e86fb8cffb6dc79eb30461707b085fabcc1142288b6b57f9…
PA-DATA PA-PAC-REQUEST
padata-type: kRB5-PADATA-PA-PAC-REQUEST ( 128 )
padata-value: 3005a0030101ff
include-pac: True
req-body
Padding: 0
kdc-options: 40810010 (forwardable, renewable, canonicalize, renewable-ok)
cname
realm: OFFICE
sname
name-type: kRB5-NT-SRV-INST ( 2 )
sname-string: 2 items
SNameString: krbtgt
SNameString: OFFICE
till: 2037 - 09 - 13 02 : 48 : 05 (UTC)
rtime: 2037 - 09 - 13 02 : 48 : 05 (UTC)
nonce: 892433749
etype: 6 items
ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
ENCTYPE: eTYPE-AES128-CTS-HMAC-SHA1- 96 ( 17 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5 ( 23 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5- 56 ( 24 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-OLD-EXP (- 135 )
ENCTYPE: eTYPE-DES-CBC-MD5 ( 3 )
addresses: 1 item COMP-LAP- 470 < 20 >
HostAddress COMP-LAP- 470 < 20 >
addr-type: nETBIOS ( 20 )
NetBIOS Name: COMP-LAP- 470 < 20 > (Server service)
|
This is essentially the exact same message that came through the first time, but now the pre-authentication data is populated.
After processing the request message, the authentication service returns the KRB_AS_REP to the client . It looks something like the following:
Kerberos
Record Mark: 1953 bytes
0 ... .... .... .... .... .... .... .... = Reserved: Not set
. 000 0000 0000 0000 0000 0111 1010 0001 = Record Length: 1953
as-rep
pvno: 5
msg-type: krb-as-rep ( 11 )
padata: 1 item
PA-DATA PA-ENCTYPE-INFO2
padata-type: kRB5-PADATA-ETYPE-INFO2 ( 19 )
padata-value: 30293027a003020112a1201b1e4f46464943452e53594d42…
ETYPE-INFO2-ENTRY
crealm: OFFICE.COMPANY.COM
cname
name-type: kRB5-NT-PRINCIPAL ( 1 )
cname-string: 1 item
CNameString: UserNameX
ticket
tkt-vno: 5
realm: OFFICE.COMPANY.COM
sname
name-type: kRB5-NT-SRV-INST ( 2 )
sname-string: 2 items
SNameString: krbtgt
SNameString: OFFICE.COMPANY.COM
enc-part
etype: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
kvno: 2
cipher: 090fab39d47e27189016766e793df4e5c0b7962d7117cc06…
enc-part
etype: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
kvno: 8
cipher: be22cff8845c2050c3a39c9f83868b15bbb9b023a6bbc58d…
|
The following fields are present in the KRB_AS_REP message:
- pvno — The Kerberos protocol version number (5)
- msg-type — Application class tag number (10)
- padata — pre-authentication data (in this case, from RFC4120, Section 5.2.7.5, it will “provide information to the client about which key salt to use for the string-to-key to be used by the client to obtain the key for decrypting the encrypted part the AS-REP.”)
- crealm — The Kerberos realm (RCBJ.NET in this case)
- cname — The client/username (UserNameXin this case).
- ticket — The Kerberos Ticket Granting Ticket for this session.
- ticket->tkt-vno —The ticket format version number (5).
- ticket->realm — The realm this ticket is issued for ( OFFICE.COMPANY.COM in this case).
- ticket->sname — The service name this ticket belongs to, the KDC Ticket Graning Service. (krbtgt@OFFICE.COMPANY.COM)
- ticket->enc-part — The part of the ticket encrypted with the TGS’s secret key.
- enc-part — the client/TGS session key (encrypted with the user’s secret key)
These data fields represent Message A (the enc-part field that is encrypted with the user’s secret, derived from the password) and Message B (the ticket field that contains the TGT). There is also some meta data included in the KRB_AS_REP message.
So, at this point, the client has a session key that is decrypted using the user’s secret key and the TGT (which contains the same session key, among other things, encrypted with the TGS’s secret key). In the next step, the TGS will have access to the client/TGS session key as well.
Token Service Exchange
Next, the client (workstation) establishes a new socket connection and sends the TGS-REQ message, which looks something similar to the following:
Kerberos
Record Mark: 1859 bytes
0 ... .... .... .... .... .... .... .... = Reserved: Not set
. 000 0000 0000 0000 0000 0111 0100 0011 = Record Length: 1859
tgs-req
pvno: 5
msg-type: krb-tgs-req ( 12 )
padata: 2 items
PA-DATA PA-TGS-REQ
padata-type: kRB5-PADATA-TGS-REQ ( 1 )
padata-value: 6e82066730820663a003020105a10302010ea20703050000…
ap-req
pvno: 5
msg-type: krb-ap-req ( 14 )
Padding: 0
ap-options: 00000000
0 ... .... = reserved: False
. 0 .. .... = use-session-key: False
.. 0 . .... = mutual-required: False
ticket
tkt-vno: 5
realm: OFFICE.COMPANY.COM
sname
name-type: kRB5-NT-SRV-INST ( 2 )
sname-string: 2 items
SNameString: krbtgt
SNameString: OFFICE.COMPANY.COM
enc-part
etype: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
kvno: 2
cipher: 090fab39d47e27189016766e793df4e5c0b7962d7117cc06…
authenticator
PA-DATA Unknown: 167
padata-type: Unknown ( 167 )
padata-value: 3009a00703050040000000
req-body
Padding: 0
kdc-options: 40810000 (forwardable, renewable, canonicalize)
0 ... .... = reserved: False
. 1 .. .... = forwardable: True
.. 0 . .... = forwarded: False
... 0 .... = proxiable: False
.... 0 ... = proxy: False
.... . 0 .. = allow-postdate: False
.... .. 0 . = postdated: False
.... ... 0 = unused7: False
1 ... .... = renewable: True
. 0 .. .... = unused9: False
.. 0 . .... = unused10: False
... 0 .... = opt-hardware-auth: False
.... 0 ... = unused12: False
.... . 0 .. = unused13: False
.... .. 0 . = constrained-delegation: False
.... ... 1 = canonicalize: True
0 ... .... = request-anonymous: False
. 0 .. .... = unused17: False
.. 0 . .... = unused18: False
... 0 .... = unused19: False
.... 0 ... = unused20: False
.... . 0 .. = unused21: False
.... .. 0 . = unused22: False
.... ... 0 = unused23: False
0 ... .... = unused24: False
. 0 .. .... = unused25: False
.. 0 . .... = disable-transited-check: False
... 0 .... = renewable-ok: False
.... 0 ... = enc-tkt-in-skey: False
.... . 0 .. = unused29: False
.... .. 0 . = renew: False
.... ... 0 = validate: False
realm: OFFICE.COMPANY.COM
sname
name-type: kRB5-NT-SRV-HST ( 3 )
sname-string: 2 items
SNameString: host
SNameString: comp-lap- 470 .office.company.com
till: 2037 - 09 - 13 02 : 48 : 05 (UTC)
nonce: 891991996
etype: 5 items
ENCTYPE: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
ENCTYPE: eTYPE-AES128-CTS-HMAC-SHA1- 96 ( 17 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5 ( 23 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-MD5- 56 ( 24 )
ENCTYPE: eTYPE-ARCFOUR-HMAC-OLD-EXP (- 135 )
|
The TGT-REQ message’s structure is similar the AS-REQ message we looked at earlier, which makes sense given that both of these messages have a common KRB_KDC_REQ definition (RFC 4120, Section 5.4.1). However, many of these fields are optional and missing here. RFC4120 states:
The TGT-REQ request contains:
- pvno: The Kerberos protocol version (5).
- msg-type: Application class tag number (12).
- pa-data: Pre-Authentication data field that contains an authentication header (see below).
- req-body: The request body.
In the sample message above, we can see the Pre-Authentication data field is populated with an authentication header that is of type PA-TGS-REQ (see RFC 4120, Section 5.2.7.1) data structure — it contains the TGT and authenticator for this step and is of type AP-REQ. The PA-TGS-REQ contains the following fields:
- pvno —Kerberos protocol version number
- msg-type — Application class tag number (14)
- padata — The Pre-Authentication data.
- ticket — The ticket structure (TGT from Message 2)
- ticket->tkt-vno — The ticket format version number.
- ticket->realm —The realm the ticket was issued for.
- ticket->sname — The service this ticket was issued for (krbtgt@OFFICE.COMPANY.COM)
- ticket->enc-part —Encrypted part of the ticket.
- authenticator —Authenticator, encrypted using the Client/TGS Session Key
This includes Message C (the TGT from Message B and the ID of the requested service, krbtgt@OFFICE.COMPANY.COM for our Windows Domain login) and Message D (Authenticator, encrypted using the Client/TGS Session Key) from our earlier description.
At this point, the TGS uses its secret key to decrypt the TGT. Then, it can retrieve the Client/TGS session key from the decrypted ticket. Then, it can use the session key to decrypt the authenticator (enc-part field). The TGS can now compare the username in the authenticator to the name in the TGT. If the two names match, TGS proceeds as described below; otherwise, an error will be returned.
The TGS-REQ request body contains the following fields:
- flags: Flags describing what type of Service Ticket to return (in this case, the ticket should be renewable, forwardable, and canonicalized.
- realm: The realm the ticket is issued for (OFFICE.COMPANY.COM, in this case).
- sname: The service that the Service Ticket should be issued for (here, comp-lap-470.office.company.com).
- till: Requested expiration time of ticket to be issued for this request.
- nonce: nonce for this request.
- etype: The desired encryption algorithm(s) to be used in the response.
The KDC Ticket Granting Service responds back with a TGS-REP message:
TGS-REP
Kerberos
Record Mark: 1885 bytes
0 ... .... .... .... .... .... .... .... = Reserved: Not set
. 000 0000 0000 0000 0000 0111 0101 1101 = Record Length: 1885
tgs-rep
pvno: 5
msg-type: krb-tgs-rep ( 13 )
crealm: OFFICE.COMPANY.COM
cname
name-type: kRB5-NT-PRINCIPAL ( 1 )
cname-string: 1 item
CNameString: UserNameX
ticket
tkt-vno: 5
realm: OFFICE.COMPANY.COM
sname
name-type: kRB5-NT-SRV-HST ( 3 )
sname-string: 2 items
SNameString: host
SNameString: comp-lap- 470 .office.company.com
enc-part
etype: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
kvno: 17
cipher: d37396fa5a43f0a89b3ca77a368d2e2d223b8162f60f95a0…
enc-part
etype: eTYPE-AES256-CTS-HMAC-SHA1- 96 ( 18 )
cipher: 74d2037c10fc5399211a495dfdcfc8aea0a4bc793d3e0e6d…
|
The fields included are:
- pvno — The Kerberos protocol version number (5).
- msg-type — Application class tag number (13).
- crealm — The realm name (once again, the Windows Domain name,OFFICE.COMPANY.COM).
- cname — The username.
- ticket —The ticket structure (Client-to-server ticket, encrypted using the service’s secret key. The ticket is called a Service Ticket. In this example, the service is the local workstation’s login service.
- ticket->tkt-vno — The ticket format version number.
- ticket->realm — The realm this ticket was issued for.
- ticket->sname — Service name this ticket was issued for (comp-lap-470.office.company.com).
- ticket->enc-part —Encrypted part of Client-to-Server (or Service) ticket.
- enc-part — Client/Server (or Service) Session Key encrypted with the Client-TGS Session Key.
This includes Message E (client-to-server or Service Ticket, encrypted using the service’s secret key, or in this case, workstation’s computer account’s secret key) and Message F (client-server session key, encrypted with the client-TGS session key). To further clarify what secret key is being used to decrypt the Service Ticket in Message E, recall that every workstation and server registered in the Windows Domain has a computer account defined that has a secret key (password) associated with it.
Upon receipt, the client can decrypt the client-server session key that it needs for the next step and the encrypted client-to-server ticket is available for submission to the desired service. Although, the Service Server named in the client-to-server ticket we have just obtained is the local server that we are logging into, which makes this particular example a bit odd in terms of the standard Kerberos use case — there is no remote server component that is being accessed. At least, not yet. Given enough time, the typical Windows user will do something that involves accessing a remote service (network file system, printer, email, etc).
Client/Server Exchange (or Lack Thereof)
During Windows login for domain users, the final exchange (KRB-AP-REQ and KRB-AP-REP messages) does not actually occur because the “service” we are hitting is the local workstation (or Windows server) login service, which is the same thing that initiated the Kerberos authentication sequence to start with. So, from the standpoint of having an example that demonstrates the Kerberos Protocol, this isn’t the ideal example, but it is so common that it still seemed the best option for a first example in this post.
The first time I ever ran Wireshark to capture the examples used in this post, I spent about ten minutes looking for the third part, that was quite obviously missing. A few minutes of googling explained what I described above.