一、题目介绍
1、题目来源:
BUUCTF网站,网址:https://buuoj.cn/challenges
2、题目描述:
通过以上信息,拿到flag。
二、解题思路
首先打开靶机,尝试输入1查看回显,回显如图所示:
尝试将 1 和 or 一起输入,即 1 or 1=1。
显示 nonono,表明 or 被过滤了,这时我们就需要检查哪些关键字被过滤掉了,来判断此时应该使用什么注入方式。
首先利用 Burpsuite 进行抓包。
利用关键字字典对query进行爆破。
爆破完成,查看response,Length=560的关键字都是被过滤掉的。
得出最终结论,被过滤的关键字有:
prepare|flag|unhex|xml|drop|create|insert|like|regexp|outfile|readfile|where|from|union|update|delete|if|sleep|extractvalue|updatexml|or|and|&|" 作者:雨落雪辰 https://www.bilibili.com/read/cv11014857/ 出处:bilibili
由此观之,报错注入,union联合注入,盲注皆不可行,所以我们尝试进行堆叠注入。
堆叠注入:将多条SQL语句放在一起,并用分号;隔开。
进行堆叠注入,先尝试查看数据库名称。
成功查询到数据库的名称,这表明堆叠注入是可行的,我们接着顺势查询表明。
看到表Flag,我们基本可以确定,flag在表Flag中。我们首先想到利用from来查询Flag,可是通过抓包分析可知,from关键字被过滤掉了,所以只能另寻他法。
此时我们想到,开始时我们输入1有会显,我们不妨再尝试输入0试试。
输入0发现无回显,我们尝试输入字母试试。
输入abc发现依然没有回显。这时我们可以总结出一条规律,输入非0数字--有会显,输入0或字母--没有回显,我们由此可以猜测后端代码含有 ||或运算符。
补充:|| 或or 运算符讲解:
select command1 || command2
情况一:若command1为非0数字,则结果为1。
情况二:若command1为0或字母,command2为非0数字,则结果为1。
情况三:command1和command2都不为非0数字,则结果为0。
通过以上分析,我们可以判断后端代码中存在或运算符。
查看本题的后端代码,事实与我们的判断相吻合。
$sql = "select ".$post['query']."||flag from Flag";
方法一:使用 sql_mode 中的 PIPES_AS_CONCAT 函数。
PIPES_AS_CONCAT:将 || 或运算符 转换为 连接字符,即将||前后拼接到一起。
select 1 || flag from Flag的意思将变成 先查询1 再查询 flag,而不是查询1flag,只是查询的结果会拼接到一起,不要弄混淆了。
所以查询语句如下:
1;sql_mode=PIPES_AS_CONCAT;select 1
查询结果如下:
1的查询结果为1,被flag的查询结果拼接到了一起,get到flag。
方法二:利用非预期漏洞获取flag。
1、非预期漏洞的概念:
若输入1,1。那么sql语句就变成了 select 1, 1 || flag from Flag。其中由 [1] 和 [1 || flag] 两部分组成,而非 [1,1] || [flag]。非预期漏洞是利用数据库对符号判断的不准确形成的漏洞。
2、如何拿到flag:
输入 *,1 后,sql语句就变成了 select * , 1 || flag from Flag。
其中分为两部分: (1) select * from Flag(2) select 1 || flag from Flag。
select * from Flag 通过查看表Flag中的所有数据可以 get到flag。