Kerberos
Introduction
The Kerberos protocol defines how clients interact with a network authentication service.
On the other hand, authorization is accomplished using Privilege Attribute Certificate (PAC) data.
Kerberos Tickets
Clients obtain tickets from the Kerberos Key Distribution Center (KDC), which uses Active Directory as its account database, and they present these tickets to servers, as network credentials.
Ticket-Granting Ticket
Originally, The client used his master key which is derived from the user password to decrypt session keys received from KDC.
To avoid users to enter their passwords frequently, the protocol introduces the usage of the ticket.
When a user logs on, the client requests a ticket for the KDC just as it would request a ticket for any other service. The KDC responds by creating a logon session key and a ticket for the KDC's full ticket-granting service.
GSS API
Applications that use AP exchange messages directly are typically called "kerberized" applications. Most applications use the Generic Security Service Application Program Interface (GSS-API) and can even be wrapped by higher-level abstractions such as Simple Authentication and Security Layer (SASL) [RFC2222].
When an application wants to use Kerberos-based authentication, it uses either the higher-level SSPI API to invoke Kerberos directly; or it uses SPNEGO [MS-SPNG], which in turn invokes Kerberos.
MS-KILE Extension
Microsoft extend the Keberos authorization data to provide the server with additional information such as:
Group membership
Claims
Interactive logon information
Integrity levels
Realm
A collection of key distribution centers (KDCs) with a common set of principals, as described in [RFC4120] section 1.2.
An administrative boundary that uses one set of authentication servers to manage and deploy a single set of unique identifiers.
A realm is a unique logon space.
Authentication Service
Kerberos V5 is composed of three exchanges:
The Authentication Service (AS) exchange
The Ticket-Granting Service (TGS) exchange
The Client/Server Authentication Protocol (AP) exchange

The AS exchange and TGS exchange are transported by Kerberos implementations. The AP exchange is passive and relies on an upper-layer application protocol to carry the AP exchange messages.
Format
The ticket formats are defined in [RFC4120] section 5.3.
The exchange message format is defined in [RFC4120] section 5.4 using the ASN.1.
Also, we can consume the code in Impakct packages to understand the protocol:
from pyasn1.type import tag, namedtype, univ, constraint, char, useful
...
class KDC_REQ(univ.Sequence):
componentType = namedtype.NamedTypes(
_vno_component(1),
_msg_type_component(2, (constants.ApplicationTagNumbers.AS_REQ.value,
constants.ApplicationTagNumbers.TGS_REQ.value)),
_sequence_optional_component('padata', 3,
univ.SequenceOf(componentType=PA_DATA())),
_sequence_component('req-body', 4, KDC_REQ_BODY())
)
class AS_REQ(KDC_REQ):
tagSet = _application_tag(constants.ApplicationTagNumbers.AS_REQ.value)
class TGS_REQ(KDC_REQ):
tagSet = _application_tag(constants.ApplicationTagNumbers.TGS_REQ.value)Both KRB_TGS_REQ and KRB_AS_REQ have a common structure as the KRB_KDC_REQ message.
On the other hand, the KRB_KDC_REP message format is used for the reply from the KDC for either an initial (AS) request or a subsequent (TGS) request.
AS Exchange
The client presents its principal name and shall present pre-authentication information ([RFC4120] sections 5.2.7 and 7.5.2) in the KRB_AS_REQ message to request a ticket-granting ticket (TGT) from the KDC ([RFC4120] section 5.3).
Pre-authentication
By tracing the packets seen in the Kerberos process, we can see that the first KRB_AS_REQ message contains PA-PAC-REQUEST as the padata, then a second KRB_AS_REQ is sent with pa-enc-timestamp padata if the Kerberos client receives an error message when pre-authentication is required.
Refer to the code in the Kerberos implementation of function getKerberosTGT in Impacket, we see the Kerberos client is expecting a Kerberos error message:
# This should be the PREAUTH_FAILED packet or the actual TGT if the target principal has the
# 'Do not require Kerberos preauthentication' set
preAuth = True
try:
asRep = decoder.decode(r, asn1Spec = KRB_ERROR())[0]
except:
# Most of the times we shouldn't be here, is this a TGT?
asRep = decoder.decode(r, asn1Spec=AS_REP())[0]
# Yes
preAuth = FalseThen it computes the encrypted timestamp using the client's key to prepare the padata to be sent in the second KRB_AS_REQ to demonstrate its knowledge of the user's key.
# Let's build the timestamp
timeStamp = PA_ENC_TS_ENC()
now = datetime.datetime.utcnow()
timeStamp['patimestamp'] = KerberosTime.to_asn1(now)
timeStamp['pausec'] = now.microsecond
# Encrypt the shyte
encodedTimeStamp = encoder.encode(timeStamp)
# Key Usage 1
# AS-REQ PA-ENC-TIMESTAMP padata timestamp, encrypted with the
# client key (Section 5.2.7.2)
encriptedTimeStamp = cipher.encrypt(key, 1, encodedTimeStamp, None)The KDC returns a TGT and a session key the client can use to encrypt and authenticate communication with the KDC for ticket-granting service (TGS) requests in the TGS exchange, without reusing the persistent key.
Ticket-Granting Ticket
The ticket, with the logon session key embedded in it, is encrypted with the KDC's master key.
Session Key
The logon session key is contained in an encrypted part, encrypted with the user's master key derived from the user's logon password, in the KRB_AS_REP message.
Refer to the code implementation in Impacket, we can see that the Kerberos client can decrypt the encrypted part to get the logon session key for further usage in the TGS exchange:
# So, we have the TGT, now extract the new session key and finish
cipherText = asRep['enc-part']['cipher']
...
# Key Usage 3
# AS-REP encrypted part (includes TGS session key or
# application session key), encrypted with the client key
# (Section 5.4.2)
try:
plainText = cipher.decrypt(key, 3, cipherText)
except InvalidChecksum as e:
# probably bad password if preauth is disabled
if preAuth is False:
error_msg = "failed to decrypt session key: %s" % str(e)
raise SessionKeyDecryptionError(error_msg, asRep, cipher, key, cipherText)
raise
encASRepPart = decoder.decode(plainText, asn1Spec = EncASRepPart())[0]
# Get the session key and the ticket
cipher = _enctype_table[encASRepPart['key']['keytype']]
sessionKey = Key(cipher.enctype,encASRepPart['key']['keyvalue'].asOctets())TGS Exchange
The client presents the TGT, a Kerberos authenticator, and the service principal name (SPN) in the request sent to the KDC for a service ticket for the server.
Kerberos Authenticator
A timestamp encrypted with the TGS session key derived in the KRB_AS_REP used to demonstrate the knowledge of the session key in the accompanying ticket.
The authenticator is embedded in a KRB_AP_REQ carried by the KRB_TGS_REQ message as a PA_TGS_REQ padata field, refer to the [RFC4120] section 5.5.1.
Implementation in the function getKerberosTGS of the Impacket package:
# Key Usage 7
# TGS-REQ PA-TGS-REQ padata AP-REQ Authenticator (includes
# TGS authenticator subkey), encrypted with the TGS session
# key (Section 5.5.1)
encryptedEncodedAuthenticator = cipher.encrypt(sessionKey, 7, encodedAuthenticator, None)
...
apReq['authenticator']['cipher'] = encryptedEncodedAuthenticator
encodedApReq = encoder.encode(apReq)
...
tgsReq['padata'][0]['padata-type'] = int(constants.PreAuthenticationDataTypes.PA_TGS_REQ.value)
tgsReq['padata'][0]['padata-value'] = encodedApReqTicket-Granting Ticket
Contained in the padata of an encoded AP-REQ request body as seen in the [RFC4120] section 5.2.7.1.
Implementation in the function getKerberosTGS of the Impacket package:
The KDC validates the TGT ([RFC4120] section 5.3) and the authenticator ([RFC4120] section 5.5.1). If these are valid, the KDC returns a service ticket ([RFC4120] section 5.3) and session key the client can use to encrypt communication with the server.
Session Key
As in the KRB_AS_REP message, a new session key is contained in the encryption part, encrypted by the TGS session key this time, of the KRB_TGS_REP message.
See the example code in Impacket.
The new session key is used in the AP exchange, for example like this.
AP Exchange
The client presents the ticket ([RFC4120] section 5.3) and a new authenticator ([RFC4120] section 5.5.1). The server will decrypt the ticket, validate the authenticator, and can use any authorization data ([RFC4120] section 5.2.6) contained in the ticket for access control.
Optionally, the client might request that the server verify its own identity. If mutual authentication is requested, the server returns the client's timestamp from the authenticator encrypted with the session key.
Service Principal Name (SPN)
A unique identifier associates a service instance with a service sign-in account.
Format
An SPN must be unique in a forest in which it is registered.
<service class>/<host>:<port>/<service name>Common service classes can be found here:
Registration
Typically, SPN registration is done by a service installation program running with domain administrator privileges.
Privilege Attribute Certificate (PAC)
The Privilege Attribute Certificate (PAC) was created to provide the authorization data, which the Kerberos protocol doesn't provide, for Kerberos Protocol Extensions [MS-KILE].
Into the PAC structure [MS-KILE] encodes authorization information, which consists of group memberships, additional credential information, profile, and policy information, and supporting security metadata.
The Kerberos protocol allows a field within the Kerberos ticket to carry authorization information, and Windows uses that field to carry information about Windows groups.
Keytab File
Creation
We can use the command ktpass on windows to
configure the server principal name for the host or service in Active Directory Domain Services (AD DS) and
generate a .keytab file that contains the shared secret key of the service.
C:\> ktpass /princ host/User1.contoso.com@CONTOSO.COM /mapuser User1 /pass MyPas$w0rd /out machine.keytab /crypto all /ptype KRB5_NT_PRINCIPAL /mapop setOn Linux, we can use command kutil.
>ktutil
ktutil: addent -password -p username/domain.com@DOMAIN.COM -k <kvno> -e rc4-hmac
ktutil: wkt ./keytab.file
ktutil: quitLast updated
