前言
今天看一本PHP书籍的时候,看到里面提到了数据库的字符集,让我想到了宽字节注入,自己好像对此也是一知半解。查了点资料,特此做个笔记。
原因
宽字节注入,相信大家都知道是什么东西,利用GBK编码的问题通过%df
把\
给吃掉,从而使'
逃离出来,这里说得是gbk
,但并不一定就只有gbk
,只要字符通过转码,就有可能出现这类问题。
那么gbk
转码到底是从哪里来的呢?
我们看下这张图,原来就是从client
到connection
这里,会有一个gbk
转码
再看下下面的代码,来个案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| <?php <?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()
代替ddslashes
,因为前者会根据当前字符集进行过滤
参考地址
http://www.freebuf.com/articles/web/31537.html
http://www.91ri.org/8611.html
http://www.laruence.com/2008/01/05/12.html