Sqlilabs-Less-32~37&初探宽字节注入


Less-32 Bypass addslashes()


此时我们知道我们输入的id=1’被转义成1';在十六进制中变成315c27;在一般情况下,此处是不存在SQL注入漏洞的,不过有一个特例,就是当数据库的编码为GBK时,可以使用宽字节注入。
查看源码:

这里也介绍一下preg_quote()函数,这个函数的功能为向其中每个正则表达式语法中的字符前增加一个反斜线
原来又是熟悉的preg_replace()函数;preg_replace(要替换的东西,替换成啥东西,哪个里面的东西需要替换)

果然发现了GBK编码;


概念:

单字节字符集: 所有的字符都使用一个字节来表示(ASCII 编码0-127)
多字节字符集: 在多字节字符集中,用多个字节来表示(也有可能一部分用一个字节表示)
宽字符:用多个字节来代表的字符称之为宽字符
字符、字符集 字符(character)是组成字符集(character set)的基本单位。对字符赋予一个数值(encoding)来确定这个字符在该字符集中的位置。
UTF8 由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。
宽字节:GB2312、GBK、GB18030、BIG5、ShiftJIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将两个ascii字符误认为是一个宽字节字符。


原理:

1、宽字节注入是利用mysql的一个特性
2、PHP发送请求到mysql,mysql在使用GBK编码(GBK是宽字节,双字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字的范围)
3、字符和转义的反斜杠组成了新的汉字,但是组成的新汉字又不是一个正常的汉字,就起到了注掉 \ 的作用
4、可以看出来是字符集不一致造成的宽字节注入

1
2
默认情况下:  1' --+ --> 1\' --+ 
注入后: 1%df' --+ --> 1運' --+

思路:
1.%df吃掉 \ 具体的原因是urlencode(‘) = %5c%27,我们在%5c%27前面添加%df,形成%df%5c%27,而上面提到的mysql在GBK编码方式的时候会将两个字节当做一个汉字,此事%df%5c就是一个汉字,%27则作为一个单独的符号在外面,同时也就达到了我们的目的。

而到后续注入的时候还是会用到单引号的地方;此时如果还是用上述方法的时候会发现不行

还记得开头出现的十六进制吗?此时可以尝试对security进行十六进制编码;因为mysql支持十六进制的数值,所以我们这里直接将数据转为16进制即可(0x表示16进制)


Less-32 Bypass addslashes()


又遇到了之前的addslashes()函数:addslashes(string)函数返回在预定义字符之前添加反斜杠\的字符串
绕过方法和上一关一样。


Less-36 Bypass MySQL Real Escape String


mysql_real_escape_string(string):string为需要转义的字符;该函数用于转义SQL语句中的特殊字符串,导致闭合失败等问题,防止SQL注入
绕过方法和上一关一样。


Less-34- POST-Bypass Add SLASHES

这关为POST型注入;我们可以使用bp进行注入攻击;绕过方法与上面相同;不在细讲。


Less-37- POST-MySQL_real_escape_string

这关为POST型注入;我们可以使用bp进行注入攻击;绕过方法与上面相同;不在细讲。

初探宽字节注入

字符和字符集的概念:

在了解宽字节注入的时候我们先来了解一下字符集;字符集:字符是各种文字和符号的统称,包括各个国家文字、标点符号、表情、数字等等。字符集就是一系列字符的集合。
计算机只能存储二进制的数据那英文、汉字、表情等字符应该如何存储呢?我们要将这些字符和二级制的数据一一对应起来比如说字符“a”对应“01100001”反之“01100001”对应“a”。我们将字符对应二进制数据的过程称为”字符编码”反之,二进制数据解析成字符的过程称为“字符解码”。
常见的字符集分类:ASCII和latin1为单字节编码;gbk为双字节编码;UTF-8为一至四字节编码。
宽字节就是两个以上的字节,宽字节注入产生的原因就是各种字符编码的不当操作,使得攻击者可以通过宽字节编码绕过SQL注入防御。通常来说,一个gbk编码汉字,占用2个字节。一个utf-8编码的汉字,占用3个字节。


宽字节注入过程原理:

1.id=%df%27,,先进行addslashes();浏览器执行时会自动url解码一次;%df%5c%27 –> �'
2.转十六进制:�' –> 0xdf0x5c0x27
3.将16进制数转为url编码: 0xdf0x5c0x27 –> %df%5c%27
4.这里以GBK(内部操作字符集)进行url解码,执行sql语句:%df%5c%27 –> 運’


php与mysql的交互流程:

将php的sql语句以character_set_client进行编码(也就是转十六进制);在将16进制数以character_set_connection进行编码(也就是转为url编码),然后在以内部字符集进行url解码;最后以character_set_results编码进行输出。


剖析:

就是因为在通过内部字符集进行url解码时;因为内部字符集的问题,如GBK字符集,在以GBK为编码的mysql中
%df和%5c才可以结合为汉字;这也就导致了宽字节的注入;可以使用%df去吃掉用于防止注入攻击而添加上去的