首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

宽字节注入剖析

2019/2/18 11:32

前言

由于开发gbk编码并没有考虑到一些安全隐患,常常一些web的cms的gbk编码版本会在数据库中要求以GBK编码数据,并带来比较严重的SQL宽字节注入的隐患。

漏洞银行第三期的PPT原文

宽字节注入源于程序员设置MYSQL连接时错误配置为:

set character_set_client = gbk

这样配置会引发编码转换从而导致的注入漏洞。

具体原理如下:

①正常情况下当GPC开启或使用addslashes函数过滤GET或POST提交的参数时,黑客使用的单引号 ' 就会被转义为: \' (转义斜杠\和单引号')

②但如果存在宽字节注入,我们输入%df%27时首先经过上面提到的单引号转义变成了%df%5c%27(%5c时反斜杠\),之后在数据库查询前由于使用了GBK多字节编码,即在汉字编码范围内两个字节会被编码为一个汉字。然后MYSQL服务器会对查询语句进行GBK编码即%df%5c%转换成为汉字'运(繁体的)',而单引号逃逸了出来,从而造成注入漏洞。

大家需要注意的是,php在小于等于5.3.0版本的时候默认开启全局魔术引号(gpc),从5.4版本开始php废除全局魔术引号,人们则为了防止攻击者进行SQL注入而使用addslashes()函数来达到gpc的一个效果。

也就是说,当你输入http://xxx.com/x.php?title=1'这个url时,你输入的单引号会被php默认添加转译斜杠。

当遇到字符型文本的查询接口,会绕不开原本sql语句的单引号而无法实现注入。

语句执行过程

1.比如本来进入MYSQK执行的SQL语句为:

select * from news where title = ''

2.被php的gpc后为:

select * from news where title = '1\'' (这里查询的是 1\' ,url编码为1%5c%23)(%5c是斜杠,%23是单引号)

3.MYSQL实际查询语句:

select * from news where title = '1\''(大家要注意这是实际进入MYSQL的SQL语句)

要注意数据库没有gbk编码的话,php讲查询语句经过gpc(全局魔术引号)或 addslashes()函数处理的话,php处理过的语句就是MYSQL执行的语句。

其查找的内容为 1' (就是说你自己输入的单引号被添加转义符而成为了单引号实体) ,而数据库本来就没有 1' 这个内容。注入点自然而然是失效的。

但是,如果数据库本身被GBK编码,如在MYSQL中设置"set character_set_client = gbk",则会导致由于编码问题,SQL语句实际执行时吸收php程序带来的转义符号,使攻击者绕过php自身的gpc防护而直接进行注入。

如%df%5c,或者写成%df\(%df这个字节 和 转义斜杠 \),这个编码是 繁体的 '运' 字(%5c是转义斜杠的URL编码)。

则假设目前数据库是GBK编码。

上一段带来的案例:输入http://xxx.com/x.php?title=1'

被gpc后

MYSQL执行的语句为select * from news where title = '1\'',报错(错误原因在上文说过了)

语句执行过程

1.输入:

http://xx/com/x.php?title = %df%27(%27是单引号'的URL编码)

2.gpc后:

select * from news where title = '%df\''

3.MYSQL执行的语句为:

select * from news where title = '运'' ,报错

MYSQL执行的语句为select * from news where title = '运'',报错,即你输入的%df和gpc处理的转移斜杠在GBK编码的数据库中合并为一个字符,而你输入的引号会引起数据库的引号不闭合的语法报错。

上面这一句话至关重要,因为转义斜杠被吸收,从而有了注入单引号的可能。

原本的查询语句为:select * from news where title = ''

我们可以使用自己的单引号闭合前面的单引号,再注释掉后面的单引号,而中间我们可以插入自己想进行的语句。

语句执行过程

1.如union型查询语句的payload为:

.php?title = 1 %df%27 union select 1,user(),concat(name,pass) from admin %23

(%23 为 注释符号 #,注释掉后面的引号来使语句没有语法错误)

2.gpc处理后为:

select * from news where title ='1%df\' union select 1,user(),concat(name,'~',pass) from admin #'

3.MYSQL执行的语句:

select * from news where title ='1运' union select 1,user(),concat(name,'~',pass) from admin #'

此时union前面查不到 1运 这个内容,所以只会返回union后面能查的见的内容给我们。

注意,上面这一句可是语法正确的。加 # 是为了注释原本SQL语句的后面的单引号,消除语法错误。

哈哈哈,现在成功利用GBK编码绕开了后台SQL语句本身的两个引号,从而实现我们进行联合查询的可能。

所以,建站系统一般不要选择gbk编码的cms,因为这类cms通常会要求你的数据库也是gbk编码导致存在SQL注入隐患。

另外注意一点,gbk编码是存在数据库的编码才会引发SQL注入隐患,而php环境以及前端是gbk编码可是和SQL注入没有关系的!总之,只要数据库不是gbk编码,就不会存在宽字节注入了。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20190218G0FFD200?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券