CTF_[SUCTF 2019]EasySQL
本文最后更新于 426 天前,其中的信息可能已经有所发展或是发生改变。

题目地址:https://buuoj.cn/challenges#[SUCTF%202019]EasySQL

启动靶场:

0x01

一个提交按钮,测试了1这个数据,会返回一个Array,结合题目来看,和sql注入有关

看了一眼页面源码,以post方式提交表单

0x02

抓取一下数据包看看:

开始想的话,和sql注入有关的话,它可能会去请求某个和查询有关的页面,以query传参POST方式提交查询

0x03

猜测是不是数字型注入就用联合查询试了一下,1 union select 1

返回Nonono,对键入的值做了过滤处理

0x04 堆叠注入尝试

1;showdatabases;

1;select database();

注入出当前数据库是ctf

1;show tables;(查询当前数据库里的所有表,也就是ctf这个数据库里有一张Flag表,那么flag肯定就在这张表里了

但是想使用1;select flag from Flag;来读出表里的内容却:

可见flag也被过滤了!

0x05

到了这里,看见佬的wp说有经验的师傅可以猜出来后端的查询数据库代码是怎么样的了,但是我没有开发经验呀,我真不知道师傅们怎么猜出来的

原话“这道题目需要我们去对后端语句进行猜测,有点矛盾的地方在于其描述的功能和实际的功能似乎并不相符,通过输入非零数字得到的回显1和输入其余字符得不到回显来判断出内部的查询语句可能存在有||,也就是select 输入的数据||内置的一个列名 from 表名,进一步进行猜测即为select post进去的数据||flag from Flag(含有数据的表名,通过堆叠注入可知),需要注意的是,此时的||起到的作用是or的作用”

第一种是猜出了源码select $_POST[‘query’] || flag from Flag,

sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数

当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数

第一种就按默认没有配置来进行,此时||就是逻辑或

当时这里特别不懂,于是我就在本地数据库创建了一张Flag表来测试

我的本地数据查看了一下sql_mode的配置是:

是没有配置PIPES_AS_CONCAT的,也就是说 || 就是逻辑或,OR函数

$_POST[‘query’]

提交的数据换成*,1(如果直接写的话会被报错,且写在后面会失效)

解释:

sql=select.post[‘query’].“||flag from Flag”;(拼接语句)

如果$post[‘query’]的数据为

*,1

sql语句就变成了select *,1||flag from Flag,

就是select *,1 from Flag,这样就直接查询出了Flag表中的所有内容。

此处的1是临时增加一列,列名为1且这一列的所有值都为1

确实可以查出flag表中的所有信息

但是这里我开始一直不懂,那为什么select * || flag from Flag就不行呢?

GPT的这个解释我想应该很详细了:

在MySQL中,SELECT *, 1 || flag FROM Flag能够正常回显整张表的结果,是因为在这个查询语句中,1 || flag表示将1和flag列中的值进行字符串连接,然后作为一个新的列返回。

然而,当您使用SELECT * || flag FROM Flag时,* || flag表示将所有列的值与flag列中的值进行字符串连接。这种情况下,如果某些列的值不是字符串类型,例如整数或日期类型,MySQL会尝试将其转换为字符串类型进行连接,这可能导致一些不可预料的结果,甚至出错。

另外,即使所有列的值都是字符串类型,使用* || flag进行连接时,每个列的值之间会使用逗号分隔,而不是使用空格或其他分隔符。这可能导致返回的结果不符合预期。

因此,如果您想要连接某个特定列的值与其他列的值,最好明确指定要连接的列,而不是使用*。这样可以确保连接操作只涉及到您想要的列,并且避免潜在的问题。

所以使用payload:*,1就可以直接查询出flag

2)第二种是将||作为字符串连接符,因此需要在语句中更改其配置

sql_mode=PIPES_AS_CONCAT时即可

Payload:1;set sql_mode=PIPES_AS_CONCAT;select 1

拼接完之后:select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag

相当于是select 1 from Flag和select flag from Flag

在本地数据库做上述一样的设置后,确实能把flag{a}查询出来

1;set sql_mode=PIPES_AS_CONCAT;select 1

文末附加内容
暂无评论

发送评论 编辑评论


				
上一篇
下一篇