场景
额,因为题目已经说明了是sql注入的题了,看了下那就开始测试呗:
我的思路
探测注入类型
先看是什么类型的输入,是字符型还是数字型,一般就字符的了
好像被挡了,额,是什么关键字嚒?这里有空格,and,=;
模糊测试
这里我运用学到的一个新知识(思路),就是先fuzz(模糊测试)一下,用我准备的关键字密码本测一下:
发现好多关键字都被挡了,包括我的union和sleep,联合注入和时间盲注都寄了,布尔盲注本题不对口,额,这里有一个被我忘记的堆叠注入了(就是用分号连接两个句子)
这里我判断错误了,因为我的样本参数太少了,事实上我忘记了,等价函数替代这回事:
像是sleep()函数被替代了,但是他的等价函数benchmark关键字是没有被拦的:
sleep() ==> benchmark(count,expr) 重复计算expr表达式的count次数,通过这种方式评估出mysql执行这个expr表达式的效率;
(这一块待补充)
堆叠注入补充:
很简单的,但是注入条件十分有限,只有调用数据库的函数支持执行多条语句才能够使用,mysqli_multi_query()函数,大多开发人员不会用这个,往往开发用的是mysqli_query函数,只执行一条语句;
就两条查询语句拿分号一拼接,不用像union一样考虑两边对称 ;
那就试一下咯;经过刚刚的fuzz,select至少是没被拦的,就是没回显;
这个没回显的;换成数字型看看;
得知:
1.前面是没有引号;
2.查看到了这些数据库了;
继续看看tables能不能查到:
看到了这个Flag表格,盲猜flag就在里面了;也可猜得是带入该表格查询,
select 1,*** from ****(?Flag?);
然后我就想执行select * from Flag嘛,em,可是fuzz得到from关键字是被挡的;
(这个时候我的另一个思路就是,能不能用别的函数语句或者关键字给他绕过去;待补充)
师傅们思路
这个时候,参照网上师傅们的思路是:他们通过依次输入1;0;-1;a这四个值,观察得到只有1回显,联想到逻辑符号 || ;
select 1 || **** from (?Flag?);
查看源码猜测后端语句 有||操作符,当我们输入非零数字,才可满足||的逻辑为真进而回显。但要查找flag,后端又有“或”逻辑存在,我们需要将||视作字符串连接符,相当于CONCAT() 函数。因此需要借用sql_mode=PIPES_AS_CONCAT转换操作符,起到连接符的作用。
1)sql_mode 设置了 PIPES_AS_CONCAT 时,|| 就是字符串连接符,相当于CONCAT() 函数
2)当 sql_mode 没有设置 PIPES_AS_CONCAT 时 (默认没有设置),|| 就是逻辑或,相当于OR函数
第一种就按默认没有配置来进行,此时||就是逻辑或
||在命令执行中见过,
回顾:
command1;command2顺序执行
command1 || command2
如果command1执行失败,则执行command2
command1 && command2
如果command1执行成功,则执行command2
第一种解法:
将||作为字符串连接符,因此需要在语句中更改其配置
sql_mode=PIPES_AS_CONCAT时即可
Payload:1;set sql_mode=PIPES_AS_CONCAT;select *(这个不可行)有回显但无Flag表返回值; 即select * from Flag;selct flag from Flag
大佬的Payload是:
Payload:1;set sql_mode=PIPES_AS_CONCAT;select 1
疑惑1:
为什么1可行但是*不可行呢?
拼接完之后:select 1;set sql_mode=PIPES_AS_CONCAT;select 1||flag from Flag
相当于是select 1 from Flag和select flag from Flag
疑惑2:
我怎么确定是管道符||后面就是flag,不是别的什么呢?
第二种解法:
基于已知条件(猜测后端语句 有||操作符)
师傅们猜测后端的指令为select $_POST['query'] || flag from Flag;
(参数query可由F12查看源码)
这里我的疑惑2还没解决;
那我们用Post请求提交Payload为“query=*,1”;
即猜测后端sql语句为:select *,1 || ***** from Flag;
实现select *,1 from Flag执行,select **** from Flag不执行