SPN parsing turns a string into an operational target. We split the SPN into service class, host, optional port or instance, and owning account. Then we decide whether the service is useful for roasting, lateral movement, delegation, or ticket forgery.
SPN anatomy
MSSQLSvc/sql01.ootw.local:1433
| | |
class host port
HTTP/web01.ootw.local
| |
class host
MSSQLSvc/sql01.ootw.local/INSTANCE
| | |
class host instance
Parsing rules
The service class is left of the first slash.
The host is right of the first slash until a colon or second slash.
The port is after a colon.
The instance is often after the second slash.
The owner is not in the SPN string; the owner is the AD object that has the `servicePrincipalName` value.
Service-class decision table
| Service class | What to ask next |
|---|---|
MSSQLSvc | Is it user-owned and roastable? Can the cracked account access SQL or run commands? |
HTTP | Is it WinRM, ADCS, IIS, Exchange, or another web SSO endpoint? |
cifs | Does the impersonated identity have local admin or share access on the host? |
ldap | Is this a DC? Can the ticket be used for LDAP writes, DCSync setup, RBCD, or directory queries? |
TERMSRV | Is RDP enabled and is the impersonated identity allowed to log on? |
HOST | Which host-backed service will accept this ticket? |
GC | Do we need forest-wide LDAP-style enumeration? |
time | Is this only useful as a delegation source for altservice? |
Find owner from SPN
ldapsearch -LLL -x -H ldap://10.10.10.200 -D "ootw.local\\student" -w 'student' -b "DC=ootw,DC=local" '(servicePrincipalName=MSSQLSvc/sql01.ootw.local:1433)' sAMAccountName objectClass distinguishedName servicePrincipalName
Find all SPNs owned by one account
ldapsearch -LLL -x -H ldap://10.10.10.200 -D "ootw.local\\student" -w 'student' -b "DC=ootw,DC=local" '(sAMAccountName=svc_sql)' sAMAccountName servicePrincipalName
Windows owner lookup
setspn -Q MSSQLSvc/sql01.ootw.local:1433
setspn -L OOTW\svc_sql
PowerShell owner lookup
Get-ADObject -LDAPFilter '(servicePrincipalName=MSSQLSvc/sql01.ootw.local:1433)' -Properties servicePrincipalName,sAMAccountName |
Select-Object sAMAccountName,ObjectClass,DistinguishedName,ServicePrincipalName
Name matching
If the client connects to sql01.ootw.local, request the FQDN SPN.
If the client connects to SQL01, test the short-name SPN if it exists.
If the service runs on a port, include the registered port when the SPN includes it.
If the service rejects the ticket, verify which SPN the service actually registered.
If two accounts own the same SPN, expect Kerberos failures or service confusion.
Operational interpretation
- User-owned SPN: prioritize Kerberoast and service account takeover.
- Computer-owned SPN: prioritize host access, delegation, RBCD, and machine account key abuse.
- DC-owned LDAP SPN: high-value for directory operations.
- HTTP on CA: ADCS web enrollment or web relay relevance.
- MSSQLSvc: SQL lateral movement and command execution paths.