在mysql中,用于转义的函数有addslashes,mysql_real_escape_string,mysql_escape_string等,

还有一种情况是magic_quote_gpc,不过高版本的PHP将去除这个特性。

首先,宽字节注入与HTML页面编码是无关的,笔者曾经看到

<meta charset=utf8>

就放弃了尝试,这是一个误区,SQL注入不是XSS。虽然他们中编码的成因相似,不过发生的地点不同。

很多网上的材料都说程序使用了宽字节来处理程序,却又不指出具体是指什么程序。本文就介绍一下具体

漏洞发生的原理与简单的利用。在这里我们限定使用的语言是PHP5.4,数据库MYSQL5.6。

涉及到的一些概念

字符、字符集与字符序

字符(character)是组成字符集(character set)的基本单位。对字符赋予一个数值(encoding)

来确定这个字符在该字符集中的位置。

字符序(collation)指同一字符集内字符间的比较规则。

UTF8

由于ASCII表示的字符只有128个,因此网络世界的规范是使用UNICODE编码,但是用ASCII表示的字符使用UNICODE并不高效。

因此出现了中间格式字符集,被称为通用转换格式,及UTF(Universal Transformation Format)。

宽字节

GB2312、GBK、GB18030、BIG5、Shift_JIS等这些都是常说的宽字节,实际上只有两字节。

宽字节带来的安全问题主要是吃ASCII字符(一字节)的现象。

MYSQL的字符集转换过程

1. MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection;

2. 进行内部操作前将请求数据从character_set_connection转换为内部操作字符集,其确定方法如下:

• 使用每个数据字段的CHARACTER SET设定值;

• 若上述值不存在,则使用对应数据表的DEFAULT CHARACTER SET设定值(MySQL扩展,非SQL标准);

• 若上述值不存在,则使用对应数据库的DEFAULT CHARACTER SET设定值;

• 若上述值不存在,则使用character_set_server设定值。

将操作结果从内部操作字符集转换为character_set_results。

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

PHP测试代码:

<!DOCTYPE html><meta charset="gbk"><!--仅用于基础的显示,换成utf8也行就是不好看--><?php

error_reporting(0);$conn =mysql_connect('127.0.0.1','root','');mysql_select_db('mysql',$conn);mysql_query("set names gbk");//不安全的编码设置方式$res =mysql_query("show variables like 'character%';");//显示当前数据库设置的各项字符集while($row =mysql_fetch_array($res)){var_dump($row);}$user =addslashes($_GET['sql']);//mysql_real_escape_string() magic_quote_gpc=On addslashes() mysql_escape_string()功能类似$sql ="SELECT host,user,password FROM user WHERE user='{$user}'";echo $sql.'</br>';if($res =mysql_query($sql)){while($row =mysql_fetch_array($res)){var_dump($row);}}else{echo "Error".mysql_error()."<br/>";}?>

http://localhost/xl.php?sql=root%df%27%20or%201=1%23

是可以执行成功的!

URL解码sql=rootß’ or 1=1#

解析过程:

$_GET[‘sql’]经过addslashes编码之后带入了‘\’

1、root%df%5C%27%20or%201=1%232、带入mysql处理时使用了gbk字符集%df%5c->運成功的吃掉了%5c%27->‘单引号成功闭合

执行了插入的sql语句。

怎么吃的:

GBK编码,它的编码范围是0x8140~0xFEFE(不包括xx7F),在遇到%df(ascii(223)) >ascii(128)时自动拼接%5c,

因此吃掉‘\’,而%27、%20小于ascii(128)的字符就保留了。

补充:

GB2312是被GBK兼容的,它的高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(0x5C不在该范围内),因此不能使用编码吃掉%5c。

其它的宽字符集也是一样的分析过程,要吃掉%5c,只需要低位中包含正常的0x5c就行了。

安全过滤

上文中代码使用了mysql_query(“set names gbk”)来设置编码,其实在mysql中是推荐mysql_set_charset(“gbk”);函数来进行编码设置的,

这两个函数大致的功能相似,唯一不同之处是后者会修改mysql对象中的mysql->charset属性为设置的字符集。

同时配套的过滤函数为mysql_real_escape_string()。上面代码中列出了几个过滤的函数,他们之间的区别就是mysql_real_escape_string()

会根据mysql对象中的mysql->charset属性来对待传入的字符串,因此可以根据当前字符集来进行过滤。

同理可得

由上文可得宽字节注入是由于转编码而形成的,那具有转编码功能的函数也成了漏洞的成因。

转码函数

mb_convert_encoding()

iconv()

以下用iconv()来演示,修改上面的代码:

<!DOCTYPE html><meta charset="gbk"><?php

error_reporting(0);$conn =mysql_connect('127.0.0.1','root','');mysql_select_db('mysql',$conn);mysql_set_charset("utf8");//推荐的安全编码$user =mysql_real_escape_string(($_GET['sql']));//推荐的过滤函数$user =iconv('GBK','UTF-8',$user);$sql ="SELECT host,user,password FROM user WHERE user='{$user}'";echo $sql.'</br>';$res =mysql_query($sql);while($row =mysql_fetch_array($res)){var_dump($row);}?>

http://localhost/xl.php?sql=root%e5%27or%201=1%23

同样可以执行成功,编码解析的过程依然如上。

总结一下漏洞成因:

代码一

1、使用了不安全的字符集设置函数与过滤函数。

2、漏洞发生在PHP请求mysql时使用character_set_client值进行一次转码。

代码二

1、使用了推荐的设置函数与过滤函数。

2、解析错误发生在iconv()函数转码时,GBK转向UTF8吃掉了“\”

3、PHP请求mysql时转码安全。

另外:

当改变编码方向时

这种情况下需要两个参数来配合注入。

例如:

http://localhost/xl.php?sql=root%e9%8c%a6¶=%20or%201=1%23

总结:

宽字节注入跟HTML页面编码无关。

Mysql编码与过滤函数推荐使用mysql_real_escape_string(),mysql_set_charset()。

转编码函数同样会引起宽字节注入,即使使用了安全的设置函数。

参考文献

mysql字符集的设置:http://www.laruence.com/2008/01/05/12.html

mysql宽字节注入_转宽字节注入详解相关推荐

  1. mysql表变量临时表_表变量和临时表详解

    首先让我们来看看什么是表变量和临时表. sql server 表变量 1.初识表变量 表变量在sql server 2000中首次被引用.表变量的定义和创建一个表大致相同,只不过是使用DECLARE ...

  2. mysql 事务排他锁_[数据库事务与锁]详解六: MySQL中的共享锁与排他锁

    注明: 本文转载自http://www.hollischuang.com/archives/923 在MySQL中的行级锁,表级锁,页级锁中介绍过,行级锁是Mysql中锁定粒度最细的一种锁,行级锁能大 ...

  3. 连接mysql所必须参数_数据库连接参数使用方法详解

    在设计数据库应用程序的时候,经常需要将一些信息从程序中独立出来,以保证程序的可移植性.其中最重要的信息就是数据库的连接参数. 在Delphi中,获得正确的数据库连接参数的方法十分简单,你只需要建立一个 ...

  4. php byte转 宽字符,C++宽字符与普通字符的转换实例详解

    C++宽字符与普通字符的转换实例详解 把字符串转换成宽字符串, 实例代码: wstring string2Wstring(string sToMatch) { #ifdef _A_WIN int iW ...

  5. 简述mysql完全备份过程_【SQL】MySQL之使用mysqldump全备份及恢复过程详解_MySQL

    mysqldump bitsCN.com [SQL]MySQL之使用mysqldump全备份及恢复过程详解 [目标]使用mysqldump做全备,结合mysql自带的binlog功能实现增量备份 为了 ...

  6. mysql简易购物车系统_基于PHP+Mysql简单实现了图书购物车系统的实例详解

    基于PHP+Mysql简单实现了图书购物车系统的实例详解,购物车,这是,页面,简单,图书 基于PHP+Mysql简单实现了图书购物车系统的实例详解 易采站长站,站长之家为您整理了基于PHP+Mysql ...

  7. mysql revoke 授权_浅谈MySQL中授权(grant)和撤销授权(revoke)用法详解

    MySQL 赋予用户权限命令的简单格式可概括为: grant 权限 on 数据库对象 to 用户 一.grant 普通数据用户,查询.插入.更新.删除 数据库中所有表数据的权利 grant selec ...

  8. 数学建模_随机森林分类模型详解Python代码

    数学建模_随机森林分类模型详解Python代码 随机森林需要调整的参数有: (1) 决策树的个数 (2) 特征属性的个数 (3) 递归次数(即决策树的深度)''' from numpy import ...

  9. MySQL建表(那些字段必须)命令详解

    MySQL建表(那些字段必须)命令详解1. create table命令 强调:使用建表命令之前必须使用use命令选择表所在的数据库.create table命令的格式如下: create table ...

  10. MySQL锁、事务隔离级别、MVCC机制详解、间隙锁、死锁等

    一. 简介 1. 锁定义 锁是计算机协调多个进程或线程并发访问某一资源的机制. 在数据库中,除了传统的计算资源(如CPU.RAM.I/O等)的争用以外,数据也是一种供需要用户共享的资源.如何保证数据并 ...

最新文章

  1. 20180917-1每周例行报告
  2. JAVA SE学习day_07:异常处理、TCP通信
  3. command not found: shopt 的 ~/.bashrc
  4. matlab碎纸拼接相似函数,基于蒙特卡洛算法构建能量函数的碎纸图片拼接方法
  5. spring配置详解-属性注入(构造函数)
  6. 正则表达式入门之重复匹配
  7. Java数据类型和标识符
  8. 好的网站收藏---长期更新---长期更新---长期更新---长期更新--
  9. 解决在使用pip进行安装时的Could not install packages due to an EnvironmentError的问题
  10. 苹果开发者中心宕机8天终于回归
  11. Scatter-gather DMA 与 block DMA
  12. eeprom和编程器固件 k2_关于k2的一个非常诡异的情况,涉及原厂固件比第三方如老毛子网速快,穿墙,eeprom等...
  13. springboot配置微信公众号获取openid
  14. 不要奇怪 XP震网病毒缺陷或为2014最大软件漏洞
  15. 中国农业大学计算机考研复试分数线,2020中国农业大学考研复试分数线已公布...
  16. 论文解读:A Hierarchical Framework for Relation Extraction with Reinforcement Learning
  17. 兰州交通大学php,航拍兰州交通大学校园∣让我再看你一遍 从南到北
  18. Herb Sutter简介
  19. @Aspect 用法
  20. 剑指offer--序列化与反序列化二叉树(先序递归,建树)

热门文章

  1. 简而言之,JUnit:测试结构
  2. 玩Java 8 – Lambda和并发
  3. Java:计算类的serialVersionUID
  4. 使用ANTLR4,用于代码镜像和基于Web的DSL的Primefaces扩展
  5. Google Authenticator:将其与您自己的Java身份验证服务器配合使用
  6. 如何在Java中获得类似于C的性能
  7. c语言结构体定义字符串数组,C语言,结构体中字符串的声明(采用字符指针还是字符数组)...
  8. IntelliJ IDEA查看方法在哪里被调用(Usage Search/Call Hierarchy)
  9. php输出分组,ThinkPHP 项目分组中的模板输出
  10. python中关键字global的简单理解