题目地址: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