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. JavaScript ES 模块:现代化前端编程必备技能

    自从 ES 模块被添加到规范中后,JavaScript 中的模块就更加简单了.模块按文件分开,异步加载.导出是用 export 关键字定义的:值可以用 import 关键字导入. 虽然导入和导出单个值 ...

  2. python_sys.argv的使用

    # sys.argv练习 # 写一个python脚本,在cmd里执行 # python xxx.py 用户名 密码 cp 文件路径 目的地址 # python xxx.py alex sb cp D: ...

  3. 线程安全的SimpleDateFormat

    import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; imp ...

  4. 三:登录功能实现,servlet

    1)servlet 2)request 请求对象 3)response响应对象 4)转发 5)重定向 1.servlet就是用来处理客户端的请求的 1.1去官网下载 1.2 在STS上添加该包ctrl ...

  5. 一些 git 常用的命令

    1.本地命令 查看状态 -git status 添加文件 -git add . 提交文件 -git commit -m "(comment)" 查看历史key -git reflo ...

  6. Java编译程序和运行过程详解

    java整个编译以及运行的过程相当繁琐,我就举一个简单的例子说明: 编译原理简单过程:词法分析 --> 语法分析 --> 语义分析和中间代码生成 --> 优化 --> 目标代码 ...

  7. python-网络安全编程第四天(数据库编程&网络编程)

    前言 好几天没更因为寒假放假回家放松了几天 嘿嘿 今天继续开始启动学习模式. python数据库编程 Python DB API访问数据库流程 Python DB API包含的内容 什么是 PyMyS ...

  8. 全网最全!这份深入讲解jdk和jvm原理的笔记,刷新了我对JVM的认知

    前言 前两天和朋友探讨技术的时候有聊到JVM和JDK这一块,聊到这里两个人就像高山流水遇知音那是根本停不下来,事后我想着趁现在印象还比较深刻就把这些东西整理起来分享给大家来帮助更多的人吧.话不多说,满 ...

  9. 巧妙运用Camtasia 旅行Vlog轻松get

    旅行时,除了要欣赏当地的美丽风景.享受当地美食外,当然还要将旅行中的各种小细节记录下来.以前我们可能更多地使用相机拍照,现在呢,越来越多的人采用视频拍摄的方式制作Vlog.这种兼具影像与叙事的视频表现 ...

  10. ResNet模型

    ReeNet论文地址:Deep Residual Learning for Image Recognition Resnet的两种不同结构 上图左边的结构主要是针对深度较少的网络,当深度较大时则用右边 ...