Operator On The Wire
← Back to Knowledge Base
OOTW / Chapter IV - Active Directory / 04. Techniques / Service Principals

Parsing

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 classWhat to ask next
MSSQLSvcIs it user-owned and roastable? Can the cracked account access SQL or run commands?
HTTPIs it WinRM, ADCS, IIS, Exchange, or another web SSO endpoint?
cifsDoes the impersonated identity have local admin or share access on the host?
ldapIs this a DC? Can the ticket be used for LDAP writes, DCSync setup, RBCD, or directory queries?
TERMSRVIs RDP enabled and is the impersonated identity allowed to log on?
HOSTWhich host-backed service will accept this ticket?
GCDo we need forest-wide LDAP-style enumeration?
timeIs 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.