0x0 原理
針對場景:
存在另一處操作直接調用輸入數據而不做其他處理
關鍵:【尋找另一處引用這個數據的操作】如果另一處操作直接將1’作為變量帶進自身的sql語句中,且未做如轉義等處理,那1’的單引號便會發生作用,起到sql注入的效果
0x11 演示
以sqlilabs 24關為例
先點擊forget your pass?出來如下頁面,看來是提示我們通過注入修改密碼
注冊一個新用戶,用戶名admin4‘#,密碼4444
注冊成功
這時候看數據庫,提前留意下admin4的密碼
以剛注冊的用戶登陸
修改密碼為4111
再看回數據庫
會發現被修改密碼的是admin4,而不是我們登陸的admin4’#,這就是二次注入
0x12解析
以24關的代碼為例
回憶我們剛剛的操作,注冊admin4’#,修改admin4’#密碼,發現admin4的密碼被修改
重點在admin4’#的修改密碼操作
對應代碼在pass_change.php
可以看到,執行的sql語句為
$sql= ”UPDATE users SET PASSWORD = ‘$pass’ where username = ‘$username’ and password = ‘$curr_pass’ ”;
當我們以admin4’#的用戶修改原密碼4444為新密碼4111時,執行的對應sql語句就為
$sql= ”UPDATE users SET PASSWORD = ‘4111’ where username = ‘admin4’#’ and password = ‘4444’”;
這條語句實際執行時產生的效果相當於
$sql= ”UPDATE users SET PASSWORD = ‘4111’ where username = ‘admin4’;
也就是修改用戶admin4的密碼為4111,也就造成了二次注入
0x2 防御
24關其實在注冊,登陸,修改密碼的數據帶入sql語句前都用了mysql_real_escape_string對特殊字符進行轉義,但修改密碼中, sql語句中的$username是直接通過$_SESSION["username"]從數據庫中提取的,這個變量並未進行處理就被帶入sql語句中執行了,進而導致單引號發揮作用,造成注入。
防止二次注入,要么禁止輸入數據庫的變量中存在非法字符,如果必須要有字符,在數據出庫后,也要做好處理
數據的輸入輸出都要有處理