1.老规矩,先输入1
2.输入1 or 1,页面提示nonono,说明or已被列入黑名单,通过我们尝试,and,union等等都被列入黑名单。
3.我们来判断参数是否被引号,双引号,括号包裹。
输入1' → 页面回显不正常
输入1'#企图注释掉后面的引号 → 依旧不正常
这说明什么,说明了我们#号后面注释掉了一些东西,使sql语句出了问题,因此就不能够使用注释了(同时我们便可以大胆猜测,这边应该没有包裹,因为既然后面还有重要的语句,源码中的sql语句就不会是简单的select * from flag where id=$_POST['inject'] 这种类型)。
4.我们这时尝试输入1发送,2再发送,再随便打任何一个数字再输入,发现查询到的永远都是
这是我们输入参数后,从而触发了数据库语句所查询的语句,而一直只查询到1。
5.我们用堆叠查询来看看能不能查到数据库和表的信息的吧
1;show databases;//最后加个;是为了与它后面的语句也隔开来。
1;show tables;
里面有一个flag,又想起来刚刚我们一直只查到的1,这涉及到很多人的一个知识盲区(包括我自己)
于是这也就解释了为什么有大佬直接猜出sql语句,select $_POST['inject'] || flag from flag;
因为的话,select 1||flag from flag
select 2||flag from flag
在sql_mode=pipes_as_concat没有执行的前提下查询到的语句都是
因此便有大佬猜测出原sql语句,xmsl这些大佬,成为大佬之路艰苦啊。
6.说到这里,问题便可以解决了,便去构造payload。
利用这个方法的特点,查询flag中的所有信息,后面的不管他反正也没用,select *,1 || flag from flag;
7.看见了官方的wp,顺便整理一下
它的payload是 1;set sql_mode=PIPES_AS_CONCAT;select 1
在执行了set sql_mode=PIPES_AS_CONCAT后,select 1||flag from flag显示的就为select 1 from flag 与select flag from flag的拼接版,翻译PIPES_AS_CONCAT,即将pipes(即||)当做concat连接符来用,然后执行
可以看以下的演示
同样搞出了flag。