SQL注入:宽字节注入(GBK双字节绕过)

宽字节注入的作用是非常大的,实际上在代码层的防御一般不外乎两种,一是反斜杠转义,而就是replace替换成空字节,之前的替换空字节也就是各种bypass,想办法绕过代码层定制的黑名单,那么,转义的话,就不像替换那么好绕了

要么不用被转义的字符,要们就只能想办法构造了,这时候,便有了一个很牛逼的构造方法,GBK双字节绕过,实际也算是宽字节注入,这个可以看看一本书

  • 《双字节编码 php的隐形杀手》

宽字节注入的方法也很简单,就是编码,我们一点点分析

假设一个URL存在注入但是有addslashes,mysql_real_escape_string,mysql_escape_string等等函数实现转义就比如如下代码

function check_addslashes($string)

{

 $string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash

 $string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash

 $string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash

 return $string;

}

定义了个一个过滤函数,然后使用它

if(isset($_GET['id']))

{

$id=check_addslashes($_GET['id']);

mysql_query("SET NAMES gbk");

$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";

$result=mysql_query($sql);

$row = mysql_fetch_array($result);

这儿形成的URL应该是

http://www.xxx.com/index.php?id=1

我们敲单引号会被过滤,但又必须要敲,那么怎么办呢?这时候就利用GBK双字节注入

我们在后边这么构造URL

http://www.xxx.com/index.php?id=1%df'and 1=2 union select 1,2,3%23

这样的话id的参数传入代码层,就会在’前加一个\,由于采用的URL编码,所以产生的效果是

%df%5c%27

关键就在这,%df会吃掉%5c,形成一个新的字节,举个例子就是%d5遇到%5c会把%5c吃掉,形成%d5%5c,这个编码经过代码解码后会形成一个汉字“誠”

说的再形象点,我来画个画解决

基本解释:

因为%df的关系,\的编码%5c被吃掉了,也就失去了转义的效果,直接被带入到mysql中,然后mysql在解读时无视了%a0%5c形成的新字节,那么单引号便重新发挥了效果

那么真正的原因是什么呢?

GBK双字节注入到底是怎么来的呢?

宽字节注入发生的位置就是PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码。

http://www.xxx.com/index.php?id=1%df'and 1=2 union select 1,user(),3%23

按照这个参数,我们在页面输出$sql,看看最终传入到mysql中的语句构造

SELECT * FROM users WHERE id='1運' and 1=2 union select 1,user(),3#' LIMIT 0,1

我们可以看到,单引号前并没有\,而是多了一个汉字

那么这句传入到mysql中运行的结果是什么呢?

输出了user()

这是为什么呢?为什么在传入到mysql时,%df%5c%27会变成運’?

我们之前强调过了,宽字节注入的发生位置在PHP发送请求到MYSQL时字符集使用character_set_client设置值进行了一次编码。

就是这一次编码,发生了这一切

当一个Mysql连接请求从客户端传来的时候,服务器认为它的编码是character_set_client,
然后会根据character_set_connection把请求进行转码,从character_set_client转成character_set_connection,
然后更新到数据库的时候,再转化成字段所对应的编码
如果使用了set names指令,那么可以修改character_set_connection的值,
也同时会修改character_set_client和character_set_results的值
当从数据库查询数据返回结果的时候,将字段从默认的编码转成character_set_results

这儿会产生什么呢?

我们追踪下数据的变化过程

%df%27===>(addslashes)====>%df%5c%27====>(GBK)====>運’

用户输入==>过滤函数==>代码层的$sql==>mysql处理请求==>mysql中的sql

mysql_query("SET NAMES gbk");

当这行代码在代码层被写入时,三个字符集(客户端、连接层、结果集)都是GBK编码。

那么便会发生如上的情况

有人会说,那直接试用UTF-8编码呢,很多网站就是这么做的,但是为了避免用户输入的GBK字符形成乱码,网站真正的做法是会将一些用户提交的GBK字符使用iconv函数(或者mb_convert_encoding)先转为UTF-8,然后再拼接入SQL语句。

%e5%5c%27====(addslashes)====>e55c5c5c27====(iconv)====>e98ca6\\’

上面的UTF-8的SQL代码,但是如果转成GBK时,e98ca6\\’实际是錦’

那么,mysql中又是如何处理sql语句中的编码的呢?

我们传统意义上说的编码其实是指字符集,它包括两个方面,一个是存储的字符,另外一个是映射关系,也就是真正的编码。各种字符集的存储的字符都是差不多的,就那么几个字符,而编码却是各不相同,是真正发挥威力的地方。
原来的系统数据存储采用gbk字符集,因为版本原因,升级后系统必须采用latin1字符集来存储,所以新的数据库中存储的是gbk的字符,而使用的是latin1的编码。所以这种数据只能在需要显示gbk的页面上正确显示,在显示其他字符集的地方就会是乱码。

这儿mysql对于那个新形成的字符的处理,问了下phithon大牛,很快便给了答案,在他写的一篇文章中有类似的解释—-遇到一个有趣的逻辑漏洞》

到这儿,基本就说的差不多了,还剩最后的一部分了,哪些能形成宽字节呢?

GBK双字节编码:一个汉字用两个字节表示,首字节对应0x81-0xFE,尾字节对应0x40-0xFE(除0x7F),刚好涵盖了对应的编码0x5C。

这儿我给个GBK表,便于大家查询

GBK编码表

6、安全方案

对于宽字节编码,有一种最好的修补就是:

(1)使用mysql_set_charset(GBK)指定字符集

(2)使用mysql_real_escape_string进行转义

原理是,mysql_real_escape_string与addslashes的不同之处在于其会考虑当前设置的字符集,不会出现前面e5和5c拼接为一个宽字节的问题,但是这个“当前字符集”如何确定呢?

就是使用mysql_set_charset进行指定。

上述的两个条件是“与”运算的关系,少一条都不行。

GBK宽字节注入SQL的更多相关文章

  1. 3期浅析宽字节注入-----SQL注入

    通过分类的名称,你就可以找到漏洞银行的hack show视频. 吸收这个知识的几个关键的信息. 1.通过视频得到知识源.         [信息来源] 我怎么从不清楚到知道这个信息来源?这个过程没办法 ...

  2. SQL注入--宽字节注入

    PHP测试代码: <?php // 面向对象写法 $id=addslashes($_GET[‘id’]); //获取id并转义预定义字符 // /$id=$_GET[‘id’]; $mysqli ...

  3. 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 5.全局防护Bypass之宽字节注入

    0x01 背景 首先我们了解下宽字节注入,宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞.具体原 ...

  4. Sql 注入详解:宽字节注入+二次注入

    sql注入漏洞 原理:由于开发者在编写操作数据库代码时,直接将外部可控参数拼接到sql 语句中,没有经过任何过滤就直接放入到数据库引擎中执行了. 攻击方式: (1) 权限较大时,直接写入webshel ...

  5. SQL宽字节注入

    0x00 概述 - 什么是宽字节注入? 宽字节注入就是因为gbk编码方式需要两个ascii码组合来解码,所以形象的叫做宽字节,这个作为了解即可 -宽字节注入的条件 1) 数据库查询设置为GBK编码 2 ...

  6. SQL注入:宽字节注入

    了解GBK编码 尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的 ...

  7. CTF—WEB—sql注入之宽字节注入

     宽字节注入 宽字节注入是利用mysql的一个特性,mysql在使用GBK编码(GBK就是常说的宽字节之一,实际上只有两字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字 ...

  8. SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入

    1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...

  9. Mysql宽字节注入(转)

    尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...

随机推荐

  1. Python爬虫-换行的匹配

    之前在学习爬虫的时候遇到了匹配内容时发现存在换行,这时没法匹配了,后来在网上找到了一种方法,当时懒得记录,今天突然有遇到了这种情况,想想还是在这里记录一下吧. 当时爬取的时csdn首页博客,如下图 看 ...

  2. AOP 与 注解的那些事儿~

    持续原创输出,点击上方蓝字关注我 目录 前言 什么是AOP? AOP的相关概念(面试常客) Spring Boot 如何整合AOP自定义一个注解? 使用拦截器如何自定义注解? 内部调用导致AOP注解失 ...

  3. java 基础知识(java web 方面的)

    1.java面向对象的基本特征:封装性,多态性,继承性. 2.Java的泛型:iterator接口主要有hasnext()方法,next()方法,remove()方法:collection接口继承了i ...

  4. Nacos配置中心源码分析

    1.使用 compile 'com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-config:2.2.3.RELEASE' spring: app ...

  5. 一个提高GPU模糊算法的速度的方法

    一个提高GPU模糊算法的速度的方法 我们知道,模糊算法,比如高斯模糊是卷积算法的一种应用.计算图像中一个像素的模糊颜色值需要通过采样周围像素的颜色值来计算. 对于GPU应用,比如OpenGL,在sha ...

  6. Postman设置自动捕获传递Cookie教程

    目录 前言 一.安装 1.Postman安装Install Interceptor Bridge 2.谷歌浏览器安装扩展Postman Interceptor 二.使用 1. 打开Capture Co ...

  7. WPF有关控件和模板样式设计的微软官方文档

    说明 如果你正在使用WPF开发应用程序,相信这篇博客会对你有用.希望你能认真的阅读 正文 此文主要以Button为例进行介绍此文档的组成部分. Button Parts Button控件没有任何命名的 ...

  8. C++基础知识篇:C++ 存储类

    存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期.这些说明符放置在它们所修饰的类型之前.下面列出 C++ 程序中可用的存储类: auto register static extern m ...

  9. [BUGCASE]FixedDataTable表格数据渲染错误

    一.问题描述 广告配置中绑定第三方规格ID表格数据,有一部分展示错乱,具体如下: 表格组件使用 Facebook 的 (fixed-data-table) 组件 二.原因分析 1.检查props 先查 ...

  10. 训练yolo之前,anchor聚类问题

    前期做数据可视化,发现标签数据存在一些孤立点(噪声点),影响kmeans聚类. 处理方法如下: 使用kmeans迭代10次得到聚类中心 计算所有数据到其聚类中心的欧式距离均值和方差 通过拟合正态分布, ...