0x00 前言
思维定势最不可取。但是在刚学习一些知识和技能时,我们只能生搬硬套或者照葫芦画瓢。
惟有在日后学习时,不断思考所学内容的本质,方能举一反三,妙思频出。
0x01 题目
题目来源:CISCN-2019-华北赛区-Day2-Web-Web1
index.php
很明显,flag应该在当前数据库的flag表的flag列。
抓包看看参数和其他信息:
0x02 尝试
面对sql注入,我首先想的是找到可行的注入方法,换言之,我要知道题目限制了哪些关键字符,该怎么绕过或者采用什么注入方式巧妙避免这些限制。
严格的限制
限制空格
1.本题限制有点严格,我先尝试了1’#
2.单独使用某个字符会回显如下:
3.看起来是组合的错误,那当然要使用空格分开了:
em,空格直接限制了,有以下几种绕过方法:
- /**/
- %09
- %0a %0b %0c %0d
- %a0 (没用成功过)
%09和%0a-%0d都可以,我使用%09。
莫名其妙的限制
What can I say ?
后面采用了ASCII编码,十六进制编码等等,都绕不开过滤,只能通过fuzz找找突破口:
bp再爆破就爆破不出来了,直接给答案吧:
id=(select%091)
0x03 返回值才是本质
正文
许多函数和语句看的都是返回值,不要被其他事物迷惑,从本质(这里是返回值)上思考!
看下图:
细细思考这个payload,妙啊!
斗胆猜一下原型语句:
1 | SELECT passage FROM current_table WHERE ID="$id" limit 1; |
拼接一下payload:
1 | SELECT passage FROM current_table WHERE ID="(select 1)" limit 1; |
小括号返回值是1,所以最终语句是:
1 | SELECT passage FROM current_table WHERE ID="1" limit 1; |
我尝试了那么多次,联合注入、报错注入、布尔盲注等等都不行。
可是这里也是一个布尔盲注,这不禁让我思考布尔盲注适用的条件是什么:在回显单一时,可以使用布尔盲注。
这种情况不是很明显的回显单一,但是有趣的正是这点:
布尔盲注适应回显单一的情况(只需要是和否的回显就可以),但是本题的输入可能是单一的,所以不妨让布尔盲注的结果作为输入,让是为id=1的passage,否为id=2的passage,巧妙地利用IF语句实现盲注!举个例子:
id=(SELECT IF(ASCII(SUBSTRING(flag, 1, 1)) > 1, 1, 2) AS result FROM flag)
如此再写脚本即可:
1 | import requests |
附问
写脚本时:data = f"id={payload}"
写成了:data ={'id':payload}
,导致payload被URL编码了一次后没解码。不过当我使用后者时本身就是错误的,所以先不细究(没思路)。
0x04 小结
多尝试,多思考,多看到本质!