> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/fsprotect/edges/ad/has_spn.md).

# HAS\_SPN

## Summary

|                            |           |
| -------------------------- | --------- |
| **FSProtect ACL Alias**    | HAS\_SPN  |
| **Affected Object Types**  | Computers |
| **Exploitation Certainty** | Unlikely  |

## Description

The `HAS_SPN` attribute in Active Directory indicates that a machine’s Service Principal Name (SPN) attribute is populated with one or more SPNs. SPNs are unique identifiers that link a service instance to the service account under which it runs, playing a critical role in Kerberos authentication. When a machine has one or more SPNs registered, it signifies that the system is configured to offer Kerberos-based services. This allows clients to request service tickets that correctly identify and authenticate the service, ensuring that the proper service account is engaged during the authentication process.

## Identification

### PowerShell

#### Active Directory Module

Using the ActiveDirectory PowerShell module, you can enumerate HAS\_SPN entries.

Function: Find-HASSPN

```powershell
function Find-HASSPN {
    [CmdletBinding()]
    param ([string]$Target = $null,[string]$SearchBase = $null,[string]$OutputPath = "ServicePrincipalName.csv")
    Import-Module ActiveDirectory -ErrorAction Stop
    Write-Host "Gathering computer objects with 'ServicePrincipalName' property..."
    $adComputerParams = @{
        Filter      = "*"
        Properties  = "ServicePrincipalName"
        ErrorAction = "Stop"
    }
    if ($SearchBase) {
        $adComputerParams.Add("SearchBase", $SearchBase)
        Write-Host "Searching for computers within '$SearchBase'."
    } else {
        $adComputerParams.Add("SearchBase", (Get-ADRootDSE).DefaultNamingContext)
        Write-Host "Searching for all computers in the domain."
    }
    $computersToScan = @()
    $spnResults = @()
    try {
        if ($Target) {
            Write-Host "Searching for ServicePrincipalName on specific computer: '$Target'."
            $computersToScan += Get-ADComputer -Identity $Target -Properties "ServicePrincipalName" -ErrorAction Stop
        } else {
            $computersToScan = Get-ADComputer @adComputerParams
        }
    }
    catch {
        Write-Error "Failed to retrieve computer objects from Active Directory: $($_.Exception.Message)"
        return
    }
    if (-not $computersToScan) {
        Write-Output "No computer objects found to process."
        return
    }
    foreach ($computer in $computersToScan) {
        if ($computer.ServicePrincipalName) {
            foreach ($spn in $computer.ServicePrincipalName) {
                $spnResults += [PSCustomObject]@{
                    'Service'     = $spn
                    'Working on'  = $computer.Name
                }
            }
        }
    }
    if ($spnResults.Count -gt 0) {
        Write-Host "Found $($spnResults.Count) ServicePrincipalName entry(ies)."
        try {
            $spnResults | Sort-Object -Unique 'Service', 'Working on' | Export-Csv -Path $OutputPath -NoTypeInformation -Encoding UTF8 -ErrorAction Stop
            Write-Output "Results exported successfully to '$OutputPath'"
        }
        catch { Write-Error "Failed to export results to CSV file '$OutputPath': $($_.Exception.Message)"}
    } else { Write-Output "No computer objects found with 'ServicePrincipalName' property set."}
}
```

**1.** Scan all domain computers

```powershell
Find-HASSPN
```

**2.** Scan a specific object

```powershell
Find-HASSPN -Target "FSSQL"
```

**3.** Using SearchBase to limit the scope

```powershell
Find-HASSPN -SearchBase "OU=Workstations,DC=forestall,DC=labs"
```

#### Active Directory Users and Computers

**1.** Open Active Directory Users and Computers on your Windows server.

**2.** Right-click on the Computer.

**3.** Select Properties from the context menu.

**4.** In the Properties window, navigate to the Attribute Editor tab.

**5.** In the attribute editor's list, locate and check the option servicePrincipalName with double click.

**6.** Click OK to close the dialogs.

## Exploitation

No viable exploitation technique has been identified for this finding. The "Exploitation" section is included for completeness, but no method or proof-of-concept is currently available to exploit the issue.

## Mitigation

No specific mitigation can be applied to the `HAS_SPN` edge. Since this edge only represents the existence of a `Service Principal Name` and does not correspond to an exploitable path, no direct mitigation is required.

## Detection

Adding new Access Control Entries on Active Directory objects changes the `ntSecurityDescriptor` attribute of the objects themselves. These changes can be detected using Event IDs 5136 and 4662 to identify dangerous modifications.

| Event ID | Description                              | Fields/Attributes      | References                                                                                                                     |
| -------- | ---------------------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| 5136     | A directory service object was modified. | ntSecurityDescriptor   | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-5136>                                     |
| 4662     | An operation was performed on an object. | AccessList, AccessMask | <https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/event-4662>                                     |
| 4742     | A computer account was changed.          | Subject, Account Name  | <https://learn.microsoft.com/en-us/previous-versions/windows/it-pro/windows-10/security/threat-protection/auditing/event-4742> |

## References

* [What is Service Principal Names & Service Accounts - Payatu](https://payatu.com/blog/what-is-service-principal-names-service-accounts/)
* [MS-ADTS: Active Directory Technical Specification - Service Principal Names](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-adts/cd328386-4d97-4666-be33-056545c1cad2)
