前言:
今天看一本PHP书籍的时候,看到里面提到了数据库的字符集,让我想到了宽字节注入,自己好像对此也是一知半解。查了点资料,特此做个笔记。
产生注入原因:
宽字节注入,相信大家都知道是什么东西,利用GBK编码的问题通过%df把\给吃掉,从而使'逃离出来,这里说得是gbk,但并不一定就只 有gbk,只要字符通过转码,就有可能出现这类问题。
那么gbk转码到底是从哪里来的呢?
我们看下这张图,原来就是从client到connection这里,会有一个gbk转码
再看下下面的代码,来个案例
<?php //连接数据库部分,注意使用了gbk编码 $conn = mysql_connect('localhost', 'root', 'root') or die('bad!'); mysql_query("SET NAMES 'gbk'"); mysql_select_db('test', $conn) OR emMsg("连接数据库失败,未找到您填写的数据库"); //执行sql语句 $uid = isset($_GET['uid']) ? addslashes($_GET['uid']) : 1; echo addslashes($_GET['uid'])."<br>"; $sql = "SELECT * FROM admin WHERE uid='{$uid}'"; echo $sql."<br>"; $result = mysql_query($sql, $conn) or die(mysql_error()); ?> <!DOCTYPE html> <html> <head> <meta charset="gbk" /> <title>新闻</title> </head> <body> <?php $row = mysql_fetch_array($result, MYSQL_ASSOC); echo "<h2>{$row['name']}</h2><p>{$row['uid']}<p>\n"; mysql_free_result($result); ?> </body> </html>
首先set names gbk 等同于character_set_client=gbk,character_set_connection=gbk,character_set_results=gbk
然后我们看下代码,对GET来的uid先addslashes过滤一下,然后执行到数据库,我们注意,在这里set names gbk就起作用了,在传输到数据库的时候,会把代码gbk编码一下,就是在这里产生了注入,当我们输入%df'
经过addslashes变成%df\',然后gbk编码,%df\会变成一个汉字,从而使'逃逸出来,产生了注入
理解:
1:少用iconv,可能产生编码问题
2:用mysql_set_charset代替set names,因为mysql_set-charset会修改mysql->charset为设定的字符集
3:用mysql_real_escape_string()代替addslashes,因为前者会根据当前字符集进行过滤
参考地址:
http://www.freebuf.com/articles/web/31537.html
http://www.laruence.com/2008/01/05/12.html