黑客24小时在线接单网站

电脑高手24在线咨询,黑客24小时在线接单网站,黑客接单平台,黑客网站找人,黑客在线qq接单

科普:宽字节注入详解

前言

在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测试代码:

  • <!DOCTYPEhtml>
  • <metacharset="gbk"><!--仅用于基础显示,替换为utf8也就是不好看-->
  • <?php
  • error_reporting(0);
  • $conn=mysql_connect('127.0.0.1','root','');
  • mysql_select_db('mysql',$conn);
  • mysql_query("setnamesgbk");///不安全的编码设置方法
  • $res=mysql_query("showvariableslike'character%';");///显示当前数据库设置的字符集
  • while($row=mysql_fetch_array($res)){
  • var_dump($row);
  • }
  • $user=addslashes($_GET['sql']);//mysql_real_escape_string()magic_quote_gpc=Onaddslashes()mysql_escape_string()功能类似
  • $sql="SELECThost,user,passwordFROMuserWHEREuser='{$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?' or 1=1#

    可以成功执行!

    科普:宽字节注入详解

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

    解析过程:

    $_GET[‘sql’] 经过 addslashes编码后带入‘\’
    1、root?\' or 1=1#
    2、带入mysql用于处理gbk字符集
    ?\ -> 运 成功吃了\
    ' -> ‘ 单引号成功闭合

    执行插入sql语句。

    怎么吃的:

    GBK编码,其编码范围为0×8140~0xFEFE(不包括xx7F),在遇到?(ascii(223)) >ascii(128)自动拼接\,因此吃掉‘\’,而且, 小于ascii(128)字符保留。

    补充:

    GB2312是被GBK兼容,高位范围是0xA1~0xF7,低位范围是0xA1~0xFE(0x5C不在这个范围内),不能用编码吃\。

    其他宽字符集也有相同的分析过程,要吃\,只需要在低位包含正常内容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传入的字符串可以根据当前的字符集进行过滤。

    具体差异可参考:http://www.laruence.com/2010/04/12/1396.html

    同理可得

    从上面可以看出,宽字节注入是由转编码形成的,具有转编码功能的函数也成为漏洞的原因。

    转码函数

    mb_convert_encoding()

    iconv()

    以下用iconv()演示并修改上述代码:

  • <!DOCTYPEhtml>
  • <metacharset="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="SELECThost,user,passwordFROMuserWHEREuser='{$user}'";
  • echo$sql.'</br>';
  • $res=mysql_query($sql);
  • while($row=mysql_fetch_array($res)){
  • var_dump($row);
  • }
  • ?>

  • http://localhost/xl.php?sql=root?'or 1=1#

    编码分析的过程也可以成功执行。

    总结漏洞的原因:

    代码一

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

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

    代码二

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

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

    3、PHP请求mysql转码安全。

    另外:

    改变编码方向时$user = iconv(‘UTF-8′,’gbk’,$user);

    通过访问http://localhost/xl.php?sql=root锦可以带一个\,然后注释掉单引号。

    注入需要两个参数。

    例如:

    http://localhost/xl.php?sql=root锦¶= or 1=1#

    总结:

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

    Mysql建议使用编码和过滤函数mysql_real_escape_string(),mysql_set_charset()。

    即使使使用了安全的设置函数,转编码函数也会导致宽字节注入。

       
    • 评论列表:
    •  纵遇忆囚
       发布于 2022-05-29 08:46:56  回复该评论
    • 的字符集。同时配套的过滤函数为mysql_real_escape_string()。上述代码中列出了几个过滤函数,它们之间的区别是mysql_real_escape_string()会根据mysql对象中的mysql->charset
    •  酒奴卮酒
       发布于 2022-05-29 10:48:38  回复该评论
    • 码中列出了几个过滤函数,它们之间的区别是mysql_real_escape_string()会根据mysql对象中的mysql->charset传入的字符串可以根据当前的字符集进行
    •  世味悸初
       发布于 2022-05-29 15:44:03  回复该评论
    • 除。首先,注入宽字节HTML页面编码无关,作者曾经看到过<meta charset=utf8>放弃尝试是一种误解,SQL注入不是XSS。虽然编码的原因相似,但发生在不同的地方。许多在线材料说,程序使用宽字节来处理程
    •  痴者掩灼
       发布于 2022-05-29 13:11:10  回复该评论
    • 套的过滤函数为mysql_real_escape_string()。上述代码中列出了几个过滤函数,它们之间的区别是mysql_real_escape_string()会根据mysql对象中的mysql->charset传入的字符串可以根据当前的字符集进行过滤。具体差异可参考:ht

    发表评论:

    Powered By

    Copyright Your WebSite.Some Rights Reserved.