原理:
二次注入需要具備的兩個條件:
(1)用戶向數據庫插入惡意語句(即使后端代碼對語句進行了轉義,如mysql_escape_string、mysql_real_escape_string轉義)
(2)數據庫對自己存儲的數據非常放心,直接取出惡意數據給用戶
舉例:
(1)在sqli_libs的第24關,其頁面如下所示:
(2)當我們點擊Forgot your password?時,出現提示:
(3)因此可以嘗試在注冊頁面進行二次注入,首先,我們注冊一個賬號,名為:admin'# ,密碼為:123456
(4)注冊成功,嘗試登錄admin‘# ,然后可以查看一下phpmyadmin內存儲情況
(5)而這時的admin原密碼是admin,並且兩個賬號都存儲在數據庫內的。當我們重新修改admin'#的密碼的時候,這里修改為:12345678;可以發現二次注入的威力所在。admin的密碼被修改為了:12345678;而admin'#用戶的密碼並沒有發生變化。
(6)代碼審計,嘗試分析源碼,出現問題的頁面很顯然是注冊頁面,與密碼修改重置的頁面。
注冊用戶時:
僅對特殊字符進行了轉義,判斷輸入兩次密碼是否一致,然后將用戶鍵入,將數據插入至數據庫。
$sql = "insert into users ( username, password) values(\"$username\", \"$pass\")"
這里直接插入了數據
修改密碼時:
$username= $_SESSION["username"];//直接取出了數據庫的數據
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";//對該用戶的密碼進行更新
$sql = "UPDATE users SET PASSWORD='12345678' where username='admin‘#
執行成功!
防御:
(1)對外部提交數據謹慎
(2)從數據庫取數據時,不能輕易相信查詢出的數據,要做到同樣的轉義或是甄別