二階SQL注入漏洞

2022-06-28 22:27:18 字數 2880 閱讀 8658

大家通常談論的sql注入都是一階sql注入漏洞,但是還有一種二階sql注入,原理跟一階sql注入相同,只是稍加複雜,而且更加難以發現,難以利用,今天我們來分析一下二階sql注入漏洞。

首先,要明白一階sql注入漏洞是在單個http請求響應中觸發的,而二階sql注入漏洞則需要兩個http請求響應,第一次http請求是精心構造的,為第二次http請求觸發漏洞做準備。

在第乙個http請求中,攻擊者構造髒資料(帶有單引號或注釋符)儲存到資料庫中。

在第二個http請求中,攻擊者直接從資料庫中讀取髒資料,沒有執行進一步的校驗和處理就拼接到下一次sql查詢中,從而造成二階sql注入漏洞。

其實,歸根結底還是乙個信任問題。開發人員信任了從資料庫中來的資料,而沒有進行處理和淨化。

網上有張圖對二次注入解釋的比較清楚,在這裡引用一下:

關於轉義函式,我們需要重點關注:addslashes(),mysql_escape_string()和mysql_real_escape_string()。這幾個函式,在引數插入資料庫時會對特殊字元進行轉義,但是儲存在資料庫中時還是原始格式內容。

sqlilab中的第二十四關,考察的知識點是二次sql注入,我們來分析一下這個漏洞和其中的**:

登入的位置我們可以嘗試是否存在sql注入,嘗試幾次後發現行不通,無論輸入什麼sql注入語句,都是無異常,如下圖:

看了原始碼才知道,這裡輸入的使用者名稱和密碼都經過了mysql_real_escape_string()這個函式的處理。

查一下這個函式,它會對sql語句中的某些特殊字元進行轉義:

使用了這個函式,基本上注入是不太可能了。

如果仔細看的話,在登入頁面下面還有兩個功能,乙個是忘記密碼,乙個是註冊新使用者。我們先註冊乙個venus使用者,密碼為111111,然後使用這個使用者登入,登入成功介面如下:

登入之後,是乙個讓我們修改密碼的功能。

我們看一下修改密碼的原始碼並分析其中的邏輯

可以看到$username是直接從session中獲取的,並沒有進行轉義操作,而其他的幾個變數如$curr_pass和$pass都已經經過mysql_real_escape_string函式處理。問題就出在$username這個引數上,session中的username是從資料庫中獲取到的。

而在這個例子中,我們可以通過註冊賬號往資料庫中寫入帶有特殊字元的username,我們先看看註冊使用者的後台處理**:

註冊使用者時,使用了mysql_escape_string()函式,前面提到過,這個函式會對特殊字元進行轉義,但最終儲存到資料庫時還是保留了原始格式,我們可以註冊乙個venus』#使用者來驗證一下,密碼是123123,註冊完成登入:

註冊成功之後,我們去資料庫中檢視下當前的使用者名稱和密碼:

前面的是系統內建的使用者,15和16是我們剛才註冊的使用者。

ok,現在我們來修改venus』#的密碼,然後再看看修改密碼的sql語句,這裡我們將密碼改為123456。原始碼裡的sql語句如下:

將使用者名稱拼接到sql語句中之後,sql語句就成為了如下所示:

update users set password='123456' where username='venus』#' and password='$curr_pass'

由於#號注釋掉了後面的語句,所以,我們本來是修改的venus』#的密碼,但實際上修改了venus的密碼,而且venus』#的當前密碼也可以隨便輸入。

現在我們再來看看資料庫中venus使用者的密碼:

發現venus的密碼改變了,而venus』#的密碼沒有變化。

我們現在用剛才修改的密碼123456去登入venus這個使用者

登入成功。

這就是典型的二次sql注入漏洞。

二階sql注入防禦

防禦sql注入最有效的方法還是預編譯,盡量避免使用sql語句拼接。

如果使用了sql語句拼接,要對所有拼接到sql語句的引數進行嚴格的淨化和處理。

通過上面的講解和案例分析,相信大家對二階sql注入有了一定的了解。二階sql注入漏洞比一階sql注入更加隱蔽和難以發現,根據二階sql注入形成原因,挖掘的時候應該重點關注資料庫寫入操作,比如建立使用者或者是某個請求中提交精心構造的輸入,然後逐步跟蹤應用程式中可能會使用該輸入的地方,來查詢應用程式是否會有異常。二階sql注入的危害不僅是上文提到的修改管理員賬戶的密碼,根據場景的不同,它的危害跟普通的sql注入一樣。如果在以後的滲透中遇到二階sql注入,會繼續跟大家分享。

1.《sql注入攻擊與防禦第二版》

2.

二階sqli注入

通過對客戶端提交的資料進行嚴格的審查是有效避免sql注入的方法,但是一旦輸入的資料存入到資料庫之後,對這些資料的使用往往沒有做嚴格的檢查,但是對這些資料的操作往往具有很高的許可權,在使用這些資料再進行sql查詢或者sql寫操作的時候,很可能造成嚴重的sql注入,例如 使用者建立了乙個賬戶john 對...

C 二階構造

1.如何判斷建構函式的執行結果?目前無法判斷 2.在建構函式中執行return語句會發生什麼?建構函式直接 返回,執行結束 3.建構函式執行結束是否意味著物件構造成功?不 include class test int geti int getj int status int main return ...

Pocket Cube二階魔方

hdu5983的一道題,看錯了輸入,看了題解發現用一位陣列存比較方便。開兩個24的陣列存完直接暴力交換就完事了,搞了兩個小時,才發現這麼簡單,真是自閉魔方。include using namespace std int a 30 b 30 int isok return1 void cpy intm...