二次编码注入
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代码中使用了urldecode()等函数,放在了一个比较尴尬的位置,与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