mysql sql宽字节注入_SQL注入之宽字节注入

mysql sql宽字节注入_SQL注入之宽字节注入AboutSQLInje 宽字节注入 0x01 前言对于 SQL 注入 我估计搞安全的都玩的滚瓜烂熟了 搞站什么的都是分分钟来的 但是之前做了一道宽字节注入的题目 又打开了我一扇通往新世界的大门 PS 早都碰到过 只不过一直没有时间写 0x02 宽字节和 mysql 单字节字符集 所有的字符都使用一个字节来表示 比如 ASCII 编码 多字节字符集 在多字节字符集中 一部分字节用多个字节来

About SQL Injection

宽字节注入

0x01 前言

对于SQL注入,我估计搞安全的都玩的滚瓜烂熟了,搞站什么的都是分分钟来的,但是之前做了一道宽字节注入的题目,又打开了我一扇通往新世界的大门(PS:早都碰到过,只不过一直没有时间写)。

0x02 宽字节和mysql

单字节字符集: 所有的字符都使用一个字节来表示,比如 ASCII 编码。

多字节字符集: 在多字节字符集中,一部分字节用多个字节来表示,另一部分(可能没有)用单个字节来表示。

两位的多字节字符有一个前导字节和尾字节。 在某个多字节字符集内,前导字节位于某个特定范围内,尾字节也一样。

UTF-8 编码: 是一种编码的编码方式(多字节编码),它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。

常见的宽字节: GB2312、GBK、GB18030、BIG5、Shift_JIS,实际上只有两字节。宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。(GB2312 不存在宽字节注入。)

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

注意:HTML页面设置的编码跟注入是没有任何联系的,它只不过使规定了HTML渲染时候的字符集设置,与服务器端以及数据库没有任何联系。

0x03 简单的宽字节示例

出自Bugku的一道题目,非常基本。正常的传递单引号,没有任何效果。

%E5%AE%BD%E5%AD%97%E8%8A%82%E6%B3%A8%E5%85%A5-1.png

查看源代码

%E5%AE%BD%E5%AD%97%E8%8A%82%E6%B3%A8%E5%85%A5-2.png

红线标注了gb2312,这是html编码方式,但是提示了我们可能是这个方向,于是就尝试http://103.238.227.13:10083/?id=1%df’

%E5%AE%BD%E5%AD%97%E8%8A%82%E6%B3%A8%E5%85%A5-3.png

发现页面报错,也就是’没有被闭合,而是逃逸了出来生效了,SQL语句如下:select * from key where id=’1運” limit 1

这时候就明显的看出来了有个多余的单引号逃逸了,也就是你传递进去的那个单引号生效了,至此,这道题目的考察项已经完全get到了。

构造payload:http://103.238.227.13:10083/?id=1%df’ union select 1,string from sql5.key–+

那么问题来了,为什么会出现这种情况呢?

mysql设置的字符集为gbk,并且使用了那些上面所提到的过滤函数,在你传递’的时候,会在前面加上,导致’,使之被转义,从而无法闭合SQL语句,无法达到预期效果。

上面介绍了gbk是一种两个字节的编码方式,当传递%df’的时候,后台接收为%df%5c%27,这时候,数据库由于是gbk编码,所以数据库会认为%df%5c是一个中文字符’運’,转义的被吃掉了,无法转义’,这时候就导致了’可以成功逃逸出来,可以对SQL语句进行下一步改造。

可以写个php页面验证下gbk编码中文字符的长度:

header(‘content-type:text/html;charsetr=gbk’);

echo strlen(“哇”);

?>

这里还要提一点,不管你在单引号前面加什么字符,都要确保这个字符的ascii大于128,否则无法达到汉字的范围,也就无法使宽字节注入生效。

0x04 gbk与gb2312

前文提到了,gb2312不存在宽字节注入,我当时也很不理解,看了离别歌大佬的博客以后,顿有所悟(大佬终究是大佬)。

GBK与GB2312都是宽字节家族的一员,按理来说,GBK都存在宽字节注入,GB2312也存在,但是实际上,当采用字符集编码为GB2312时,宽字节注入这种情况便无法发生了,为什么呢?这要归结于GB2312编码的取值范围,它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(PS:前一位是高位,后一位是低位),而是0x5c,是不在低位范围中的。所以,0x5c也就是根本不在gb2312的编码范围内,也就是说,无论如何,都无法构造出gb2312认识的编码,也就不存在吞掉,无法构造注入了。

搬运大佬的一句总结:把这个思路扩展到世界上所有多字节编码,我们可以这样认为:只要低位的范围中含有0x5c的编码,就可以进行宽字符注入。

0x05 进阶示例在 PHP 代码中使用 mysql_query(“set names GBK”); 指定三个字符集(客户端、连接层、结果集)都是GBK编码。

demo:

$name = addslashes($_GET[‘name’]);

$con=mysqli_connect(“localhost”,”root”,”fuckroot”,”sqli”);

if (mysqli_connect_errno($con))

{

echo “连接 MySQL 失败: ” . mysqli_connect_error();

}

// 执行查询

$sql = “select * from user where name = ‘”.$name.”‘”;

mysqli_query($con,”set names GBK”);

$result = mysqli_query($con,$sql);

if(!$result){

// 打印错误原因

printf(“Error: %sn”, mysqli_error($con));

}

// 一条条获取

while ($row=mysqli_fetch_row($result))

{

printf (“%s : %s”,$row[0],$row[1]);

}

// 释放结果集合

mysqli_free_result($result);

// $row=mysqli_fetch_row($result);

echo “Closed!”;

mysqli_close($con);

?>

利用的poc:?name=111%de’ or 1=1–+

这里利用了addslashes函数进行转义特殊字符,而我们传递进去的是%de’,就会变成0xde5c,而上文设定的字符集是GBK,之后就会产生宽字节注入,道理与上文一样。

2.

php的iconv函数,对数据进行转码,有三种情况:

2.1$name = iconv(“GBK”,”UTF-8″, addslashes($_GET[‘name’])) ;

页面设置都是UTF-8编码,但是页面为了接受部分用户以GBK编码方式提交的数据,会对用户的数据先进行转码,把GBK转为UTF-8,然后再拼接SQL语句,进行一系列的操作。但是,假如传递了一个%df进去,在拼接SQL语句之前,也就是转码的时候,这个单引号逃逸就已经发生了。因为GBK会把%df解码为一个中文字符,然后进行存储。简单理解,也就是说,进行UTF转码之前,GBK就已经操作过了,所以即便进行UTF-8转码,转的也是已经生效的payload “運’”,无法对单引号进行实际操作。至此,单引号溢出,SQL注入形成。

利用的poc:name=111%B3‘ or 1=1–+

2.2$name = iconv(“UTF-8″,”GBK”, addslashes($_GET[‘name’])) ;

这个跟第一个类似,就是把UTF-8的编码转码成GBK。其实按道理来说对字符串进行转义,然后转码,按照UTF-8的编码方式进行操作,应该不会出现单引号溢出的这种问题。但是,74CMS 3.4版存在这样的漏洞,这就很gay。

现在,直接传递一个GBK编码的中文字符“錦’”参数值,这个参数先被过滤函数转义:graph LR

錦’–>錦’

那么GBK编码的16进制结果就变成了0xE55C5C27,好,现在把数据传入数据库,用UIF-8对其进行解码,UTF-8并不认识0xE5,于是0xE5就变成了乱码,而0x5C5C27会被正常解码为“‘”,就是:graph LR

0xE55C5C2–>�\’

现在,出现了两个转义用的反斜线,这时候,单引号就可以成功溢出了,因为第一个反斜线转义了第二个反斜线,使第二个反斜线失去了转义功能,也就导致了单引号的逃逸。至此,成功引发了SQL注入。

利用的POC:name=錦’ or 1=1–+

name=%E9%8C%A6′ or 1=1–+

2.3

这种情况,我认为,基本不会出现,不过网络世界这么大,啥鸟都有,也说不定。

这种是对UTF-8的编码进行GBK转码,然后使用过滤函数进行转义:$name = iconv(“UTF-8″,”GBK”, $_GET[‘name’]) ;

$name = addslashes($name);

看起来就很奇葩,但是有可能存在,利用的POC与2.2一样,只不过解析过程不一样。传递参数:name=錦’

先进行GBK转码(为了方便理解,我都以16进制表示):graph LR

0xE98CA627–>0xE55C27

然后进行过滤函数转义:graph LR

0xE55C27–>0xE55C5C5C27

惊奇的发现,5C多了两个。这因为,进行完GBK转码以后,在进行过滤函数转义的时候,会把0x5C认为是一个特殊字符,所以会对这个反斜线进行转义,也就是多加一个反斜线变成\,也就是5C5C,之后数据进入数据库,GBK对其进行解码,0xE55C会被解码为“錦”,0x5C5C27会被解码为“\‘”,也就是:graph LR

0xE55C5C5C27–>錦\’

至此,又跟2.2介绍的一样了,殊途同归,单引号成功逃逸,SQL注入产生。

0x06 小结

关于宽字节,我目前也就在CTF里面接触到了,不过既然碰到了我就写一写,这方面确实菜的不行,所以避免不了去看一些大佬的分析,也学到了很多的东西。

防范:

1.gbk编码造成的宽字符注入问题,解决方法是设置character_set_client=binary。

2.单独调用set names gbk和mysql_real_escape_string是无法避免宽字符注入问题的。还得调用mysql_set_charset来设置一下字符集。

3.谨慎使用iconv来转换字符串编码,很容易出现问题。只要我们把前端html/js/css所有编码设置成gbk,mysql/php编码设置成gbk,就不会出现乱码问题。不用画蛇添足地去调用iconv转换编码,造成不必要的麻烦。

4.在代码审计或网站开发中需要留意一下,类似 GBK 和 BIG5 这种的双字节编码,同时存在低位可以是 %5C 的字符。

PS:最近老是写到凌晨,有不足或者错误的地方,看到了希望可以及时联系我进行纠正。

特别鸣谢

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/227965.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午8:06
下一篇 2026年3月16日 下午8:06


相关推荐

  • 在Ubuntu上使用FreeFileSync同步文件

    在Ubuntu上使用FreeFileSync同步文件FreeFileSync可以在Windows,Linux,macOS上面运行。本文使用操作系统是Ubuntu18.04。安装FreeFileSync下载程序,并解压。$wgethttps://freefilesync.org/download/FreeFileSync_11.0_Linux.tar.gz$tarxvfFreeFileSync_11.0_Linux.tar.gz解压之后进入FreeFileSync文件夹,就可以双击运行程序了。我们可以创建一个启动器,这样我们可以从桌面运

    2022年5月16日
    46
  • 手机版mt4平台下载下载手机版mt4_手机mt4平台下载安卓

    手机版mt4平台下载下载手机版mt4_手机mt4平台下载安卓MetaTrader4(缩写MT4)是由俄罗斯迈达克软件公司(英文名称MetaQuotesSoftwareCorp)发布的一款交易软件,可同时在电脑端和手机端使用。但是,正版手机端mt4一般要从谷歌商店下载,而GooglePlay的下载地址经常打不开。本人使用mtr软件多年,在使用方面有一些经验,现将2020年版手机mt4下载地址分享给各位网友,愿您交易如索罗斯一般行如流水!mt4下载地址:https://t00y.com/file/29212124-458672692提取码:pj265(

    2022年8月15日
    6
  • 猿创征文|点亮JAVA技术之灯(线程篇)「建议收藏」

    猿创征文|点亮JAVA技术之灯(线程篇)「建议收藏」线程安全就是说多线程访问同一段代码,不会产生不确定的结果。又是一个理论的问题,各式各样的答案有很多,我给出一个个人认为解释地最好的:如果你的代码在多线程下执行和在单线程下执行永远都能获得一样的结果,那么你的代码就是线程安全的。(1)不可变像String、Integer、Long这些,都是final类型的类,任何一个线程都改变不了它们的值,要改变除非新创建一个,因此这些不可变对象不需要任何同步手段就可以直接在多线程环境下使用(2)绝对线程安全不管运行时环境如何,调用者都不需要额外的同步措施。……….

    2025年8月23日
    10
  • js阻止冒泡,兼容写法。

    js阻止冒泡,兼容写法。有几次遇到 a 链接里面包含 click 点击方法 这时候会触发 click 事件 还会触发 a 链接跳转 这时候就需要阻止冒泡了 添加 event stopPropagat 就可以了 在 chrome 上可以使用 本以为万事大吉了 没想到火狐不支持 event 事件 既然问题来了 就得解决 所以搜遍了百度 得到了以下的代码 兼容火狐获取 event 方法 functiongetE if

    2026年3月16日
    2
  • 【Java基础】– instanceof 用法详解

    【Java基础】– instanceof 用法详解1 instanceof 关键字如果你之前一直没有怎么仔细了解过 instanceof 关键字 现在就来了解一下 instanceof 其实是 java 的一个二元操作符 和 lt gt 这些是类似的 同时它也是被保留的关键字 主要的作用 是为了测试左边的对象 是不是右边的类的实例 返回的是 boolean 值 AinstanceofB 注意 A 是实例 而 B 则是 Class 类下面使用代码测试一下 classA interfaceInt classBextend

    2026年3月17日
    1
  • 大数据毕业设计 – 选题推荐(一)

    大数据毕业设计 – 选题推荐(一)文章目录1开题指导1.1起因1.2如何避坑(重中之重)1.3为什么这么说呢?1.4难度把控1.5题目名称1.6最后选题建议3最后1开题指导1.1起因近期开题的同学越来越多,很多同学不知道怎么选题,不知道老师分配的题目应该怎么做,指导老师分享的信息不多,无从下手。1.2如何避坑(重中之重)毕设选题实际上对很多同学来说一个大坑,每年挖坑给自己跳的人太多太多,选题选得好后面的答辩以及论文撰写会轻松很多,选的不好就是一个无穷无尽的折磨。。。。1.3为什么这么说呢?其实这主要

    2022年5月25日
    125

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号