ADKERB-011: Computer SPN Audit

Platform
Active Directory
Category
AD Kerberos Security
Severity
Info
Zero Trust pillar
Identity (weight 1)
Golden fixtures
2
Branch coverage
Observed: fixtures prove the verdicts they exercise
Provenance
baseline

What it checks

The check performs an LDAP query against each domain naming context in the forest: (&(objectCategory=computer)(servicePrincipalName=*)) For every matching object it captures sAMAccountName, dNSHostName, distinguishedName, the full servicePrincipalName multi-valued attribute, userAccountControl (to detect disabled or trusted-for-delegation machines), msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD configuration), lastLogonTimestamp, operatingSystem, and whoCreated / whoModified metadata from the replication metadata where available. Guerrilla then runs three correlation passes: 1. Duplicate detection. Every SPN string is normalized (lowercase, trimmed) and grouped across the forest. Any SPN that appears on more than one security principal (computer or user) is flagged. This is the same logic setspn -X implements server-side via the SPN uniqueness check that the KDC performs at ticket-granting time. 2. Default vs non-default classification. Each SPN is compared against the well-known default set Windows registers automatically (HOST/<host>, HOST/<fqdn>, RestrictedKrbHost/<host>, RestrictedKrbHost/<fqdn>, TERMSRV/<host>, TERMSRV/<fqdn>, WSMAN/<host>, WSMAN/<fqdn>, and the cluster, MSServerCluster, and Hyper-V Replica services on cluster nodes). Anything outside this set (MSSQLSvc, HTTP, CIFS on a non-server, exchangeAB, MSOMHSvc, MSOMSdkSvc, IMAP, POP, SMTP, ldap, gc, GC, kadmin, krbtgt, etc.) is classified as a non-default service registration and listed for analyst review. 3. Posture flags. For each computer with SPNs the check evaluates whether userAccountControl carries TRUSTED_FOR_DELEGATION (0x80000), TRUSTED_TO_AUTH_FOR_DELEGATION (0x1000000), or has a populated msDS-AllowedToDelegateTo (constrained delegation) or msDS-AllowedToActOnBehalfOfOtherIdentity (RBCD) attribute. SPNs on delegation-enabled computers are higher-value targets and are surfaced with elevated context. The check does not require any privileged rights. Authenticated LDAP read of the domain NC is sufficient, which mirrors the visibility every domain-joined principal already has.

Why it matters

SPNs are the binding between a service name and the Kerberos long-term key used to encrypt service tickets. When the KDC issues a TGS-REP for a given SPN, it looks up the security principal that holds that SPN and encrypts the ticket with that principals key. This has two operational and security consequences. Availability: if the same SPN is registered on two different accounts, the KDC selects one at random (the SPN uniqueness constraint is enforced at write time only when the writing client validates it, not at lookup time). The client receives a ticket encrypted with the wrong accounts key and the service returns KRB_AP_ERR_MODIFIED. Windows clients then either fail outright or silently fall back to NTLM. Silent NTLM fallback defeats Kerberos-only auditing, enables NTLM relay attacks against the service, and masks the underlying misconfiguration from monitoring. Security: any principal that can write the servicePrincipalName attribute on a target computer can register an SPN of their choice on that computer. This is the foundation of the "SPN squatting" abuse path documented by SpecterOps. Writing an SPN on a victim machine account, then requesting a service ticket for that SPN, returns a TGS-REP encrypted with the victim machines NT hash equivalent. Although computer account passwords are 240 characters and effectively uncrackable, the abuse becomes potent when combined with: (a) Resource-Based Constrained Delegation, where an attacker who controls msDS-AllowedToActOnBehalfOfOtherIdentity on the target can use a controlled SPN to S4U2Self / S4U2Proxy into the target as any user including Domain Admin, (b) unconstrained delegation, where TGTs forwarded to the target can be extracted, and (c) NTLM relay scenarios against AD CS HTTP enrollment endpoints (ESC8) where the SPN registered on a relayable computer becomes the pivot. Unexpected SPNs on workstations (an MSSQLSvc on an end-user laptop, a HOST/admin-workstation on a domain controller, a CIFS/ on a kiosk) are strong indicators of either shadow IT, unsupported application installations, or active intrusion staging. The check surfaces these patterns so the analyst can investigate.

Attack path

1. Identify a write target. The attacker enumerates computer objects where the current security context has GenericWrite, WriteProperty on servicePrincipalName, or Validated-SPN write. This is commonly the result of (a) machine account quota abuse (MachineAccountQuota = 10 by default lets any user join 10 machines and own them), (b) inherited ACLs from an OU delegation, or (c) compromise of an account that owns or has been delegated rights to the target. BloodHound surfaces these paths as AddAllowedToAct, GenericWrite, or WriteSPN edges. 2. Stage the SPN. The attacker writes an arbitrary SPN to the victim computer: Set-ADComputer victim$ -ServicePrincipalNames @{Add="HTTP/attackerchosen.corp.contoso.com"}. With Impacket the equivalent is addspn.py -u corp/lowpriv -p Password1 -t victim$ -s HTTP/attackerchosen.corp.contoso.com dc01.corp.contoso.com. 3. Request a service ticket. The attacker now requests a TGS for the SPN they just registered. Rubeus.exe kerberoast /spn:HTTP/attackerchosen.corp.contoso.com /outfile:tgs.txt or, for the S4U flow, Rubeus.exe s4u /user:victim$ /rc4:<machine-hash> /impersonateuser:Administrator /msdsspn:HTTP/attackerchosen.corp.contoso.com /altservice:cifs,host,http /ptt. 4. Pivot via delegation. If the victim computer has msDS-AllowedToActOnBehalfOfOtherIdentity writable by the attacker, the attacker first adds their controlled principal to it (Set-ADComputer victim$ -PrincipalsAllowedToDelegateToAccount attacker_controlled$), then performs S4U2Self followed by S4U2Proxy to obtain a ticket as any user (including Domain Admins, since by default DA accounts are not in Protected Users and are not marked sensitive-and-cannot-be-delegated) to any service on the victim. This is the classic RBCD attack chain (Elad Shamir, "Wagging the Dog", 2019). 5. NTLM relay variant. Where AD CS Web Enrollment is exposed (ESC8 / PetitPotam, CVE-2021-36942), the attacker coerces the victim computer to authenticate to the attacker, relays that NTLM session to the AD CS HTTP enrollment endpoint, and requests a certificate using a Subject Alternative Name. The SPN audit detects the staged SPN on the relay-eligible computer before the chain completes. 6. Maintain access. Once any of the above succeeds, the attacker retains the SPN registration as a persistence primitive. A subsequent defender who only rotates the machine password leaves the SPN, and therefore the abuse path, intact.

How Guerrilla assesses it

Guerrilla queries each domain in the forest with the filter (&(objectCategory=computer)(servicePrincipalName=*)) and pulls servicePrincipalName, sAMAccountName, dNSHostName, distinguishedName, userAccountControl, msDS-AllowedToDelegateTo, msDS-AllowedToActOnBehalfOfOtherIdentity, operatingSystem, lastLogonTimestamp, and pwdLastSet. The check then performs in-memory deduplication using a case-insensitive hash of every SPN string, which matches the comparison the KDC itself performs (Kerberos principal name comparison is case-insensitive for the service component). Any collision is flagged as a duplicate finding and the colliding objects are emitted together so the analyst can reconcile. Non-default SPNs are matched against a curated allow-list of Windows-registered defaults; anything outside the list is emitted as a non-default registration with the originating computers OS, last logon, and delegation posture. For environments running with Active Directory Web Services available, the native equivalent of the duplicate scan is setspn -X (forest-wide) or setspn -L <computername> (per-host), and the native equivalent of the enumeration is Get-ADComputer -Filter 'servicePrincipalName -like "*"' -Properties servicePrincipalName, msDS-AllowedToDelegateTo, msDS-AllowedToActOnBehalfOfOtherIdentity, userAccountControl. The check correlates each result with prior ADKERB-002 (Kerberoasting) and ADACL findings to highlight computers where a non-default SPN exists alongside a writable servicePrincipalName ACL.

Recommended value

No duplicate SPNs across the domain. All SPNs on computer accounts correspond to legitimate, documented services

Remediation

Scan for duplicate SPNs using setspn -X in the forest or Get-ADObject queries. Remove or reassign duplicate SPNs to the correct accounts. Review SPNs on computer objects to identify any unauthorized or unexpected services. Use setspn -L <computername> to list SPNs per computer. Document all non-default SPNs with their business purpose

Fixture-proven verdicts

Every verdict below is proven by a golden fixture in the module's gating test suite. This table derives from the last green run; it cannot be edited by hand.

Verdict scenarios for ADKERB-011
ScenarioExpected verdict
cleanPASS
throttledNot Assessed

Framework mappings

NIST SP 800-53
CM-8
CIS AD Benchmark
7.1.3