-
什么是窄字节和宽字节呢?
当某字符的大小为一个字节时,称其字符为窄字节。
当某字符的大小为两个字节时,称其字符为宽字节。 -
宽字节注入适用于那种情况?
针对'
和\
的过滤
宽字节注入原理
所有英文默认占一个字节,汉字占两个字节
mysql在使用GBK编码时,会认为两个字符为一个汉字,例如%aa%5c
就是一个汉字(前一个ascii码大于128才能到汉字的范围)。我们再过滤'
的时候,往往利用的思路是将'
转化为\'
,因此我们再次想办法将'
前面的\
除掉
%df
之所以能吃掉\
是因为urlencode(\')=%5c%27
,如果我妈在%5c%27
前面添加%df
,成%df%5c%27
,而上面提到mysql在GBK编码方式的时候会将两个字节当作一个汉字,此时的%df%5c
就被识别出一个汉字,而%27
则作为一个单独的'
放在外面。- 将
\'
中的\
过滤掉,例如构造%**%5c%5c%27
的情况,后面的%5c
会被前面的%5c
给注释掉。这一世一种bypass的一种方法。
宽字节注入示例
- 在sqli-labs的Less-32中
上述函数将'
转为\'
,将\
转化为\\
,将"
转化为\"
。因此可以直接添加一个%df
将%5c
吃掉,也可以添加%aa%5c
将\
转义成普通的的反斜杠
payload
Less-32/?id=-1%aa%5c%27union%20select%201,database(),3--+
或者
Less-32/?id=-1%df%27union%20select%201,database(),3--+
-
在sqli-labs的Less-33中
使用了addslashes()
函数返回在预定义字符之前添加反斜杠的字符串
方法还是和之前一样 -
在sqli-labs的Less-34中
是POST型的注入漏洞,同样也是将post过来的内容进行了'\
的处理。 -
因为GET型的方式我们是以url形式提交的,因此数据会让通过URLencode
-
在这里,我们可以将utf-8转化成为utf-16或utf-32,例如将
'
转化为utf-16为�'
,我们就可以利用这个方法
username:�' or 1=1#
password:(随便输)
此时的sql语句为
SELECT username,password FROM users WHERE username='�' or 1=1
防御
再来说说如何防御
- 使用mysql_set_charset(utf8)指定字符集
- 使用mysql_real_escape_string进行转义
- 设置character_set_client=binary