sql注入之宽字节注入
在介绍宽字节注入之前,首先引入php的一个防御函数和一种编码格式GBK
魔术引号 magic_quotes_gpc
这是php自带的一种防御函数,该函数会解析用户提交的数据,如post,cookie等提交过来的数据,并对这些数据中的特殊字符添加转义符号'\',以确保数据不会出现致命错误。单引号,双引号,反斜线等都会被加上反斜线。
而对于sql注入,某些特殊字符是不可或缺的,所以如何绕过该函数也就成了问题。
GBK编码格式
gbk全称为《汉字内码拓展规范》,gbk是一种多字符编码。他使用了双字节编码方案,也就是说使用gbk方案的汉字,占用两个字节。一个utf-8编码的汉字,则占用3个字节。
举例子:
如0xD5
0x5c
对应汉字‘誠’
宽字节注入原理
如果程序员设置数据库编码为非英文编码那么就有可能产生宽字节诸如人。
假如数据库mysql的编码设置为了SET NAMES 'gbk'或是SET character_set_client = gbk,这样的设置就有可能引发编码转换从而导致注入漏洞。
其根本原因是: 宽字节注入就是PHP发送请求到Mysql时,mysql如果设置了上诉字符编码转换规则,则会跟我们故意设置的字节相结合组成一个gbk编码规则下的双字符而引起编码转换后,绕过了斜线转义。
例如,如果我们对注入数据加上后引号,魔术引号就会对其进行转义。
select * from users where id =-'1'' limit 0,1
在magic_quotes_gpc的作用后,变为如下形式
select * from users where id ='1\'' limit 0,1
然后sql语句就读不到引号内的那个单引号而把它当作引入的普通字符处理。
那么这个时候就可以使用宽字节注入了。因为’\‘的编码是%5c,然后我们可以构造以%5c结尾的一个gbk字符。而%df
%5c
就刚刚好是这样的一个gbk编码。
构造输入字符1%df'#
经过phpurl解码后变为10xdf'#
经过魔术引号转义,添加转移符号,转换为如下形式10xdf0x5c'#
所以注入语句最终为
select * from users where id ='1�\'#' limit 0,1
其中�\
即为那个誠
字