当前位置: 主页 > 日志 > PHP >

利用UTF8字节编码能否绕过PHP单引号转义进行注入?

利用GBK双字节编码可以绕过单引号转义进行注入,这在之前的文章中已经分析过了(《利用GBK双字节编码突破PHP单引号转义限制进行SQL注入》,http://www.redicecn.com/html/wangluoanquan/20101018/180.html)。今天来讨论一下是否能够利用UTF8字节编码绕过转义。

 

先回顾一下GBK编码绕转义的原理:

GBK编码的字节范围是:

首字节:0x81-0xFE

尾字节:0x40-0xFE

而转义符"\",对应的ASCII码为:0x5C 恰好在 GBK的尾字节范围内。 因此当第二字节为0x5C时,只要首字节满足在0x81-0xFE范围内,这两个字节就能够组成一个合法的GBK字符。

(0x81-0xFE)0x5C 例如: 0xD55C => 誠      0XA05C=>燶   0xEE5C => 頫

在进行URL解码时,PHP就会将其转化为相应的GBK字符,从而将转义符"\"吃掉了,达到了绕过转义的目的。

用一个实例说明该过程:
如下测试代码:

// test.php
<meta http-equiv=content-type content="text/html; charset=gb2312">
<?php
echo "\$_SERVER['QUERY_STRING']=<b>".$_SERVER['QUERY_STRING']."</b><br/>";
echo "\$_GET['id']=<b>".$_GET['id']."</b><br/>";
?>

(1)我们在浏览器里访问:http://127.0.0.1/test.php?id=123'

浏览器显示程序输出:

$_SERVER['QUERY_STRING']=id=123%27
$_GET['id']=123\'

第一行是PHP获取的的QueryString集合,即GET方式提交的所有参数集。此时的数据是经浏览器URL编码过的数据。%27是单引号的URL编码值。

第二行是PHP获取到的id参数的值,与QueryString中的值相比较,$_GET数组中的值是经过了两步转换的结果:

第一步,进行URL解码。即123%27 = > 1230x27 。

第二步,当GPC = ON时,进行特殊符号转义,此时将0x27转义为0x5C0x27(在0x27之前插入转义符0x5C)。

即1230x27 =>1230x5C0x27。

因为客户端浏览器采用gb2312编码,所以1230x5C0x27字节序列被当作gb2312字符串理解为:123\'

 

(2)我们在浏览器里访问:http://127.0.0.1/test.php?id=123%d5'

程序输出:

$_SERVER['QUERY_STRING']=id=123%d5%27
$_GET['id']=123誠'

123%d5' ,经浏览器URL编码=>123%d5%27,经URL解码=>1230xD50x27,经PHP单引号转义=>1230xD50x5C0x27。

 

1230xD50x5C0x27字节被当作gb2312字符串理解为:123誠'  (前面已经说过0xD50xDC对应了GBK字符誠),因此浏览器显示了:123誠' 。

同样,如果服务端PHP采用GBk方式连接MySQL数据库,MySQL数据库就会将含有上述字节序列的SQL语句当作gbk字符串理解,这样就吃掉了转义字符"\",达到了绕过转义的效果。

 

 

利用UTF8编码能否绕过单引号转义呢?

 

从上面的分析可以看出,能否绕过,关键在于UTF8最后一个字节范围是否能够包含转义符0x5C,如果包含就能吃掉。

 

下面看一下UTF-8编码表:

U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

 

从表中看出,UTF-8编码字符理论上可以最多到6个字节长。最后一个字节的范围是:

10000000 - 10111111 即 0x80 - 0xBF ,而0x5C 没有在这一范围呢,因此无法利用UTF8编码吃掉转义符\,所以得出的结论是:利用UTF8编码不能绕过单引号转义进行注入。

 

[日志信息]

该日志于 2010-12-03 22:03 由 redice 发表在 redice's Blog ,你除了可以发表评论外,还可以转载 “利用UTF8字节编码能否绕过PHP单引号转义进行注入?” 日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!    (尊重他人劳动,你我共同努力)
   
验证(必填):   点击我更换验证码

redice's Blog  is powered by DedeCms |  Theme by Monkeii.Lee |  网站地图 |  本服务器由西安鲲之鹏网络信息技术有限公司友情提供

返回顶部