前言
这是我及我所在的团队第一次参加正式
的CTF比赛,所取得的成绩也还算满意,比赛过程中作者负责web
方向,比赛中的成果就是两道77777
。
77777
题目描述:
这道题最坑的就是一开始
没有判断出是否注入成功的依据
,后面经师兄指导才发现依据就是注入的数字是否已经改变,当然这道题的环境官方也说明每个队注入没有隔离开
,造成即使注入成功也可能被别的队刷走,从而影响判断。
又因为它是sptintf("xxx%d%s")
,所以注入应该在str
的地方,也就是在hi
中进行注入,payload:hi=000 where ord(substr(password, 1, 1))>100
,因为是在update users set
中注入,所以这里不需要再使用union,select
等方法了。完整的payload如下图:
如果注入成功,则会返回你的
flag
字段,如:
由于这个题的环境不稳定,不太适合脚本的判断,所以,就手工注入一遍了。
77777 2
这道题跟上一道提供的描述是一样的,不同的是对hi
进行了更严格的过滤,上一道的payload就无效了。
这道题过滤了and or || & &&
(为了不产生二义,这里用空格分隔),但是唯独没有过滤掉|
。所以我们可以选择|
进行位注入
。然后在检测一下,没有被过滤的是:substr select from if
,所以考虑用if
替代where
进行判断。
经过一轮苦逼的测试,终于搞出一个payload:hi=000 | IF (substr((select substr( pw from 1)),1,1)>'z',1,0)
,这里( pw
中间一定要有空格
,不然无法绕过。另一个要说的就是pw from 1
,它会返回pw字段从1开始的所有值
。如:1
2pw = 'flag{123456}'
pw from 1 ---> flag{123456}
payload:
判断的依据是返回的数字的最后一位,如:
如果是返回错误则是如下:
另一个tips就是数字的后一位一定要
0
,不然如果是1
的话就无法判断了。1 |
任何也是真。
再然后就是逐位的判断,有些数字会被过滤掉,这点上不知道是我的payload有问题还是本来就是这样。。。。
如上,逐位比较的时候使用
+1
的方法,如果直接用2,3,4,…的话有些数字会被过滤
,还有就是有些字符也会被过滤,但无关flag字段。附上脚本:
1 | # -*- coding:utf-8 -*- |