10-Web安全——SQL注入WAF绕过之宽字节注入

addslashes()函数在指定的预定义字符前添加反斜杠,这些字符是单引号('),双引号("),反斜线(\)与NUL(NULL字符)。例如客户端提交的参数中如果含有单引号,双引号等这些特殊字符,addslashes函数则会在单引号前加反斜线“\”,将单引号转义成没有功能性的字符。

 

举个栗子:

以查询用户名为1’的信息为例,username中的参数为1',MySQL数据库在解析这条SQL语句时,会把1后面的单引号认为是闭合符号要求再输入一个单引号闭合,而不是当做username参数的一部分来处理,从而导致数据库只查询用户名为1的信息,而不是查询1'的信息。

 

在示例中数据库提示我们要求再输入一个单引号,然后输入分号“;”结束SQL语句,查询出来的结果为0,因为users表中确实没有用户名为1的信息。

 

如果想要把单引号作为username参数的一部分的话,可以使用反斜线对单引号进行转义,如下所示:

在单引号前面加一个反斜线后,数据库在解析SQL语句时就会将单引号作为一个普通字符对待,没有特殊含义,也不会把单引号识别为闭合方式,而是作为username参数中的一部分。

 

addslashes函数过滤的作用:当输入闭合符号'时把在'前加上反斜线\转义为普通字符,导致无法闭合。

 

 

在Less-23中源代码中输入?id=1\'进行测试:

发现后台仍然把我们输入的反斜线给转义过滤掉了,页面最终返回的是1\\\',第一个反斜线将第二个反斜线转义了,然后第三个反斜线把单引号给转义了。

 

 

分析Less-32源代码:

function check_addslashes($string)
{
    $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string);                //escape any backslash
    $string = preg_replace('/\'/i', '\\\'', $string);                               //escape single quote with a backslash
    $string = preg_replace('/\"/', "\\\"", $string);                                //escape double quote with a backslash
    return $string;
}

 

从后台的过滤代码中可知,使用这种方式是不可能绕过的,当然addslashes()函数也会有局限性,一般我们会采取的方法:GBK字符编码和网页URL编码两种方式。

 

 

这里主要介绍GBK字符编码绕过:

GBK编码,是在GB2312-80标准基础上的内码扩展规范,使用了双字节编码方案,其编码范围从8140至FEFE(剔除xx7F),共23940个码位,共收录了21003个汉字,完全兼容GB2312-80标准,支持国际标准ISO/IEC10646-1和国家标准GB13000-1中的全部中日韩汉字,并包含了BIG5编码中的所有汉字——(摘自百度百科)。

 

字符反斜线“\” 的ASCII码值是5C,占用一个字节,GBK编码方式可以将反斜线“\”转换为一个服务器数据库不识别的汉字,即在5C前面拼接组合一个字符0xdf,那么数据库就会将0xdf5c转换为一个不识别的汉字,这样数据库就会将其忽略掉。

 

假设当前数据库使用的是GBK编码集,那么数据库会把两个字符识别为一个汉字,所以可以使用一些字符和经过转义后多出来的反斜线“\”组合成两个字符,从而变成数据库不识别的汉字字符,从而破坏对单引号,双引号的转义,使其参数闭合。

 

 

再举个栗子

 

假设当前数据库使用GBK编码集,当,数据库会将输入的参数%df%5c解析为两个字节:

 

其中%df为高位字节,编码位是223;%5c为低位字节,编码位是92;%df%5c的GBK编码取值范围就是:第一个字节是129—254,第二个字节是64—254,数据库会按照GBK编码将%df%5c解析成一个汉字,这样“\”就会失去原来的作用。

在上图中,数据库将参数%df%5c按照GBK编码集解析成上图中的汉字:運,这种方式就是宽字节注入。

 

 

宽字节注入有前提:要求目标MYSQL数据库的编码方式是GBK编码,并且客户端必须和数据库的编码方式一致,这样才能使用宽字节注入方式,宽字节注入过程如下所示:

 

输入参数:?id=1%df' and 1=1 --+,进行测试,结果如下

测试页面返回的结果是:1�\' and 1=1 --。

由于输入的参数中有单引号,后台使用了反斜线对单引号过滤,使得参数实际上替换成了1�\' and 1=1 --,并且数据库会将“�\”字符解析成一个汉字,也就是下图中红色部分,从而绕过WAF。

 

 

后台替换成的SQL语句是这样的:SELECT * FROM users WHERE id='1%df\' and 1=1 --+' LIMIT 0,1,并且该SQL语句可以正常执行:

 

总结:

宽字节注入有个前提:要求目标MYSQL数据库的编码方式是GBK编码,并且客户端必须和数据库的编码方式一致

猜你喜欢

转载自blog.csdn.net/qq_35733751/article/details/106560160