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

echo "\$_SERVER['QUERY_STRING']=".$_SERVER['QUERY_STRING']."
";

echo "\$_GET['id']=".$_GET['id']."
";

?>

(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编码不能绕过单引号转义进行注入。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值