0


BUUCTF [SUCTF 2019]EasySQL1 writeup(详细版)

考点:堆叠注入,MySQL和mssql中||运算符的区别,运算符的意义转换(操作符重置,短路算法

打开靶机,尝试输入1查看回显:

可以看到表格回显了内容:1,用其他非0数字尝试全都回显1,那我们换个数字尝试,比如0:

什么都没有。用字母同理无回显。

使用Sql堆叠注入查看信息,先用show指令查看数据库:1;show databases;

再查看一下表:1;show tables;

看到Flag表,猜测flag应该在Flag中。但是用1;show columns from Flag;无法回显出flag只会回显Nonono. -->说明flag被过滤掉了(注:1;show columns from用来查询表中列名称)

接下来回顾一下最开始我们输入的非0数字和0与字母所回显的内容:非0数字回显1,0和字母不会回显任何内容

先了解一下||操作符:在MySQL中,操作符||表示“或”逻辑:

command1 || command2
c1和c2其中一侧为1则取1,否则取0

这里猜测后端语句,因为只有当我们输入非零数字时才会会显出1,而0和其他全都无回显,(这里很多大佬去查看的源码看到了||的使用,但我太拉跨,,实在找不到源码orz,,)而猜测逻辑大致是这样的:大胆猜测后端(内部查询语句)语句中有||操作符,只有我们输入非零数字才会满足||的逻辑为True从而进行回显的条件。也就是满足:select 输入的内容 || 一个列名 from 表名。(select 输入数据 || flag from Flag)

注:select语句用于从数据库中选取数据,返回的数据会储存在结果表中。

所以接下来搞清楚逻辑后,我们了解一下mssql中的||操作符意义:

mssql中||表示连接操作符,不表示或的逻辑。

从这里可以找到解题方法:既然我们要找到flag,后端又存在“或” 的逻辑,那么只需要把||或的逻辑改成连接符的作用就可以了。

这里需要借用到:设置** sql_mode=PIPES_AS_CONCAT**来转换操作符的作用。(sql_mode设置)

利用PIPES_AS_CONCAT令||起到连接符的作用。

构建payload:

1;set sql_mode=PIPES_AS_CONCAT;select 1

注:这里的逻辑是先把||转换为连接操作符,注意分号隔断了前面的命令,所以要再次添加select来进行查询,这里把1换成其他非零数字也一样会回显flag

由此回显出flag

法2:

构建payload:

*,1

直接得到flag

已知后端语句是select 输入内容 || flag from Flag,输入*,1就相当于构造了select *,1 || flag from Flag,这条语句执行起来相当于select *, 1 from Flag

为啥子咧,因为1||flag是个短路算法,直接输出1了

**select *和select 所有列的意义相同,**那么我们构造的select *,1 || flag from Flag ==select *,1 from Flag

拓展:

PIPES_AS_CONCAT:将”||”视为字符串的连接操作符而非或运算符,这和Oracle数据库是一样的,也和字符串的拼接函数Concat相类似.

SELECT * 和 SELECT 所有列,两者差别几乎可忽略。所以查询所有字段(或者大多数字段)的时候,可以用select *来操作。

短路算法:

|| 逻辑或的短路:a||b

计算机发现a是真,那么输出a;如果a是假,那么输出b

0 || 12 -->12 前面假,输出后面

23 || 0 -->23 前面真,输出前面

select 1 from :建立一个临时列,这个列的所有初始值都被设为1。


本文转载自: https://blog.csdn.net/m0_62851980/article/details/124083026
版权归原作者 今天不用学物理吧 所有, 如有侵权,请联系我们删除。

“BUUCTF [SUCTF 2019]EasySQL1 writeup(详细版)”的评论:

还没有评论