SQL Server runs as a Tier Zero account

A SQL Server instance runs as a Domain Admin or other Tier Zero account, so whoever administers the database can act as that account.

Category
Attack Path
Severity
At least High.
Typical owner
the database team, with the owner of the service account
Data needed
MSSQLHound's OpenGraph output, read with its built-in mapping pack*. That pack is untrusted until you trust it (trust = ["mssqlhound"] under [opengraph] in pathwarden.toml, or on the app's Mappings page); until then its data is context only. See the OpenGraph guide.
MITRE ATT&CKT1505.001T1078.002
On this page

In plain language

Every SQL Server instance runs as a Windows account. Database administrators can make the server run operating system commands, and those commands run as that account. Older installations were often set up to run as a Domain Admin "so the backups work".

That turns everyone who administers the instance (its sysadmin logins, logins that can impersonate them, administrators of the server it runs on) into a Domain Admin. Database teams are rarely treated as Tier Zero, so this path is easy to miss. Running the service as a gMSA or the default virtual account, with only the rights it needs, closes it.

What Pathwarden flags

A SQL Server instance's service runs as a Tier Zero account (often an old installation that runs as a Domain Admin). Whoever controls the instance (a sysadmin login, a login with CONTROL SERVER or IMPERSONATE ANY LOGIN, an administrator of its computer) runs code as that account (xp_cmdshell, SQL Agent jobs, CLR) and can use its identity on the network. So the instance, and everyone who administers it, controls Tier Zero.

The finding lists the accounts and logins outside Tier Zero that control the instance. The evidence comes from MSSQLHound (an OpenGraph file, see docs/opengraph.md): its service account record, and the logins, roles and permissions that lead to the instance, with Pathwarden's corrections (DENY through roles, the public role, disabled logins).

How attackers use it

SQL Server is everywhere, its sysadmins are rarely treated as Tier Zero, and xp_cmdshell is one sp_configure away for a sysadmin. A service account in Domain Admins turns "DBA on a reporting server" into "Domain Admin" (T1505.001, SQL Stored Procedures; T1078.002, Domain Accounts). The service account's password is also Kerberoastable through its MSSQLSvc SPN (PW-006).

Find it with Pathwarden

Data needed: MSSQLHound's OpenGraph output, read with its built-in mapping pack*. That pack is untrusted until you trust it (trust = ["mssqlhound"] under [opengraph] in pathwarden.toml, or on the app's Mappings page); until then its data is context only. See the OpenGraph guide.

In the web UI or the HTML report, open the Findings tab and expand PW-034: each finding shows who can use it (its exposure), the attack path drawn out, the affected objects, and the fix. The remediation path tells you whether a single plan step closes it. On the command line:

Shell
# every finding of this rule, with its path and fix
pathwarden findings -i .\collect --rule PW-034
# the step-by-step guide on this page, offline
pathwarden guide PW-034
# after the fix: collect again, then check it is gone
pathwarden retest -i .\collect-after --rule PW-034

Exit codes make retest easy to script: 0 Fixed, 1 Still open, 3 Can't tell. See findings lifecycle and retest.

Before you change anything

  • Confirm the service account in SQL Server Configuration Manager or with SELECT servicename, service_account FROM sys.dm_server_services.
  • Find out why it runs as that account: usually a linked server, a backup share or an old installer default. List what the instance reaches with it (backup paths, linked servers, SSIS packages, Agent jobs).
  • Plan a service restart window.

How to fix it

  • Change the service account with SQL Server Configuration Manager (not services.msc), to a group managed service account or the default virtual account NT SERVICE\MSSQLSERVER.
  • Grant the new account only what the instance needs (the backup share, the remote resources), then remove the old account from Tier Zero groups and rotate its password.
  • Move the MSSQLSvc SPNs to the new account (Configuration Manager does it for virtual accounts and gMSAs).

Option B: Treat the instance as Tier Zero

If it must keep the account, the instance is Tier Zero: remove sysadmin, CONTROL SERVER and IMPERSONATE ANY LOGIN from every login outside Tier Zero, limit the local administrators of its computer to Tier Zero admins, and add the computer under Additional Tier Zero in Settings.

T-SQL and PowerShell

SQL
-- Who controls the instance
SELECT r.name AS role, m.name AS member, m.is_disabled
FROM sys.server_role_members rm
JOIN sys.server_principals r ON r.principal_id = rm.role_principal_id
JOIN sys.server_principals m ON m.principal_id = rm.member_principal_id
WHERE r.name IN ('sysadmin', 'securityadmin');
SELECT pr.name, pe.permission_name, pe.state_desc
FROM sys.server_permissions pe JOIN sys.server_principals pr ON pr.principal_id = pe.grantee_principal_id
WHERE pe.permission_name IN ('CONTROL SERVER', 'IMPERSONATE ANY LOGIN');

-- Remove a login from sysadmin
ALTER SERVER ROLE sysadmin DROP MEMBER [<Login>];
PowerShell
# Create a gMSA for the instance
New-ADServiceAccount -Name "<gMSA>" -DNSHostName "<gMSA>.<Domain>" -PrincipalsAllowedToRetrieveManagedPassword "<SqlComputer>$"
Install-ADServiceAccount -Identity "<gMSA>"   # on the SQL Server computer

Verify the fix

Collect again with MSSQLHound and its coverage file, then analyze the new collection. The finding is fixed when the instance no longer runs as a Tier Zero account (or the account left Tier Zero). Without a coverage file it stays open as "can't tell".

Roll back

Set the previous service account again in SQL Server Configuration Manager and restart the service. Do not restore a Tier Zero account's old password.

References

  1. Microsoft: Configure Windows service accounts and permissions (SQL Server)learn.microsoft.com
  2. Microsoft: Group Managed Service Accounts overviewlearn.microsoft.com
  3. MSSQLHound (SpecterOps)github.com
  4. SpecterOps: Adding MSSQL to BloodHound with OpenGraphspecterops.io
  5. Microsoft: xp_cmdshell (Transact-SQL)learn.microsoft.com
  6. MITRE ATT&CK T1505.001: Server Software Component: SQL Stored Proceduresattack.mitre.org
  7. MITRE ATT&CK T1078.002: Valid Accounts: Domain Accountsattack.mitre.org

Very new and undergoing testing. These features haven't received a lot of testing yet. Try them out and let us know what's working.

↑↓ to moveEnter to openEsc to close