当floor报错注入遇到load_file

一个奇怪的特性

切题时遇到的情况, 需要用报错注入 + load_file读取本地文件拿到flag, payload很正常, 直接用updatexml(1,concat(0x7e,load_file('/tmp/1.txt')),1) 但是updatexml和extractvalue有一个限制, 就是只能报错出32个字符, 去掉开头的0x7e只有31个字符, 要找到特定的flag需要一直substr, 于是考虑能否用floor来报错出更多的内容, 但是这里遇到了问题, 用floor来报错load_file没有成功

本地搭建一个环境, 启动mysqld的时候加入--secure-file-priv=/tmp来使得mysql可以读取/tmp下的文件, 其中/tmp/1.txt的内容为hello world

假设一个这样的语句:select id, title from articles where id=1 1处是注入点, 不能用union, 使用updatexml后的语句如下:

成功得到了 /tmp/1.txt 内的内容

来试试floor的payload:

报的错是子查询返回多于一列, 也就是说, 子查询成功返回了数据

把子查询单独拉出来, 与能成功的payload进行对比:

看到使用load_file的查询语句没有报错, 成功返回了数据

要解决这个问题, 需要知道 1. floor报错的原理 2.load_file和一般查询函数取出的数据的不同点

首先看floor报错的原理, 很多人都分析过:

Mysql报错注入原理分析(count()、rand()、group by)

Mysql报错注入原理

这里我简单说一下我的理解: 首先, mysql在处理 select count(*) from t group by x的时候会创建一个虚表, 其中两个列为key和count, 接着一个一个取出t中的数据, 如果取出的数据中x列的数据不存在虚表的key列中, 则执行一个插入语句, 把x列的数据插入虚表中, 反之, 如果x列的数据已经在虚表中, 则更新虚表中对应的count加1, 如果group by有rand存在, 则有可能会在插入虚表的时候出现冲突, 从而报错