深入理解宽字节注入

一、窄字节和宽字节的区别

窄字节 宽字节 还要从字符在系统上显示问题来说起,最早操作系统是英文 就那26个字母,在加一些标点符号,一个字节八位总共2的八次方,一共255的区域来对应映射这些字符与二进制关系,很轻松就可以完成了,这一个字节就是说的窄字节,后来互联网全球化,各个国家有各个国家的语言。

你就255个肯定不够,于是为了解决这个问题,就变成两字节了,2的16次方 足够放下全球所有字符了吧,这就是宽字节。

几种常见的字符集:

  • ASCII编码:单字节编码
  • latin1编码:单字节编码
  • gbk编码:使用一字节和双字节编码,0x00-0x7F范围内是一位,和 ASCII 保持一致。双字节的第一字节范围是0x81-0xFE
  • UTF-8编码:使用一至四字节编码,0x00–0x7F范围内是一位,和 ASCII 保持一致。其它字符用二至四个字节变长表示。

那么这跟sql注入有什么关系?

二、SQL注入中宽字节注入流程

我们天天跟sql注入打交道自然知道魔术引号或者addslashes()函数会对我们输入和的单引号双引号进行转义,在前面加一个\,这样就阻止了我们进行闭合然后导致注入失败。正所谓 任何东西都有两面性,我们可以根据这个特性利用\ 和宽字节 进行注入从而注入成功。

宽字节注入主要是源于程序员设置数据库编码与PHP编码设置为不同的两个编码那么就有可能产生宽字节注入。

首先我们要知道一个流程:

PHP拿到一个sql语句后 会送给连接层(Mysql 跟PHP的中间层 负责连接) 连接层拿到后 再发给Mysql 进行查询,Mysql查询完毕后再把结果发给PHP。

流程图:

图片[1]-深入理解宽字节注入-Drton1博客

而漏洞出现的原因就在于他每次接受所转换的编码不同。

数据提交到MySQL数据库,需要进行字符集的转换,使得MySQL数据库可以对数据进行处理,这一过程一般有以下三个步骤:

收到请求,将请求数据从 character_set_client ->character_set_connection。 内部操作,将数据从character_set_connection-> 表创建的字符集。 结果输出,将数据从表创建的字符集 -> character_set_results。 当执行set names “charset”,相当于执行 set character_set_client = charset set character_set_connection = charset set character_set_results = charset

client 指的是PHP程序 connection 指的是PHP客户端与MySQL服务器之间连接层 results 指的是MySQL服务器返回给PHP客户端的结果

MySQL常见的乱码问题就是这三个字符集的设置不当所引起的。

总的来说,就是php把sql语句传给mysql时,要转换character_set_connection字符集的编码,执行流程就是:将php的sql语句以character_set_client编码(也就是转为16进制数),再将16进制数以character_set_connection进行编码(也就是转换为url编码),然后以内部操作字符集进行url解码,最后以character_set_results编码输出结果。 而在url编码中 就是字符的ascll码十六进制加一个% ,而\的十六进制是5c

在GBK编码 %df%5c会被当成一个汉字的编码

图片[2]-深入理解宽字节注入-Drton1博客

从而本来我们输入的是%df ‘ —>转义 %df \ ‘ —> %df%5C%27—>縗’

实现对转义的绕过 形成闭合。

而GBK编码,编码的范围为 8140-FEFE,首字节在 81-FE 之间,尾字节在 40-FE 之间,字符 \ 的ASCII码为5C,在其低位范围内,就能被合并掉,并且能合并掉它的字符不仅只有0xdf

图片[3]-深入理解宽字节注入-Drton1博客

查询GBK的编码

三、靶场

可以看到这里是对我们的字符进行了转义。

图片[4]-深入理解宽字节注入-Drton1博客

加个注释没有报错:

图片[5]-深入理解宽字节注入-Drton1博客

注入成功,剩下的不说了,这就是宽字节注入

图片[6]-深入理解宽字节注入-Drton1博客

© 版权声明
THE END
喜欢就支持一下吧
点赞8 分享
评论 抢沙发

请登录后发表评论