专栏首页信安之路【作者投稿】宽字符注入详解与实战

【作者投稿】宽字符注入详解与实战

宽字节注入源于程序员设置MySQL连接时的错误配置,如下:

set character_set_client=gbk

,这样的配置会引发编码转换从而导致绕过某些防护实现注入漏洞。具体分析一下原理:

  1. 正常情况下GPC开启或者使用addslashes函数过滤GET或POST提交的参数时,我们测试输入的',就会被转义为\';
  2. 若存在宽字节注入,输入%df%27时,经过单引号的转义变成了%df%5c%27,之后再数据库查询语句进行GBK多字节编码,即一个中文占用两个字节,一个英文同样占用两个字节且在汉字编码范围内两个编码为一个汉字。然后MySQL服务器会对查询语句进行GBK编码即%df%5c转换成汉字"運",单引号逃逸出来,从而绕过转义造成注入漏洞。

现在基本都会将mysql的连接配置设置为:

[set character_set_client=binary]

来解决这个问题,这篇博客将介绍php中因为编码或字符编码转换导致的注入问题。

mysql中的宽字符注入

测试搭建学习的环境利用了phithon内容管理系统,看代码

SQL语句是SELECT * FROM news WHERE tid='{$id}',根据文章的id把文章从news表中提取出来,在$sql之前,我们只用了限制函数addslashes函数,对$id进行转义,只要我们输入参数在单引号中,就逃逸不出单引号的限制,从而无法注入。

我们这里利用的是mysql的一个特性,mysql在使用GBK编码的时候,会认为两个字节是一个汉字(前一个ascii码要大于128,才到汉字范围),我们测试输入%df'

已经报错,看到报错,说明sql语句出错,看到出错说明可以注入。报错的原因就是多了一个单引号,而单引号前面的反斜杠不见啦。这就是mysql的特性,因为gbk是多字节编码,它认为两个字节代表一个字符,所以%df和后面的%5c变成了汉字“運”,而’逃逸了出来。

因为是两个字节代表一个汉字,我们尝试%df%df%27:

不报错了,因为%df%df组成了汉字"哌",%5c%27不是汉字,仍然是\'

mysql如何判断一个字符是不是一个汉字,根据gbk编码,第一个字节的ascii码大于128,基本上就行,若不用%df而用%a1也可以

%a1%5c虽然不是一个汉字,但一定会被mysql认为是一个宽字符,所以就能让后面的%27逃逸出来,构造一个exp,查询管理人员的账号密码。

GB12和GBK的区别

gb2312和gbk都是宽字节家族医院,但是当把数据库编码设置为关闭gb2312时,结果就不能注入

这主要是gb2312编码取值范围的事情,它高位范围0xA1~0xF7,低位范围是0xA1~0xFE,\是%5c,是不在低范围中的,即其根本不是gb2312遍吗,故其不会被吃掉。故只要低位的范围中含有0x5c的编码,就可以进行宽字节的注入

利用mysql_real_escape_string解决问题

一些cms把addslashes替换为mysql_real_escape_string来防止宽字节的注入

我们若解决需要做的指定php连接mysql的字符集。我们需要在执行sql语句之前调用一下mysql_set_charset函数,设置当前的字符集为gbk,来避免问题

宽字节注入修复

character_set_client='binary'设置为binary(二进制),只需要在所有的sql语句前指定一下连接的形式为二进制:mysql_query("SET character_set_connection=gbk, character_set_results=gbk,character_set_client=binary", $conn);,当我们的mysql接受到客户端的数据后,会认为他的编码是character_set_client,然后会将换成character_set_connection的编码,然后在进入具体表和字段后,再转换成字段对应的编码,然后当查询结果产生后,会从表和字段编码,转换成character_set_results编码,返回给客户端。

这个方法避免宽字节的注入还是有效的,但是如果开发者画蛇添足的增加一些东西,会让前期的努力前功尽弃。

iconv造成的严重后果

很多cms会将接收到的数据,调用这样一个函数,转换其编码:iconv('utf-8','gbk',$_GET['id']);,目的一般是避免乱码,特别是搜索框的位置

可以发现,在sql语句执行前,将character_set_client设置成了binary,所以避免宽字节的注入问题。但之后其调用了iconv将已经过滤的参数$id给转换了一下,测试一下

报错说明我们錦被iconv从utf-8转换成gbk后,变成了%e5%5c,而后面的'被addslashes变成了%5c%27,这样组合起来就是%e5%5c%5c%27,两个%5c就是\,正好把反斜杠转义了,导致'逃逸出单引号,产生注入。利用的是将\转移掉。

利用iconv将gbk转换成utf-8,则可以直接用宽字节注入的姿势来。gbk汉字2字节,utf-8汉字是3字节,若把gbk转换成utf-8,则php会每两个字节一转换。所以,如果\’前面的字符是奇数的话,势必会吞掉\,’逃出限制。

总结

  1. gbk编码造成的宽字符注入问题,解决方法是设置character_set_client=binary。
  2. 矫正人们对于mysql_real_escape_string的误解,单独调用set name=gbk和mysql_real_escape_string是无法避免宽字符注入问题的。还得调用mysql_set_charset来设置一下字符集。
  3. 谨慎使用iconv来转换字符串编码,很容易出现问题。只要我们把前端html/js/css所有编码设置成gbk,mysql/php编码设置成gbk,就不会出现乱码问题。不用画蛇添足地去调用iconv转换编码,造成不必要的麻烦。

代码审计实战

对骑士cms审计时发现在plus/ajax_street.php

在之前配置文件设置的是mysql_query("SET character_set_connection=" . $dbcharset . ", character_set_results=" . $dbcharset . ", character_set_client=binary", $this->linkid);,其中利用了iconv函数造成致命的错误,同时分析发现页面将查询结果回显回来,构造一些union的查询语句即可获取数据库的敏感信息

漏洞的利用

测试有几个字段,发现category表一共有9个字段,所以可以构造获取数据库用户和先关信息的exp

然后利用union的查询语句爆出可利用的列为4,8,exp:

http://localhost/74cms/upload/plus/ajax_street.php?act=key&key=-%e9%8c%a6' union select 1,2,3,4,5,6,7,8,9-- -),

然后是爆出数据库和用户名等相关信息

补充

GBK编码中的两个字符是一个汉字,第一个字符需要大于128

本文分享自微信公众号 - 信安之路(xazlsec),作者:J_drops

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-09-26

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Web 指纹识别之路

    攻击者最常用的方法是首先覆盖目标的网络存在并枚举尽可能多的信息。利用此信息,攻击者可以製定出准确的攻击方案,这将有效利用目标主机正在使用的软件类型/版本中的漏洞...

    信安之路
  • 一文读懂 DEX 文件格式解析

    我想说的是写个解析脚本不是为了模仿着 apktools 造轮子,而是在解析过程中寻找逆向的道路,方法会变,工具会变,但一切都建立在 dex 上的安卓不会变

    信安之路
  • 部署nginx_lua_waf记录

    通过部署nginx_lua_waf,具有使用简单、高性能、轻量级的优势,能够有效的防范sql注入、文件包含、XSS、fuzzing等web攻击,屏蔽异常的网络请...

    信安之路
  • 硬盘和文件系统管理

    1、预备知识 介绍Linux硬盘知识(文件命名方案xxyN) 分区名的前两个字母表示分区所在设备的类型(hd是IDE硬盘,sd是SCSI硬盘,scsi比ID...

    苦咖啡
  • 接收发送消息与数据库交互

    线上的接口的坑太多了。不如自己写一个吧。实际的业务场景中,可以用户回复关键词,可获取系统中相关的消息。

    一粒小麦
  • 这个Kaggle三项排行榜的“顶级大师”,今年17岁

    Kaggle,这是个坐拥 100 万会员的数据建模和数据分析竞赛平台,目前已被 Google 收购。企业和研究者可在这个平台上发布数据,而统计学者和数据挖掘专家...

    AI科技大本营
  • Linux基础(day54)

    13.1 设置更改root密码 设置更改root密码目录概要 /usr/local/mysql/bin/mysql -uroot 更改环境变量PATH,增加my...

    运维小白
  • 安装 MySQL,你准备好了么!

    将下载的 MySQL 压缩包解压并移到你所要安装的路径,下面以我的安装路径D:\Program Files\mysql-8.0.13-winx64为例;

    村雨遥
  • HP DL380 G5服务器创建RAID

    这台HP DL380 G5已经稳定运行了好几年的时间了,Data日渐增多,起初的Disk容量已经不能满足现在的需求,加上Disk已经运行了几万小时,读写能...

    行 者
  • Java中的基本数据类型转换(自动、强制、提升)

    Java技术栈

扫码关注云+社区

领取腾讯云代金券