SQL注入绕过PHP单引号字符转义原理及预防方法

http://mo47.com/blog/2011/sql_injection_gpc

利用GBK双字节编码,绕过单引号转义

附赠工具一款:PHP汉字url编码转换器

PHP测试代码如下

/* 注入实验:start */
$id = $_GET['id'];
//建立连接
$conn = false;
$conn = mysql_connect("localhost","root","");
mysql_query("set names 'gbk'");
mysql_select_db("test", $conn);  

//执行
$sql = "SELECT id,name FROM table WHERE id = '".$id."' LIMIT 1";
if(!($query = mysql_query($sql,$conn))){
  echo mysql_error();
}
$result = array();
while($row = mysql_fetch_array($query,MYSQL_ASSOC)){
	$result[] = $row;
}

echo '$id:'.$id."\n";
echo '$sql:'.$sql."\n";
print_r($result);
/* 注入实验:end */

常规注入

URL:http://localhost/a.php?id=10%20AND%201=2

SQL:

SELECT downid,name FROM x_downs WHERE projectid = '10 AND 1=2' LIMIT 1

其中由于projectid = ‘$id’被单引号括住了,1=2,1=1暂时失效了

 

绕过去吧

不过我们可以通过汉字双字节编码进行注入

URL:http://localhost/a.php?id=10%D6%20AND%201=2%23

SQL:

SELECT downid,name FROM x_downs WHERE projectid = '10謀' AND 1=2#' LIMIT 1

可以看到在前面加了个%D6后,引号被吃掉了

 

原理

php会针对URL编码进行decode

decode后,url参数为 ?id=10 0xD6 ‘ 0×20 AND 0×20 1=2 0×23

magic_quotes_gpc处理时会自动转义,即在前面加一个\

处理后url参数变成: ?id=10 0xD6 0x5c ‘ 0×20 AND 0×20 1=2 0×23

可以看到,在前面PHP会自动加一个0x5c(注:0x5c为\),也就是会自动转义成\’

由于汉字是双字节的,所以0xD6 0x5c被转为这个汉字,’之前的\就这样消失了

最后的%23#,在sql中#是注释,所以后面的’就没用了

最终sql中projectid = ’10謀’在sql执行的时候,由于projectid为int类型字段,mysql会自动intval()处理一下 详情见这里

所以等效于

SELECT downid,name FROM x_downs WHERE projectid = 10 AND 1=2

达到我们成功注入的目的

 

解决方法

两种

1.对用户的输入信息严格检查和过滤

2.针对本方法,进行如下修改

(1)切勿在连接设置字符集时:set names ‘gbk’

(2)当有类似设置时character_set_connection=gbk, character_set_results=gbk, character_set_client=binary

将character_set_client必须设置为binary

注:主要作用是在传输数据时使用binary的形式,避免了由于php将0xd6和0x5c合成一个汉字的问题


    原文作者:SQL
    原文地址: https://blog.csdn.net/mydriverc2/article/details/42421785
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞