[SUCTF 2019]EasySQL 1
本题是 EasySQL 但是我感觉一点都不简单 。
我们打开界面发现很像上一关的随便注,但是我尝试了 联合查询 报错注入 布尔盲注 堆叠注入 发现都不能查询到 flag 。仅仅堆叠注入可以查询的 tables 一级。
查询过大佬的博客后发现本题考查的是 sql_mode
sql_mode:是一组mysql支持的基本语法及校验规则
PIPES_AS_CONCAT:将“||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似
当 sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数
当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数并且大佬猜测后端的执行语句为:
select $_GET['query'] || flag from flag
(😓,这可能就是我与大佬的差距吧)
既然知道了后端语句,那么我们也就大概明白了该如何获得 flag
因为在一开始我们没有设置 PIPES_AS_CONCA
所以后端语句的 || 的作用是 或
假如我们输入的是
1
由于我们没有设置 PIPES_AS_CONCA
所以后端执行的语句是
select 1 from flag
先补充一下 select 的用法
select 字段名 from 表名 where 条件
可能有人会好奇为什么select 1 :
select 1在作为子查询中的判断子查询结果是否存在条件时效率较高。select 1 from 中的1是一常量(可以为任意数值),查到的所有行的值都是它。
那么 select 1 from 和 select * from 的区别是什么?
效率上来说,1>anycol>*,因为不用查字典表。
总结:
当不需要知道结果是什么,只需要知道有没有结果的时候,可以使用select 1 作为子查询结果是否存在判断,这样可以提高性能
- select 字段名 from 表名 where 条件
如果我们输入的是
1;set sql_mode=PIPES_AS_CONCAT;select 1
由于已经设置了 PIPES_AS_CONCAT 所以 || 的作用变成了concat连接的作用
后端的查询语句为:
1;set sql_mode=PIPES_AS_CONCAT;select 1 from flag select flag from flag,所以:
我们可以用1;set sql_mode=PIPES_AS_CONCAT;select 1 获得 flag :