Service Principal Names (SPNs) associated with user accounts are prime targets for Kerberoasting attacks. Canary SPNs detect when attackers request service tickets for offline cracking.
NOTE: When creating any kind of Cyber Deception in your organization be creative with your strategy! Create Canaries that make sense for your network and existing assets so they are believable by adversaries. The examples below are to show you the basic structure for creating a Canary SPN - create your own names that make sense for your specific deception. One last pro-tip, log into your canary accounts and/or SPN accounts every so often so they have a somewhat current ‘last logon’ timestamp.
Understanding the Attack
- Attacker enumerates user accounts with SPNs
- Requests TGS tickets for those SPNs
- Extracts tickets and cracks them offline
- Canary SPNs have no real service—any ticket request is malicious
What is a Service Principal Name (SPN)?
Definition
A Service Principal Name (SPN) is a unique identifier that Kerberos uses to associate a service instance with a service account in Active Directory. Think of it as a "phone number" that tells Kerberos how to reach a specific service running under a specific account.
Why SPNs Exist
In Windows Active Directory environments, many services run under dedicated service accounts (not the computer account). When a user wants to access one of these services, Kerberos needs to know:
- What service they're trying to access (e.g., SQL Server, IIS web server)
- Where that service is running (hostname/port)
- What account is running that service (to encrypt the ticket properly)
The SPN provides this mapping.
SPN Structure
SPNs follow this format:
ServiceClass/ServiceHost:Port/ServiceName| Component | Description | Required? | Example |
|---|---|---|---|
| ServiceClass | Type of service | Yes | MSSQLSvc, HTTP, CIFS, LDAP |
| ServiceHost | Hostname where service runs | Yes | sqlserver01.corp.local |
| Port | Service port number | Optional | 1433, 443 |
| ServiceName | Additional service identifier | Optional | Database instance name |
Common Examples
MSSQLSvc/sqlserver01.corp.local:1433
↳ SQL Server running on sqlserver01.corp.local on port 1433
HTTP/webapp.corp.local
↳ Web service running on webapp.corp.local
CIFS/fileserver.corp.local
↳ File share service on fileserver.corp.local
LDAP/dc01.corp.local
↳ LDAP service on domain controller dc01How SPNs Work in Kerberos
Here's the authentication flow:
1. User wants to access SQL Server
User → Domain Controller: "I need a ticket for MSSQLSvc/sqlserver01.corp.local:1433"
2. Domain Controller looks up the SPN
DC searches AD: "Which account has this SPN registered?"
Result: svc_sql_prod
3. DC creates a TGS ticket
DC encrypts ticket using svc_sql_prod's password hash
DC → User: Here's your service ticket (encrypted)
4. User presents ticket to SQL Server
User → SQL Server: Here's my ticket
SQL Server (running as svc_sql_prod): I can decrypt this! Access granted.Registering SPNs
SPNs must be registered to service accounts in Active Directory:
powershell
# Register an SPN to a service account
setspn -S MSSQLSvc/sqlserver01.corp.local:1433 DOMAIN\svc_sql_prod
# View SPNs registered to an account
setspn -L svc_sql_prod
# Find which account has a specific SPN
setspn -Q MSSQLSvc/sqlserver01.corp.local:1433Why Attackers Target SPNs: Kerberoasting
This is where SPNs become a security concern:
The Attack Flow
- Enumeration: Attacker queries AD for all accounts with SPNs
powershell
Get-ADUser -Filter {ServicePrincipalName -ne "$null"} -Properties ServicePrincipalName
```
2. **Request TGS Tickets**: Attacker requests service tickets for every SPN they find
- Kerberos will provide these tickets to ANY authenticated domain user
- No special privileges needed
3. **Offline Cracking**: The TGS tickets are encrypted with the service account's password
- Attacker extracts the encrypted portion
- Attempts offline brute-force/dictionary attacks
- If the service account has a weak password → attacker gains access
### Why This Works
- **Any domain user** can request TGS tickets for any SPN
- Service accounts often have:
- Weak or predictable passwords
- `PasswordNeverExpires` flag set
- Elevated privileges (sometimes Domain Admin!)
- The entire attack happens **without alerting** the actual service
## Canary SPNs: Turning the Tables
This is where honey SPNs come in:
### The Deception Strategy
```
1. Create fake service account: svc_sqlbackup_honey
2. Give it a super strong password: "Xy9$mK2#pL8@vQ4&rT6^wN3!"
3. Register a realistic SPN: MSSQLSvc/sqlbackup.corp.local:1433
4. Enable Kerberos auditing (Event ID 4769)
Result:
- Attacker enumerates SPNs → sees svc_sqlbackup_honey (looks legitimate!)
- Attacker requests TGS for the honey SPN → Event 4769 fires
- SOC gets immediate alert: "Someone is Kerberoasting!"
- Attacker wastes time trying to crack an uncrackable passwordDetection Advantage
Since no legitimate service actually uses the honey SPN:
- Any TGS request (Event 4769) for it = malicious activity
- Zero false positives
- Early warning before attacker succeeds
Real-World SPN Examples
| Service | SPN Format | Typical Account |
|---|---|---|
| SQL Server | MSSQLSvc/hostname:1433 | svc_sql, svc_mssql |
| IIS Web Server | HTTP/hostname | svc_iis, svc_web |
| Exchange | exchangeMDB/hostname | svc_exchange |
| SharePoint | HTTP/sharepoint.domain.com | svc_sharepoint |
| LDAP | LDAP/dc.domain.com | Domain Controller computer account |
| File Share (CIFS) | CIFS/fileserver.domain.com | Usually computer account |
Creating a Canary SPN Account
powershell
# Create the canary service account
New-ADUser -Name "svc_sqlreport" `
-SamAccountName "svc_sqlreport" `
-UserPrincipalName "svc_sqlreport@domain.local" `
-Description "SQL Reporting Services Account" `
-Enabled $true `
-PasswordNeverExpires $true `
-AccountPassword (ConvertTo-SecureString "Sup3r_C0mpl3x_P@ssw0rd_2024!!" -AsPlainText -Force) `
-Path "OU=Service Accounts,DC=domain,DC=local"
# Register a fake SPN
Set-ADUser -Identity "svc_sqlreport" -ServicePrincipalNames @{
Add = "MSSQLSvc/sqlreport.domain.local:1433",
"MSSQLSvc/sqlreport.domain.local"
}
# Verify SPN registration
Get-ADUser -Identity "svc_sqlreport" -Properties ServicePrincipalNames |
Select-Object Name, ServicePrincipalNamesMultiple Canary SPNs for Different Services
powershell
# Array of canary SPN configurations
$CanarySPNs = @(
@{
Name = "svc_sqlbackup"
SPN = "MSSQLSvc/sqlbackup.domain.local:1433"
Description = "SQL Backup Service"
},
@{
Name = "svc_iis_admin"
SPN = "HTTP/iis-admin.domain.local"
Description = "IIS Administration Service"
},
@{
Name = "svc_exchange"
SPN = "exchangeMDB/exchange01.domain.local"
Description = "Exchange Mailbox Service"
}
)
foreach ($Config in $CanarySPNs) {
# Create account
New-ADUser -Name $Config.Name `
-SamAccountName $Config.Name `
-Description $Config.Description `
-Enabled $true `
-PasswordNeverExpires $true `
-AccountPassword (ConvertTo-SecureString "C@nary_$(Get-Random -Maximum 99999)!" -AsPlainText -Force) `
-Path "OU=Service Accounts,DC=domain,DC=local"
# Set SPN
Set-ADUser -Identity $Config.Name -ServicePrincipalNames @{Add = $Config.SPN}
Write-Host "Created canary SPN account: $($Config.Name) with SPN: $($Config.SPN)"
}Domain Controller Audit Policy
| Audit Category | Subcategory | Configuration | Purpose |
|---|---|---|---|
| Account Logon Events | Kerberos Service Ticket Operations | Success and Failure | Detects TGS requests (Event 4769) for canary SPNs |
| Account Logon Events | Kerberos Authentication Service | Success and Failure | Detects TGT requests (Event 4768) |
| Account Logon Events | Credential Validation | Success and Failure | Detects authentication attempts |
| Account Management | User Account Management | Success and Failure | Detects account modifications |
| Account Management | Security Group Management | Success and Failure | Detects group membership changes |
| DS Access | Directory Service Access | Success and Failure | Detects AD object access |
| DS Access | Directory Service Changes | Success and Failure | Detects AD modifications |
| Logon/Logoff | Logon | Success and Failure | Detects canary account logon attempts (Event 4624/4625) |
| Logon/Logoff | Account Lockout | Success and Failure | Detects account lockouts |
| Logon/Logoff | Special Logon | Success and Failure | Detects privileged logons |
| Object Access | File System | Success and Failure | Detects canary file access (Event 4663) |
| Object Access | File Share | Success and Failure | Detects canary share access (Event 5140) |
| Object Access | Detailed File Share | Success and Failure | Detects detailed share operations |
Standalone System Audit Policy
| Audit Category | Subcategory | Configuration | Purpose |
|---|---|---|---|
| Object Access | File System | Success and Failure | Detects canary file access |
| Object Access | File Share | Success and Failure | Detects canary share access |
| Logon/Logoff | Logon | Success and Failure | Detects canary account logon attempts |
| Logon/Logoff | Account Lockout | Success and Failure | Detects account lockouts |
| Account Logon | Credential Validation | Success and Failure | Detects authentication attempts |
| Account Management | User Account Management | Success and Failure | Detects local account modifications |
Verifying Audit Configuration
powershell
# View all audit policy settings
auditpol /get /category:*
# Export audit policy for documentation
auditpol /backup /file:C:\AuditPolicy_Backup.csvGroup Policy Configuration
Creating a Canary Detection GPO
GPO Settings Path
Computer Configuration
└── Policies
└── Windows Settings
└── Security Settings
└── Advanced Audit Policy Configuration
└── Audit Policies
Required GPO Audit Settings
Account Logon
| Setting | Configuration |
|---|---|
| Audit Credential Validation | Success and Failure |
| Audit Kerberos Authentication Service | Success and Failure |
| Audit Kerberos Service Ticket Operations | Success and Failure |
Account Management
| Setting | Configuration |
|---|---|
| Audit User Account Management | Success and Failure |
| Audit Security Group Management | Success and Failure |
DS Access (Domain Controllers)
| Setting | Configuration |
|---|---|
| Audit Directory Service Access | Success |
| Audit Directory Service Changes | Success |
Logon/Logoff
| Setting | Configuration |
|---|---|
| Audit Logon | Success and Failure |
| Audit Account Lockout | Success and Failure |
| Audit Special Logon | Success |
Object Access
| Setting | Configuration |
|---|---|
| Audit File System | Success |
| Audit File Share | Success |
| Audit Detailed File Share | Success |
| Audit Handle Manipulation | Success |
