1、二次編碼注入原理
+,=,&,;
http
eg:
name=admin=
name=admin&
一般情況下,通過web瀏覽器提交的數據,php代碼會自動將其編碼回來,如admin%3d會變為admin=
不同的腳本語言對編碼的處理方式不同
php:urldecode() %3d-->=
寬字節注入和二次編碼注入:
都是在面對PHP代碼或配置,對輸入的單引號進行轉義的時候,在處理用戶輸入數據時存在問題,可以繞過轉義。
寬字節注入:
GBK編碼處理編碼的過程存在問題,可構造數據消除反斜杠\
二次編碼注入:
urldecode()與PHP本身處理編碼時,兩者配合失誤,可構造數據消除\
正常處理流程
| 用戶輸入 | PHP自身編碼 | 轉義 | 帶入SQL | 結果 |
|---|---|---|---|---|
| id=1%27 | id=1' | id=1\‘ | id=1\’ and | 不能注入 |
等函數,放在了一個比較尷尬的位置,與PHP自身編碼配合失誤。
| 用戶輸入 | PHP自身編碼 | 轉義 | 函數編碼 | 帶入SQL | 結果 |
|---|---|---|---|---|---|
| id=1%2527 | id=1%27 | id=1%27 | id=1' | id=1' and | 可注入 |
%25 轉換之后為 %
%25進行了編碼轉換,所以%27不會再進行編碼轉換。
PHP自身編碼處由於是%27,並沒有單引號出現,所以不會觸發單引號轉義。
而當在不恰當的時候代碼中使用函數進行編碼轉換,就會將%27還原為單引號,即可造成SQL注入
常規注入:
用戶輸入【1%27】=>php自身編碼【1’】=>php檢查到單引號,觸發函數,進行轉義【1\’】=>帶入sql語句【select * from users where ID=’1\’’】=>不能注入
二次編碼注入:
用戶輸入【1%2527】=>php自身編碼,%25轉換成%【1%27】=>php未檢查到單引號,不轉義【1%27】=>遇到一個函數編碼,使代碼進行編碼轉換【1’】=>帶入sql語句=>能注入
關鍵:編碼函數的位置,必須在轉義函數之后,帶入sql語句之前,sql語句中%27並不會轉換成單引號,如圖

2、二次編碼注入方法
doublecode.php
將該代碼放在sqli-libs目錄下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>二次編碼注入</title>
</head>
<body bgcolor="#000000">
<div style=" margin-top:70px;color:#FFF; font-size:23px; text-align:center">Welcome <font color="#FF0000"> Dhakkan </font><br>
<font size="3" color="#FFFF00">
<?php
//including the Mysql connect parameters.
include("../sql-connections/sql-connect.php");
error_reporting(0);
// take the variables
if(isset($_GET['id']))
{
$id = mysql_real_escape_string($_GET['id']);
echo 'mysql_real_escape_string:'.$id.'<br />';
$id = urldecode($id);
echo 'urldecode:'.$id.'<br />';
//logging the connection parameters to a file for analysis.
$fp=fopen('result.txt','a');
fwrite($fp,'ID:'.$id."\n");
fclose($fp);
// connectivity
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
$result=mysql_query($sql);
$row = mysql_fetch_array($result);
if($row)
{
echo "<font size='5' color= '#99FF00'>";
echo 'Your Login name:'. $row['username'];
echo "<br>";
echo 'Your Password:' .$row['password'];
echo "</font>";
}
else
{
echo '<font color= "#FFFF00">';
print_r(mysql_error());
echo "</font>";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
</font> </div></br></