# Overview of Kerberos Authentication

Kerberos is a stateless authentication protocol based on tickets. It effectively decouples a user's credentials from their requests to consumable resources, ensuring their password is not transmitted over the network; this allows the service to provide reliable authentication over open and insecure networks where communications could be intercepted. It is a Zero-knowledge proof protocol as the KDC (Key Distribution Center) does not record previous transactions; instead, the Kerberos Ticket Granting Service (TGS) relies on a valid Ticket Granting Ticket (TGT) and assumes that if a user has a valid TGT, they must have proven their identity.

This protocol is designed around the following core concepts:

1. The user's password must never travel over the network
2. The user's password must never be stored in any form on the client machine and it must be immediately discarded after use
3. The user's password should never be stored in an unencrypted manner
4. The user is asked to enter a password once per work session, allowing them to flawlessly access all the services they are authorized to interact with through **Single Sign-On**
5. Authentication management is centralized on the authentication server for the following reasons:
   1. When a user changes their password, the change has to happen on all the services and applications at the same time
   2. There is no redundancy of authentication information
   3. An administrator can disable the account of any user by acting in a single location
6. There has to be **mutual authentication**: not only the users have to prove their identity, the authentication server and applications must be able to do the same
7. Following the completion of authentication and authorization, the client and server must be able to establish an encrypted connection, if required

This is an overview of the events that occur when user interacts with a resource through the Kerberos protocol:

1. A user proves its identity and receives a TGT
2. The TGT will be provided when accessing a service, proving that the user provided some kind of identification prior to the interaction - if the ID of the ticket is valid the KDC will give the user a temporary ticket containing all the user's information: a Ticket Granting Service or TGS
3. The target resource will get the temporary ticket and grant the user access to its services

The Kerberos authentication process consists in 3 main components:

1. The user that wants to authenticate into a resource
2. The service provided by the resource the user wants to access
3. The Key Distribution Center

#### Realms

A realm indicates an authentication administrative domain with the intention of establishing boundaries within which an authentication server has the authority to authenticate a user, host and service. Authentication is possible even between a user and a service in different realms if there is a trust relationship between the two domains.

{% hint style="warning" %}
A user, host or service belongs to a realm **only** if it shares a secret, either a password or a key, with the authentication server of said realm.
{% endhint %}

#### Principals

A principal is the name user to refer to the entries in the authentication server database: each host, user and service in the realm have an associated principal. Principals are usually named and specified with the following format

```
Name[/Instance]@REALM
```

but the instance is optional and it's used to better qualify the type of user; for example, administrator users normally have the `admin` instance

```
otter/admin@DOMAIN.COM
```

This format is mostly used for SPNs, principals associated with services. In this case the principal has the following format

```
Service/Hostname@REALM
```

where Service is the name of the service (`host`, `cifs`, ...) and Hostname is the FQDN of the machine providing the requested service.

{% hint style="info" %}
There are principals which do not refer to users or services like for `krbtgt`: the principal is used in the form `krbtgt/REALM@REALM`.
{% endhint %}

#### Tickets

To satisfy the need to centralize authentication without sending a password over the network, Kerberos uses secret keys and tickets: as mentioned before, the user will first request a ticket from the KDC (TGT) and present it back to the KDC every time they need access to a resource - at that point the KDC will validate the TGT and return the user a TGS for that particular service; the TGS can now be used to access the resource and its services.

Both the TGT and TGS contain a lot of information about the user that requested them - to protect these details, whenever a TGT is created, the KDC encrypts it with its secret key and whenever a TGS is created it gets encrypted with the service secret key. This configuration doesn't allow the user cannot modify the information contained in the tickets but reserves access to the information to the service and KDC.

The main information contained in a ticket includes:

* The requesting user's principal
* The principal for the requested service (SPN)
* The IP address of the machine from which the ticket can be used: this is an optional field which can contain 0, 1 or multiple IP addresses
* The timestamp of the request's initialization
* The ticket's lifetime
* The temporary session key

#### Encryption

Kerberos itself only uses symmetrical key encryption as it uses the same key to both encrypt and decrypt the data but other projects like PKINIT can use different methods like a public key system.

Kerberos 5 is designed so that there is no way to predetermine the number or the type of encryption methodologies supported, contrary to Kerberos 4 which only supported DES encryption at 56 bit. In order for clients, applications and authentication servers that use to interact using Kerberos, they need to have at least one encryption protocol in common.

To solve interoperability issues and broaden the protocol's capabilities, Kerberos supports a range of encryption methods such as

* RC4-HMAC (NTLM)
* 3DES
* AES128
* AES256

Since these different algorithms use keys of different length, Kerberos uses the `string2key` hashing function: an irreversible function to convert a plaintext password to a key of the right format and length based on the encryption method used each time the user needs to authenticate.

Kerberos 5 also introduced the concept of password salts: a string that gets concatenated to the plaintext password before `string2key` is called on it. In this specific implementation, the user's [principal](#principals) is used as salt

```
key = string2key(password + user_principal)
```

This allows two users of the same realm to have the same password but still different keys and, following the same logic, two users from different realms to have the same username but different keys.

In summary, when two entities are trying to authenticate each other using Kerberos, they have to negotiate

* the encryption algorithm to use
* the type of `string2key` function to use
* whether the salt should be populated with the user's principal or be NULL (for Kerberos 4 retrocompatibility)

#### KDC - Key Distribution Center

The KDC is the authentication server for the Kerberos protocol. It is traditionally divided into three main parts:

1. The database
2. The Authentication Server (AS)
3. The Ticket Granting Server

The database contains all the user and service data required for authentication, the entries are indexed based on the principal and contain the following information (non-exhaustive list):

* The user's principal
* The encryption key and `kvno` or Key Version Number (a counter that increases each time a password or key is changed)
* The maximum lifetime of a ticket requested for said principals
* The maximum renewal lifespan
* The password's expiration date
* The expiration date of the principal

The DB is encrypted with a master key associated with the `krbtgt` SPN.

The Authentication Server or AS replies to the authentication requests from users; this is the first step of the authentication process, the AS-REQ and AS-REP, which a principal can use to get a valid TGT for the realm.

The Ticket Granting Service handles the second step of the authentication process, TGS-REQ and TGS-REP, by guaranteeing the identity of the user with the given TGT and granting a TGS for the requested service.

#### Renewable and Forwardable tickets

Among the attributes for an entry in the KDC, we mentioned a "maximum renewal lifespan": this field is used when a user is allowed for renewable tickets. A renewable ticket can be resubmitted to the KDC for renewal to extend its lifetime as long as it is not expired and it has not exceeded the maximum renewal time / lifespan.

Forwardable tickets are used in cases where a user has an active session on a host with a TGT and wants to use the same ticket to authenticate onto another host, thus keeping the same ticket. These tickets can be forwarded from one host to another without having the user supplying their password over and over again.

{% hint style="info" %}
If a user uses a forwardable ticket from host A to log onto host B, a new ticket will be created and loaded in the user's session on host B and that ticket will be forwardable as well. This means that the ticket from host B can be forwarded to host C and so on.
{% endhint %}

#### AS-REQ & AS-REP

AS-REQ is the name associated with the request sent by the user to the KDC whenever a TGT is requested. This phase is also known as _initial authentication request_. The request is sent in a unencrypted format that looks something like this

```
AS-REQ = user_principal, spn, ip_list, lifetime, authenticator
```

In most cases, the `spn` value will be set to `krbtgt/REALM@REALM` as that is the SPN associated with the Ticket Granting Server part of the KDC but it's also possible for a user to request a ticket for a specific service directly, skipping the TGS-REQ step entirely.

In the request, the user will also send an Authenticator: the timestamp of the request encrypted with the user's secret key which is known to both the user and KDC + the plaintext username of the user. The KDC will retrieve the username, look for the associated key in the database, and attempt to decrypt the authenticator. If it succeeds, it means that the user has used the same key as the one registered in its database, so they are authenticated. Otherwise, the authentication attempt fails.

This step, called **pre-authentication** and is not mandatory, but all accounts have it enabled by default. In case it gets disabled, the client no longer needs to send an authenticator and the KDC will send the TGT no matter what happens.

The response to a AS-REQ is called AS-REP; in the response the KDC does the following:

1. Creates a random session key which will be later used as the shared secret between the client and the Ticket Granting Server
2. Creates a TGT with the requested parameters without encryption (as we mentioned earlier, the SPN will often be `krbtgt/REALM@REALM` but it's possible to specify a different one)

```
TGT = user_principal, spn, ip_list, timestamp, lifetime, shared_session_key
```

3. Sends a reply containing the TGT created in step 2 encrypted using the secret key for the requested service and other parameters encrypted with the user's secret key

```
AS-REP = encrypt_with_user_key(
	user_principal, timestamp, lifetime, shared_session_key
) + encrypt_with_service_key (TGT)
```

_It's worth noting that the temporary session key created by the KDC is both sent over in the TGT encrypted with the KDC key and in the response encrypted with the user's key._

#### TGS-REQ & TGS-REP

Now that the user has a valid TGT, it can request a TGS with e TGS request (TGS-REQ). To perform the request the user will have to provide the service they wish to access as a SPN (Service Principal Name), the valid TGT and an authenticator.

```
authenticator = encrypt_with_shared_session_key(
	user_principal, timestamp
)

TGS-REQ = user_principal, lifetime, authenticator, encrypt_with_service_key(TGT)
```

The TGS-REP, the response to the user, requires the KDC to verity that the TGS request is valid by verifying that the requested SPN exists in the KDC's database, if it does the KDC can proceed to decrypt the TGT with `krbtgt`'s secret and check it's parameters to check whether

* the TGT is expired
* the user principal in the authenticator (from the TGS-REQ) matches the one specified in the TGT
* if the IP the user is sending the request from is included in the `ip_list` parameter (only if the parameter is not NULL)

{% hint style="info" %}
It is not the purpose of the KDC to check for access rights, so a user can request a TGS for a service they don't have access to. They will still be denied in the AP-REQ step.
{% endhint %}

If all goes well the KDC will send the TGS-REP with a new session key stored in the TGS to encrypt the future interactions between the user and the requested service, the Service Ticket or ST has the following structure

```
ST = user_principal, spn, ip_list, timestamp, lifetime, application_shared_session_key
```

and the TGS-REP will contain the following

```
TGS-REP = encrypt_with_shared_session_key(
	spn, timestamp, lifetime, application_shared_session_key
) + encrypt_with_service_key(ST)
```

#### AP-REQ & AP-REP

Now the user can present the service ticket to the application / service through an Application Request or AP-REQ. This step doesn't involve the KDC as the request changes based on the application and the ST given to the user contains everything that is needed for the service to verify the user's identity.

```
authenticator = encrypt_with_application_shared_session_key(
	user_principal, timestamp
)

AP-REQ = authenticator + encrypt_with_service_key(ST)
```

When the application receives the request, it will

* use the service's own key to decrypt the service ticket to get the key that it shares with the user and the rest of the information about the principal and requested service
* use the shared session key (decrypted from the ST) to decrypt the authenticator and verify the user's identity

As a last step, the client can then verify that this message is coming from the service and can start issuing service requests (_mutual authentication_).

#### PAC - Privilege Attribute Certificate

To understand the concept of [Silver Tickets](silver-tickets) and [Golden Tickets](golden-tickets), we must first understand how PAC works.

PAC is an object used for proper rights management in AD environments. Since the [KDC](#kdc-key-distribution-center) is the central database for cryptographic secrets and principal information, it has to have a way to relay said information to the services in the realm, allowing them to create security tokens for the users that authenticate into the services.

{% hint style="info" %}
MS uses the `authorization-data` field in tickets to store this information.
{% endhint %}

The PAC contains information about a principal such as the username, ID, group membership, security information, ...

```
AuthorizationData item
    ad-type: AD-Win2k-PAC (128)
        Type: Logon Info (1)
            PAC_LOGON_INFO: 01100800cccccccce001000000000000000002006a5c0818...
                Logon Time: Aug 17, 2018 16:25:05.992202600 Romance Daylight Time
                Logoff Time: Infinity (absolute time)
                PWD Last Set: Aug 16, 2018 14:13:10.300710200 Romance Daylight Time
                PWD Can Change: Aug 17, 2018 14:13:10.300710200 Romance Daylight Time
                PWD Must Change: Infinity (absolute time)
                Acct Name: pixis
                Full Name: pixis
                Logon Count: 7
                Bad PW Count: 2
                User RID: 1102
                Group RID: 513
                GROUP_MEMBERSHIP_ARRAY
                    Referent ID: 0x0002001c
                    Max Count: 2
                    GROUP_MEMBERSHIP:
                        Group RID: 1108
                        Attributes: 0x00000007
                            .... .... .... .... .... .... .... .1.. = Enabled: The enabled bit is SET
                            .... .... .... .... .... .... .... ..1. = Enabled By Default: The ENABLED_BY_DEFAULT bit is SET
                            .... .... .... .... .... .... .... ...1 = Mandatory: The MANDATORY bit is SET
                    GROUP_MEMBERSHIP:
                        Group RID: 513
                        Attributes: 0x00000007
                            .... .... .... .... .... .... .... .1.. = Enabled: The enabled bit is SET
                            .... .... .... .... .... .... .... ..1. = Enabled By Default: The ENABLED_BY_DEFAULT bit is SET
                            .... .... .... .... .... .... .... ...1 = Mandatory: The MANDATORY bit is SET
                User Flags: 0x00000020
                User Session Key: 00000000000000000000000000000000
                Server: DC2016
                Domain: DOMAIN
                SID pointer:
                    Domain SID: S-1-5-21-3643611871-2386784019-710848469  (Domain SID)
                User Account Control: 0x00000210
                    .... .... .... ...0 .... .... .... .... = Don't Require PreAuth: This account REQUIRES preauthentication
                    .... .... .... .... 0... .... .... .... = Use DES Key Only: This account does NOT have to use_des_key_only
                    .... .... .... .... .0.. .... .... .... = Not Delegated: This might have been delegated
                    .... .... .... .... ..0. .... .... .... = Trusted For Delegation: This account is NOT trusted_for_delegation
                    .... .... .... .... ...0 .... .... .... = SmartCard Required: This account does NOT require_smartcard to authenticate
                    .... .... .... .... .... 0... .... .... = Encrypted Text Password Allowed: This account does NOT allow encrypted_text_password
                    .... .... .... .... .... .0.. .... .... = Account Auto Locked: This account is NOT auto_locked
                    .... .... .... .... .... ..1. .... .... = Don't Expire Password: This account DOESN'T_EXPIRE_PASSWORDs
                    .... .... .... .... .... ...0 .... .... = Server Trust Account: This account is NOT a server_trust_account
                    .... .... .... .... .... .... 0... .... = Workstation Trust Account: This account is NOT a workstation_trust_account
                    .... .... .... .... .... .... .0.. .... = Interdomain trust Account: This account is NOT an interdomain_trust_account
                    .... .... .... .... .... .... ..0. .... = MNS Logon Account: This account is NOT a mns_logon_account
                    .... .... .... .... .... .... ...1 .... = Normal Account: This account is a NORMAL_ACCOUNT
                    .... .... .... .... .... .... .... 0... = Temp Duplicate Account: This account is NOT a temp_duplicate_account
                    .... .... .... .... .... .... .... .0.. = Password Not Required: This account REQUIRES a password
                    .... .... .... .... .... .... .... ..0. = Home Directory Required: This account does NOT require_home_directory
                    .... .... .... .... .... .... .... ...0 = Account Disabled: This account is NOT disabled
```

Depending on whether the PAC is found in a TGT or TGS, it is encrypted with `krbtgt`'s or the service's private key and not with the temporary session keys shared between the user and the AS / AP so the user cannot view or modify this information.
