Kerberoasting Attacks and Detections

Basic Overview

Caleb Oswald
9 min readJun 27, 2022

Before jumping into Kerberoasting, we need to first understand Kerberos. Kerberos was introduced by MIT in the 80s and then implemented in the late 90s. It is an authentication protocol that Windows uses to better protect its system and users. Kerberos is special because it brings in a third party called the Key Distribution Center (KDC). This is an example of a three-way handshake. The KDC uses Active Directory to secure its accounts. The KDC can be broken down into two parts, the Authentication Server (AS) and the Ticket Granting Service (TGS). The AS is responsible for issuing Ticket Granting Tickets (TGT), and the TGS is responsible for issuing service tickets.

Mitre Att&ck says that Kerberoasting is “Adversaries possessing a valid Kerberos ticket-granting ticket (TGT) may request one or more Kerberos ticket-granting service (TGS) service tickets for any SPN from a domain controller (DC)”. Meaning that an attacker can abuse the authentication protocol by using a TGT to get access to a service ticket, because with a service ticket the attacker can act as the user it stole it from, gain access to other services, possibly escalate privileges, etc. The service ticket also contains the user’s credentials, which is what we will be after today.

This attack can be simplified into three basic steps: get a list of SPNs from the target machine, request/get a service ticket, and crack the hash. In order to crack the hash, the attacker will typically use a brute force approach that can be done offline. This can be done on the target machine or remotely. I am going to show two different ways to run a Kerberoast attack, and how each of them is different. I will be running this attack via Invoke-Kerberoast and then through Mimikatz. The goal is to get a service ticket, which these two attacks will achieve but in different ways. Let’s start with Invoke-Kerberoast:

Invoke-Kerberoast Attack

  1. First, we need to pull the Invoke-Kerberoast script from a GitHub page, run the script, and save the hashes to an output file. This is where we are requesting a service ticket from the DC and then dump it.

Note: If you wanted to see a list of only the SPNs and the users, you could run a script like GetUserSPNs. But the Invoke-Kerberos script already does the LDAP call in the Get-DomainUser function.

2. We then need to locate that hash file and copy the user’s hash we wish to try and crack. Here is what the output file looks like. We will need to copy the entire hash for one user.

3. Once we have the hash, we can run the brute force attack offline so I made the decision to move over the Kali to run Hashcat. You will need to copy the hash of the user you want, and paste that (in 1 line) into a text file in Kali. (I pasted into “hash.txt”)

4. This command specifies the format, our hash file, word dictionary, and a new output file. -m 13100 is the Hashcat mode, which is Kerberos 5 TGS-REP. -o is the output file. -a 0 means it’s a dictionary attack. Hash.txt is the file we pasted our hash, and wordDict.txt is the dictionary we are using (Kali has tons already downloaded). Hashcat will run all the words in the dictionary across the hash and paste the result into the output file (“cracked.txt”).

5. In our output file, we now can see that Hashcat was successful in cracking the hash. Highlighted at the end of the hash is the cracked password.

Mimikatz Export Attack

  1. First, we can run a quick script to get the SPNs and decide which one to crack.

2. After deciding on an account to attack, in this case, we will attack Thor, we will run a tool called Mimikatz. I created this script to download, unzip, and run it all in one.

3. Using this command we will take the list of service tickets and export them. They will be in the form of a Kirbi file.

4. The name of the file is the hash. We need to copy the name of the file we wish to try and crack.

5. We will also want a dictionary. Which is just a text file full of passwords to try. Tons of these are easily found online.

6. Finally, we will use a cyber tool called tgsrepcrack. You can download this off a GitHub page. We will enter the script, the dictionary, and the service ticket from the Kerbi file. Tgsrepcrack is a script that will use brute force and try every password in the dictionary. This can be accomplished offline.

Detection for Invoke-Kerberoast

What I do know about Invoke-Kerberoast is that it uses “Get-DomainSPNTicket”. This function will request a service ticket for the given SPN. We know that 4769 is a Kerberos Service Ticket Request and that this EventCode will appear anytime a user logs in. (I will be using Splunk as my SIEM) Invoke-Kerberoast was therefore pretty easy to detect. We can see the EventCode 4769 logs that it threw, and there were two things that I noticed from this event log that stood out to me. The first was that the account and the service information were not the same. As we see here, Spidy was the user who requested the ticket for Thor.

But even more interesting than that, we can see that the requested encryption type is 0x17, which is an RC4 encryption format. The typical encryption type is 0x12, which is Advanced Encryption Standard (AES).

The difference between the two encryptions is that AES is a block cipher and therefore encodes typically 128-bit blocks, while RC4 is a stream cipher and encodes one bit at a time. Because of RC4’s simplicity, this makes it popular among attackers as they can crack the hashes much easier and faster. We can write a simple detection for this such as:

Simply asking to alert us when a Kerberos Ticket is being requested with encryption type 0x17. Another route we can take, is to alert when a ticket is requested by a Domain Admin. Considering there should only be a few Domain Admins in your environment, we could easily set up alerts by Service Names.

Alerting by the EventCode alone would not work as every time a user logs in there would be a log, so we have to refine the search.

Detection for Mimikatz Export

This attack was much more tricky to detect than the Invoke attack. Mimikatz was not throwing any logs for EventCode 4769. I did not understand why this was, because if it was requesting a service ticket from the DC then why wasn’t it throwing a service ticket log? After talking with a friend, we found that Mimikatz pulls the service tickets from the local memory stored in the Local Security Authority Subsystem Service (LSASS). You can see that in this guide. LSASS is responsible for managing your local security, login, and permissions, and is the user mode of LSA. Meaning that it acts as a service host and is hosting LSA. Microsoft’s Documentation explains it as “LSASS stores credentials in memory on behalf of users with active Windows sessions. This allows users to seamlessly access network resources, such as file shares, Exchange Server mailboxes, and SharePoint sites, without re-entering their credentials for each remote service”. I was able to confirm this because “kerberos::list” gets the same results as running “klist” in Powershell. Klist will display all the cached tickets for the current user. Because Mimikatz was pulling from local memory there was no need to talk to the DC, and therefore would not throw the service ticket logs. So I decided to take a different route. When I exported the list (kerberos::list /export), it created several .kirbi files. While kirbi files aren’t specifically for Mimikatz, we know that kirbi files aren’t super common and that Mimikatz utilizes them. EventCode 11 means that a file has been created, so we search for that along with the .kirbi to get what we want.

This is the logs that it showed:

In this log, we can even see that the image file was Mimikatz, along with the target file looking exactly like a ticket with the file type .kirbi. Something else that would work really well in this situation, would be able to have an EDR setup on the DC that alerts us when someone uses specific LDAP filters, such as wildcard servicePrincipalNames=*. This was found in the first PowerShell script we ran “getPrincName.ps1”. Unfortunately, I could not find any that were open source.

Overview of Detection

The most popular form of detection seems to be the EventCode 4769. But this wouldn’t be uncommon as every user will log on multiple times a day. Therefore we can narrow the search for the encryption type that it request, looking for 0x17 (RC4) encryption instead of the typical 0x12 (AES). We could also watch out for that event code firing for local or domain admin accounts that shouldn’t have a lot of logons. But not all attacks are the same and might require a detection to be written specifically about that attack like we had to do with Mimikatz. Another detection technique we can do is to set up an SPN Honeypot. This honeypot would look identical to other domain accounts, and we can create a custom alert that will fire if an SPN is requested for that account. Here we can see the very easy to spot honeypot “clickme”:

The goal of honeypots is to make them look as real and identical to other accounts as possible while still being enticing. Such as making sure it has logged onto a computer recently and has a bad password attempt. To make it enticing you might actually give it admin rights.

In the end, because Kerberoasting ends with a brute force attack method, the best prevention we can do is to enforce long and complex password requirements for our environment.

Thank you guys for reading. I had a great time creating this. I am always willing to learn, so please reach out if you feel there is a topic/info that I need to learn.

Resources

https://www.simplilearn.com/what-is-kerberos-article

https://github.com/nidem/kerberoast

https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/klist

https://www.netwrix.com/cracking_kerberos_tgs_tickets_using_kerberoasting.html

https://medium.com/@markmotig/kerberoasting-from-setup-to-cracking-3e8c980f26e8

https://resources.infosecinstitute.com/topic/hashcat-tutorial-beginners/

https://adsecurity.org/?page_id=1821

Jonathan Johnson

https://github.com/EmpireProject/Empire/blob/master/data/module_source/credentials/Invoke-Kerberoast.ps1

https://askanydifference.com/difference-between-aes-and-rc4-with-table/

https://powersploit.readthedocs.io/en/latest/Recon/Get-DomainSPNTicket/

https://syfuhs.net/a-bit-about-the-local-security-authority

https://docs.microsoft.com/en-us/previous-versions/windows/it-pro/windows-server-2012-r2-and-2012/hh994565(v=ws.11)

https://redcanary.com/threat-detection-report/threats/mimikatz/

https://attack.mitre.org/techniques/T1558/003/

https://docs.microsoft.com/en-us/windows-server/security/kerberos/kerberos-authentication-overview

https://adsecurity.org/?p=3513

https://www.hub.trimarcsecurity.com/post/the-art-of-the-honeypot-account-making-the-unusual-look-normal

https://jsecurity101.medium.com/ioc-differences-between-kerberoasting-and-as-rep-roasting-4ae179cdf9ec

https://github.com/jsecurity101/Marvel-Lab

By: Caleb Oswald

Last Edit: June 2022

--

--