BUUCTF [SUCTF 2019]EasySQL
知识点:
使用下面的命令可以将
||这个符号转换为concat函数set sql_mode=PIPES_AS_CONCAT
select后面接的内容都是表达式!!!(重要)
- 比如 select 1 or name表示将1 or name作为列名,他的值是1或上name字段的值
sql注入的时候,不仅可能发生在where后面的条件处,还有可能在select之后!
比如:
- 注入发生在where之后, select * from table1 where id=$_POST['q'], 这个时候注入就发生在where之后
- 发生在select之后, select $_POST['q']||flag from Flag, 这个时候就是发生在select之后(本题就是)
题目描述
题目就是一个提交框,输入内容,然后post发送给服务器。

初步尝试
我通过下面的操作,依次在#后面添加我想使用的字符串,初步探测出下面的被过滤以及没被过滤的字符串,如下图:
-
被过滤
union、from、flag、handler、sleep、prepare、" -
没被过滤的
select、*、#、show、tables、

用户是root,这个时候可以考虑使用load_file函数,但是这里不知道路径,所以没办法;

查看题解
题解说后端的sql语句可能是这个$sql = "select ".$post['query']."||flag from Flag";
方法一
还记得前面说得,select后面是表达式吗,如果我们提交的数据是*,1,那么查询语句就是select *,1||flag from Flag,这里的1||flag会被当作新的一列,他的值为1或上flag这一列的值。由于1或任何值都为真,所以返回真(这里输出1)!如下图所示:

但是我还是没理解,为什么当我输入*,'abc'不返回任何值,按照我的理解'abc'是字符串的字面量,它或上flag字段的值应该为'abc'。**希望懂的大佬解答下!!!**如下图:
****
方法二
使用set sql_mode=pipes_as_concat将||运算符变为concat函数。
- 依然将select后面的内容理解为表达式,就是出现一个新的字段,名称是concat(1,flag)。
在线的例子如下:

-
本体构造的表达式
1;set sql_mode=pipes_as_concat;select 1, 也就是select concat(1,flag) from Flag, 其输出的内容如下:
