GBK宽字节注入SQL
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的更多相关文章
- 3期浅析宽字节注入-----SQL注入
通过分类的名称,你就可以找到漏洞银行的hack show视频. 吸收这个知识的几个关键的信息. 1.通过视频得到知识源. [信息来源] 我怎么从不清楚到知道这个信息来源?这个过程没办法 ...
- SQL注入--宽字节注入
PHP测试代码: <?php // 面向对象写法 $id=addslashes($_GET[‘id’]); //获取id并转义预定义字符 // /$id=$_GET[‘id’]; $mysqli ...
- 【PHP代码审计】 那些年我们一起挖掘SQL注入 - 5.全局防护Bypass之宽字节注入
0x01 背景 首先我们了解下宽字节注入,宽字节注入源于程序员设置MySQL连接时错误配置为:set character_set_client=gbk,这样配置会引发编码转换从而导致的注入漏洞.具体原 ...
- Sql 注入详解:宽字节注入+二次注入
sql注入漏洞 原理:由于开发者在编写操作数据库代码时,直接将外部可控参数拼接到sql 语句中,没有经过任何过滤就直接放入到数据库引擎中执行了. 攻击方式: (1) 权限较大时,直接写入webshel ...
- SQL宽字节注入
0x00 概述 - 什么是宽字节注入? 宽字节注入就是因为gbk编码方式需要两个ascii码组合来解码,所以形象的叫做宽字节,这个作为了解即可 -宽字节注入的条件 1) 数据库查询设置为GBK编码 2 ...
- SQL注入:宽字节注入
了解GBK编码 尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的 ...
- CTF—WEB—sql注入之宽字节注入
宽字节注入 宽字节注入是利用mysql的一个特性,mysql在使用GBK编码(GBK就是常说的宽字节之一,实际上只有两字节)的时候,会认为两个字符是一个汉字(前一个ascii码要大于128,才到汉字 ...
- SQL注入篇二------利用burp盲注,post注入,http头注入,利用burpsuit找注入点,宽字节注入
1.布尔盲注burpsuit的使用 先自己构造好注入语句,利用burpsuit抓包,设置变量,查出想要的信息. 比如----查数据库名的ascii码得到数据库构造好语句 http://123.206. ...
- Mysql宽字节注入(转)
尽管现在呼吁所有的程序都使用unicode编码,所有的网站都使用utf-8编码,来一个统一的国际规范.但仍然有很多,包括国内及国外(特别是非英语国家)的一些cms,仍然使用着自己国家的一套编码,比如g ...
随机推荐
- 监控-Cat项目部署
一.Cat的项目背景 CAT(Central Application Tracking),是美团点评基于 Java 开发的一套开源的分布式实时监控系统.美团点评基础架构部希望在基础存储.高性能通信.大 ...
- php将富文本内容图片上传到oss并替换
/** * php 提取html中图片并替换 */ //要替换的内容 //提取图片路径的src的正则表达式 $match_str = '/(<img([^>]*)\s*src=(\'|\& ...
- 1. 线性DP 53. 最大子序和.
53. 最大子序和. https://leetcode-cn.com/problems/maximum-subarray/ func maxSubArray(nums []int) int { dp ...
- Java 类型信息详解和反射机制
本文部分摘自 On Java 8 RTTI RTTI(RunTime Type Information)运行时类型信息,能够在程序运行时发现和使用类型信息,把我们从只能在编译期知晓类型信息并操作的局限 ...
- 使用qmake编译时拷贝文件
使用qmake构建项目时,需要在make时拷贝一些文件到指定位置,非执行make install,下面总结列举一下我了解的方式 COPIES 示例pro 1 COPY_DIR = $$PWD/copy ...
- xenserver使用ceph的rbd的方法
首先安装的xenserver6.5的环境,看到有地方有提到这个上面可以安装rbd的支持,网上有一种方式是libvirt+kvm方式,因为ceph对libviet是原生支持的,但是xenserver底层 ...
- python-网络安全编程第十天(web目录扫描&&fake_useragent模块&&optionParser模块)
前言 昨天的内容没有完成今天花了点时间继续完成了 感觉自己的学习效率太低了!想办法提高学习效率吧 嗯 ,再制定下今天的目标 开始健身. python fake_useragent模块 1.UserAg ...
- day96:flask:flask-migrate&flask-session&蓝图Blueprint&蓝图的运行机制
目录 1.flask-migrate 2.flask-session 3.蓝图:Blueprint 4.蓝图的运行机制 1.数据库迁移:flask-migrate 1.Flask的数据库迁移 在开发过 ...
- Xcode6在ios7上编译framework报错
错误描述: dyld: Symbol not found: _OBJC_CLASS_$_UIPresentationController Referenced from: /var/mobile/Ap ...
- HarmonyOS Java UI之DependentLayout布局示例
DependentLayout简介 DependentLayout意为相对位置布局,与DirectionalLayout相比较有更多的排布方式,每个组件可以指定相对于其他同级组件的位置,也可以指定相对 ...