前言
該文章主要描述了addslashes()函數常見的編碼繞過的情況
2020-01-07
天象獨行
函數addslashes()作用是返回在預定義字符之前添加反斜杠的字符串。預定義字符是單引號(')雙引號(")反斜杠(\)NULL。比如下圖,這樣就造成了得結果是我們無法在注入的過程當中使用單引號(’)。在字符行注入的時候是比較頭疼的一件事情。下面我們討論一下一些情況可以繞過addslashes()函數。
測試代碼如下:
1 <!DOCTYPE html> 2 <HTML> 3 <head> 4 <title>過濾函數和類---addslashes()函數</title> 5 6 </head> 7 <body> 8 <p>addslashes() 函數返回在預定義字符之前添加反斜杠的字符串。預定義字符是單引號(')雙引號(")反斜杠(\)NULL</p><br/> 9 <form action="" method="POST"> 10 Username : <input type="test" name = "username"><br/> 11 Password : <input type="Password" name = "password"><br/> 12 <input type="submit" value="Nest"><br/> 13 </from> 14 <?php 15 function deep_addslashes($str) 16 { 17 if(is_array($str)) 18 { 19 foreach($str as $key=>$val) 20 { 21 $str[$key] = deep_addslashes($val); 22 } 23 } 24 else 25 { 26 $str = addslashes($str); 27 } 28 return $str; 29 } 30 $username = $_POST["username"]; 31 $password = $_POST["password"]; 32 if (empty("$username") or empty("$password")) 33 { 34 die("輸入字符不能為空"); 35 } 36 echo '$_POST接收后的username值:'; 37 echo "$username"; 38 echo "<br/>"; 39 //echo $password; 40 $connect_sql = mysqli_connect("127.0.0.1",'root','Password@2019','taodb'); 41 if (mysqli_connect_errno($connect_sql)) 42 { 43 echo "連接數據庫失敗".mysqli_connect_errno; 44 } 45 //mysqli_query($connect_sql,"SET NAMES 'gbk';"); 46 //$username = deep_addslashes("$username"); 47 //$username = urldecode($username); 48 $password = md5($password); 49 $sql = "select user_name,pwd from taodb.blue_user where user_name = '$username' and pwd = '$password';"; 50 echo "查詢語句:"; 51 echo "select user_name,pwd from taodb.blue_user where user_name = '$username' and pwd = '$password';"; 52 echo "<br/>"; 53 $result = mysqli_query($connect_sql,$sql); 54 echo "登陸輸出結果:"; 55 if (mysqli_fetch_row($result)) 56 { 57 echo "成功登陸"; 58 }else 59 { 60 echo "賬號或密碼錯誤"; 61 } 62 mysqli_close($connect_sql); 63 ?> 64 </body> 65 </HTML>
測試代碼驗證:
輸入:‘ or 1=1 # 測試發現存在漏洞
0X01;編碼繞過
很少一部分情況下,字符串在傳入之后,帶入數據庫查詢之前有個編碼解碼操作,然而在沒有解碼之后就沒有對參數進行再一次的過濾。這個時候就存在了繞過addslashes()函數的可能性。
1;url解碼導致addslashes()。下面我們調整一下代碼,加入addslashes()函數以及urldecode()函數處理變量$username。
1 <!DOCTYPE html> 2 <HTML> 3 <head> 4 <title>過濾函數和類---addslashes()函數</title> 5 6 </head> 7 <body> 8 <p>addslashes() 函數返回在預定義字符之前添加反斜杠的字符串。預定義字符是單引號(')雙引號(")反斜杠(\)NULL</p><br/> 9 <form action="" method="POST"> 10 Username : <input type="test" name = "username"><br/> 11 Password : <input type="Password" name = "password"><br/> 12 <input type="submit" value="Nest"><br/> 13 </from> 14 <?php 15 function deep_addslashes($str) 16 { 17 if(is_array($str)) 18 { 19 foreach($str as $key=>$val) 20 { 21 $str[$key] = deep_addslashes($val); 22 } 23 } 24 else 25 { 26 $str = addslashes($str); 27 } 28 return $str; 29 } 30 $username = $_POST["username"]; 31 $password = $_POST["password"]; 32 if (empty("$username") or empty("$password")) 33 { 34 die("輸入字符不能為空"); 35 } 36 echo '$_POST接收后的username值:'; 37 echo "$username"; 38 echo "<br/>"; 39 //echo $password; 40 $connect_sql = mysqli_connect("127.0.0.1",'root','Password@2019','taodb'); 41 if (mysqli_connect_errno($connect_sql)) 42 { 43 echo "連接數據庫失敗".mysqli_connect_errno; 44 } 45 //mysqli_query($connect_sql,"SET NAMES 'gbk';"); 46 $username = deep_addslashes("$username"); 47 $username = urldecode($username); 48 $password = md5($password); 49 $sql = "select user_name,pwd from taodb.blue_user where user_name = '$username' and pwd = '$password';"; 50 echo "查詢語句:"; 51 echo "select user_name,pwd from taodb.blue_user where user_name = '$username' and pwd = '$password';"; 52 echo "<br/>"; 53 $result = mysqli_query($connect_sql,$sql); 54 echo "登陸輸出結果:"; 55 if (mysqli_fetch_row($result)) 56 { 57 echo "成功登陸"; 58 }else 59 { 60 echo "賬號或密碼錯誤"; 61 } 62 mysqli_close($connect_sql); 63 ?> 64 </body> 65 </HTML>
現在我們再次輸入萬能密碼看看’ or 1=1 # 這個時候我們發現已經無法正常注入且單引號被轉義。
將萬能密碼進行url編碼,再次注入:
2;base64解碼繞過
測試代碼當中插入“$username=base64_decode($username);”
編碼萬能密碼:
輸入成功繞過:
2;寬字節注入
造成這種情況是因為數據庫采用的是gbk編碼。核心是一個字符串采用不同的編碼方式,過濾函數認為是安全的,數據庫的編碼方式會造成影響。