webug4.0 宽字节注入

防止sql手工注入

在php+mysql中, 可以通过转义特殊字符来防止污染sql语句(防注入),

有两种情况:

  1. 魔术引号, magic_quote_gpc 开关,不过高版本的PHP将去除这个特性
  2. 安全函数, addslashes,mysql_real_escape_string,mysql_escape_string等。

 

宽字节注入

上有计策下有对策, 当程序员设置数据库编码与php编码为不同的两种编码,那么就可能产生宽字节注入, 也称GBK双字节绕过。

也可以采用编码绕过。

 

涉及的基本概念

 

  • 字符、字符集 

字符(character)是组成字符集(character set)的基本单位。对字符赋予一个数值(encoding)来确定这个字符在该字符集中的位置。

  • UTF8 

由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。

  • 宽字节 

GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将两个ascii字符误认为是一个宽字节字符。
 

 

1. 引发原因

php编码为utf-8, 而mysql的编码设置为set  names 'gbk'或set character_set_client=gbk,php中编码为gbk,函数执行添加的是

ascii编码,mysql默认字符集是gbk等宽字节字符集。

这样配置会引发编码转换从而导致的注入漏洞(一个gbk编码汉字,占用2个字节,一个utf-8编码的汉字,占用3个字节)

 

2. 注入原理

注入原理很简单, 就是编码, 一点一点分析:

假设一个url有注入, 但是有安全函数, 我们敲单引号会被过滤,那么怎么办呢?这时候就利用GBK双字节注入

我们在后边这么构造url一个尝试:

http://www.****.com/index.php?id=1%df' and 1=1

其中,

%df '  经过安全函数之后在 ' 之前会被加上一个转义符号'\', 即:  %df \'

由于采用的是url编码, 最后转化为:

%df%5c%27

关键就在这,%df会吃掉%5c,形成一个新的字节, 形象一点就是%df遇到%5c会把%5c吃掉,形成%df%5c,这个编码经过代码

解码后会形成一个汉字“誠”

还不明白? 没关系, 举一个简单的栗子:

xi'an (西安) ==>  xian(先) 

值得一提的是, 并不是唯一的使用%df, 只要编码超过ascii码(128)之后, 可以自己组合。只要是汉字就都可以使用

总的来解释一下,

因为%df的关系,\的编码%5c被吃掉了,也就失去了转义的效果,即安全函数丧失了作用, 被直接带入到mysql中,然后mysql在解读时无视了%df%5c形成的新字节,那么单引号便重新发挥了效果, 就可以构造注入了。

 

3. 实战

话不多说, 直接实战webug4.0 宽字符注入:

webug4.0 宽字节注入_第1张图片

 

1)  尝试旧方法, 发现不管输入单引号还是整数型都无效, 于是初步判断有安全函数

2)  尝试宽字符注入:

webug4.0 宽字节注入_第2张图片

可以看到, %df与转义符结合形成一个汉字(乱码), 然后构造的单引号重新发挥了作用, 注入漏洞就因此产生。

最后我们再在url最后加一个注释符, 将php代码中的字符串引号注释掉:

webug4.0 宽字节注入_第3张图片

最终确认为宽字符注入型

3)  下面就是之前的常规操作了

  • 爆字段数

        构造url:  http://localhost:32768/control/sqlinject/width_byte_injection.php?id=1%df%27%20order%20by%203%23

     

      再输入2正常页面, 得出字段数为2

  • 同理可以爆数据库: 

       webug4.0 宽字节注入_第4张图片

      恩, 挺不错的, 宽字节注入的题, 关于数据库也是相同的名字

  • 爆表

果然, 引号还是会被安全函数转义, 这里采用编码绕过:

webug_width_byte 对应的十六进制编码:  0x77656275675f77696474685f62797465

             webug4.0 宽字节注入_第5张图片

猜测数据在sqlinjection下

  • 爆字段+爆数据

       最终发现数据不在webug_width_byte数据库中....哭晕...

       还是老老实实爆webug那个数据库吧......应该还是在env_list那个表中..

       webug4.0 宽字节注入_第6张图片

值得一提的是,  1)  记得要用数据库.表来引用目标表, 因为不确定当前数据库下也有相同的表名,

                         2)  通过前面的几道题, 发现了第几题的数据在对应题号的id中。

 

4. 安全应对方案

对于宽字节编码,有一种最好的修补就是:

(1)使用mysql_set_charset(GBK)指定字符集

(2)使用mysql_real_escape_string进行转义

原理是,mysql_real_escape_string与addslashes的不同之处在于其会考虑当前设置的字符集,不会出现前面%df和%5c拼接为一个宽字节的问题,但是这个“当前字符集”如何确定呢?

就是使用mysql_set_charset进行指定。

上述的两个条件是“与”运算的关系,少一条都不行。

 

参考: 

  • SQL注入:宽字节注入(GBK双字节绕过)
  • SQL注入教程——(四)宽字节注入

你可能感兴趣的:(Webug4.0)