Kerberos is an authentication protocol used in a Microsoft Active Directory context. The lack of knowledge about how it works can lead to the introduction of vulnerabilities that can be exploited by an attacker.
In this article, we will explain the principle and operation of the Kerberos authentication protocol.
Kerberos is a network authentication protocol, primarily used to enable users and services on a network to verify their identity.
It is based on the ‘trusted third party’ concept, which means that it uses a centralised authentication server to validate identities and distribute tickets that grant access to services.
Below are the key elements of Kerberos, which we will detail in the following sections:
The Kerberos protocol works with three entities.
When it comes to the entities involved and how they operate in an Active Directory, there are some subtle concepts that need to be clarified.
The client can be any entity in the domain with a secret known to the KDC. This includes all users and machines in the domain.
Furthermore, any client can request Kerberos access to any service. However, it is not the role of the Kerberos protocol to check whether the client is authorised to access the requested service. This responsibility is left to the service.
A service is a domain entity (user or machine) that has a secret known to the KDC.
It must also have one or more ‘Service Principal Name’ (SPN) registered with the domain controller. This registration consists of registering the services offered on the ‘ServicePrincipalName’ property of the entity’s ‘Active Directory’ object.
The secret associated with this service is used by the KDC to provide the client with a ticket. This behaviour may have a consequence on the confidentiality of the service secret in certain cases.
The KDC secret is that of the default user account ‘krbtgt’.
The security of the kerberos protocol depends on the confidentiality of the krbtgt secret. Leaking this secret compromises the entire security logic of the protocol.
The Kerberos protocol uses the notion of tickets. There are two types of ticket, which are used at different stages of the protocol. These tickets are generated by the KDC for the client using the secrets available to the KDC.
In the next sections of this article, ticket manipulation will be illustrated using the ‘impacket’ and ‘Rubeus’ tools. These two tools are very useful for manually carrying out the individual steps of the Kerberos protocol.
However, it should be borne in mind that for a user on a machine attached to the Active directory domain, these steps are completely transparent.
As far as the tools themselves are concerned, Rubeus can be used on a Windows machine and impacket on other operating systems.
The first type of ticket is the ‘Ticket-Granting Ticket’ (hereafter referred to as TGT). This ticket is obtained during the ‘authentication service’ phase, which consists of demonstrating to the KDC that the client’s secret is known.
Here are the commands for the authentication service phase.
Using the ‘impacket’ library and its ‘getTGT.py’ script:
getTGT.py -dc-ip <IP KDC/DC> <domain>/<user>:<password>
A ‘.ccache’ file will be created by the script.
Using the ‘Rubeus’ tool:
Rubeus.exe asktgt /user:<user> /password:<password> /domain:<domain> /dc:<IP KDC/DC> /outfile:<user>_tgt.kirbi
A ‘.kirbi’ file will be created by the program.
The animated figure below shows how this phase works.
At the end of the ‘authentication service’ phase, the client has a session key and a ‘TGT’ ticket. These two elements will be used to prove its identity during the next phase.
These elements can be viewed in the files created by the commands above. Note that the content of the TGT is partly encrypted with the KDC secret. The client is therefore unable to modify or consult this part.
To be more precise, the breakdown of information received during the ‘’authentication service‘’ stage is as follows:
The encrypted part of the TGT contains information about the ticket (flags, lifespan, etc.) as well as the client’s identity (name, group, UAC, etc.) and a copy of the session key.
In this way, the client cannot falsify its identity, as modifying the TGT requires the secret of the KDC.
The service ticket (ST) is the second ticket obtained by the client. It is obtained during the Ticket-Granting Service (TGS) phase.
During this phase, the client will request access to a service using the TGT and the session key previously obtained and targeting an existing Service Principal Name (SPN).
Here are the commands used to carry out the ‘Ticket-Granting Service’ phase by explicitly giving the ticket obtained in the previous phase.
Using the ‘impacket’ library and the ‘getST.py’ example script:
KRB5CCNAME=<TGT_ccache_file> getST.py -dc-ip <IP KDC/DC> -spn <Target_SPN> <domain>/<user> -no-pass -k
Using the ‘Rubeus’ tool:
Rubeus.exe asktgs /ticket:<TGT_kirbi_file> /service:<Target_SPN> /dc:<IP KDC/DC> /outfile:<user>_st_<SPN>.kirbi
The animated figure below shows how this phase works.
NB: Impacket can be used to link the AS and TGS stages in order to retrieve a service ticket by directly providing the client’s secret.
getST.py -dc-ip <IP KDC/DC> -spn <Target_SPN> <domain>/<user>:<password>
At the end of this phase, the client receives a service ticket (ST) and a service session key. Part of the service ticket is encrypted with the secret of the targeted service. This part contains the client’s identity information, the targeted SPN and a copy of the service session key.
In short, the content of an ST is similar to a TGT except that the field associated with the ‘Service principal Name’ (SPN) will contain the reference to a declared service. In the case of a TGT, this field refers to the ‘krbtgt’ service in the KDC.
Once the service ticket (ST) has been obtained, the client is now able to authenticate itself to the service.
This stage is known as the ‘application request’ (AP) and can be illustrated by the following figure:
Depending on whether you use impacket or Rubeus, the process for accessing services will be different.
Most tools based on the impacket library include the use of Kerberos in their options. Here, we assume that a ‘.ccache’ file was generated during one of the previous steps. This ‘.ccache’ file can contain either a TGT or an ST, but the procedure remains the same. In the case of a TGT, the tool will automatically perform the TGS stage.
The ‘.ccache’ file is integrated by entering the path to this file in the ‘KRB5CCNAME’ environment variable, then specifying the Kerberos options for the script used.
Note that in the impacket ecosystem, there are as many scripts as there are services to interact with (smbclient-ng.py, dnstool.py, wmiexec.py, etc.).
Here is an example of interaction with the SMB service using the smbclient-ng.py script.
$ export KRB5CCNAME=/path/to/user.ccache
$ smbclient-ng.py --kdcHost=<kdc FQDN> -d <domain> -u <user> --host <FQDN of server> -k --nopass
The process for interacting with tickets generated by Rubeus is different. It involves applying the ticket generated directly in a logon session.
This action can be carried out in different ways depending on the privilege level.
If the Rubeus user is not the administrator of the machine, he can use the ‘/ptt’ option to apply the ticket generated to the current session. However, this will overwrite the session and therefore modify the current user’s access to the machine.
Rubeus.exe asktgt /user:<user> /password:<password> /domain:<domain> /dc:<IP KDC/DC> /ptt
# or
Rubeus.exe ptt /ticket:<path/to/ticket.kirbi>
To avoid this inconvenience, it is possible, as long as you are an administrator on the Windows machine, to create a ‘sacrificial process’ to which you can apply the tickets you have generated. The ‘/ptt’ and ‘/createnetonly’ options can be used for this purpose.
Rubeus.exe asktgt /user:<user> /password:<password> /domain:<domain> /dc:<IP KDC/DC> /ptt /createnetonly:C:\Path\to\Program\to\launch
It is possible to list the Kerberos tickets for the active session with the ‘klist’ command.
Once the ‘Logon Session’ is configured, it will be possible to interact transparently with the target service.
NB: With the ‘createnetonly’ option, it is important to understand that only the program’s network interactions will be carried out using the injected identity. For local interactions with the system, the program will use the identity of the original user.
Most encryption and decryption operations in the kerberos protocol use a symmetrical key considered as a secret associated with an entity. This secret, also known as the kerberos key, is calculated by applying a hash function to the password of the entity’s account (user or machine).
To illustrate, here’s how to calculate the kerberos keys derived from an account password using the ‘Rubeus’ program.
Rubeus.exe hash /password:<password> /user:<username> /domain:<domain>
Several hash functions can be used, each of which will generate a different key for the same password. To identify which key is used for encryption, the ‘encryption-type’ or ‘etype’ property is always specified when an encrypted element is transmitted.
In an Active Directory environment, two hash algorithms are available:
This mode of operation has a consequence. Although the Kerberos keys used are all derived from an account password, it is not technically necessary to know the actual value of the password. Only knowledge of the keys is required to use the Kerberos protocol.
This is why tools such as impacket or Rubeus offer an option for using these keys directly rather than using the password.
With impacket:
getTGT.py -hashes :<NTHASH> <domain>/<username> -no-pass
# or
getTGT.py -aes <aeskey> <domain>/<username> -no-pass
With Rubeus:
Rubeus.exe asktgt /rc4:<NTHASH> /user:<username> /domain:<domain>
# or
Rubeus.exe asktgt /aes256:<aeskey> /user:<username> /domain:<domain>
These Kerberos keys can be recovered if a machine on which these secrets are stored is compromised. Most secret extraction tools can display such keys.
With all the elements presented in this first part, we hope that you will be able to understand the overall operation of the Kerberos protocol.
We’ll come back to the principles of Kerberos delegation in another article. We will also explore common vulnerabilities and attacks on this protocol, presenting examples of critical exploits encountered during our pentests of networks incorporating an Active Directory.
Author: Benoit PHILIPPE – Pentester @Vaadata