Hr-Papers|宽字节注入深度讲解
作者:CQITer小编 时间:2018-03-25 21:25
/*Team:红日安全团队团队成员:CPRTitle:宽字节注入*/
原理介绍基本概概念
宽字节是相对于ascII这样单字节而言的;像GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节
GBK是一种多字符的编码,通常来说,一个gbk编码汉字,占用2个字节。一个utf-8编码的汉字,占用3个字节
转义函数:为了过滤用户输入的一些数据,对特殊的字符加上反斜杠“\”进行转义;Mysql中转义的函数addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种是配置magic_quote_gpc,不过PHP高版本已经移除此功能
宽字节注入
先了解下SQL的执行过程:
1.以php客户端为例,使用者输入数据后,会通过php的默认编码生成sql语句发送给服务器。
在php没有开启default_charset编码时,php的默认编码为空

此时php会根据数据库中的编码自动来确定使用那种编码,可以使用<?php $m="字"; echo strlen($m); 来进行判断,如果输出的值是3说明是utf-8编码;

如果输出的值是2说明是gbk编码;

2.服务器接收到请求后会把客户端编码的字符串转换成连接层编码字符串(具体流程是先使用系统变量 character_set_client 对 SQL 语句进行解码后,然后使用 系统变量 character_set_connection 对解码后的十六进制进行编码)。

3.进行内部操作前,将请求按照如下规则转化成内部操作字符集,如下:
3.1 使用字段 CHARACTER SET 设定值;
3.2 若上述值不存在,使用对应数据表的DEFAULT CHARACTER SET设定值;

3.3 若上述值不存在,则使用对应数据库的DEFAULT CHARACTER SET设定值;

3.4 若上述值不存在,则使用character_set_server设定值。
4.执行完 SQL 语句之后,将执行结果按照 character_set_results 编码进行输出。
宽字节注入指的是mysql数据库在使用宽字节(GBK)编码时,会认为两个字符是一个汉字(前一个ascii码要大于128(比如%df),才到汉字的范围),而且当我们输入单引号时,mysql会调用转义函数,将单引号变为\’,其中\的十六进制是%5c,mysql的GBK编码,会认为%df%5c是一个宽字节,也就是’運’,从而使单引号闭合(逃逸),进行注入攻击

宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码,然后服务器会根据character_set_connection把请求进行转码,从character_set_client转成character_set_connection,然后更新到数据库的时候,再转化成字段所对应的编码
以下是数据的变化过程:
%df%27===>(addslashes)====>%df%5c%27====>(GBK)====>運’
用户输入==>过滤函数==>代码层的$sql==>mysql处理请求==>mysql中的sql 环境搭建及分析 实验1
为了方便演示该注入的过程,搭建一下环境
链接:https://pan.baidu.com/s/1cMFtCpbbaocMjaWJx7YLcQ 密码:ykve
数据库名为test,数据库的编码全部为gdk



