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." "; echo "$sql:".$sql." "; 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合成一个汉字的问题
- 上一篇: vue组件属性中字符串如何拼接变量?
- 下一篇: PHP、HTML单引号、双引号转义以及…