返回介绍

8.1.2 编码转换问题

发布于 2024-10-11 22:07:45 字数 2754 浏览 0 评论 0 收藏 0

本书前面第 4 章介绍过宽字节注入,这就是一种非常典型的编码转换问题导致绕过 GPC 的方式。我们之前的举例说明,给一个查询页面 ID 参数请求/1.php?id=-1%df’and 1=1%23 时,这时 MySQL 运行的 SQL 语句为:

select * from user where id= ’ 1 運’ and 1=1# ’

这是由于单引号被自动转义成\’,前面的%df 和转义字符\反斜杠(%5c)组合成了%df%5c,也就是“運”字,这时候单引号依然还在,于是成功闭合了前面的单引号。

这个例子讲的是 PHP 与 MySQL 交互过程中发生编码转换导致的问题,而其实只要发生编码转换就有可能出现这种问题,也就是说在 PHP 自带的编码转换函数上面也会存在这个问题,比如 mb_convert_encoding() 函数。

我们来证实一下,代码如下:

<meta http-equiv="Content-Type" content="text/html ; charset=utf-8"/>

<?php

$sql="where id='".urldecode ( "-1%df%5c' -- " ) ."'" ; 

print_r ( mb_convert_encoding ( $sql , "UTF-8" , "GBK" ));? >

这里要注意的是,把网页和文件编码都设置成 UTF-8,不然浏览器会自动转码,这段代码是把 UTF-8 编码转换成 GBK,运行这段代码,输出如下:

where id='-1 運 ' -- '

可以看到也成功闭合了前面的单引号。

这种方式造成的 SQL 注入也有不少先例,比如 ecshop 就出过多次这个问题,我们来看看出现这个问题的核心代码,代码位置在 includes/cls_iconv.php 文件的 chinese 类中的 Convert() 函数:

function Convert ( $source_lang , $target_lang , $source_string = '' ) 

{

/****** 省略 ****/

  if (( $this->iconv_enabled || $this->mbstring_enabled ) && !( $this-> config['source_lang'] == 'GBK' && $this->config['target_lang'] == 'BIG-5' )) 

     {

     if ( $this->config['target_lang'] ! = 'UNICODE' ) 

     {

       $string = $this->_convert_iconv_mbstring ( $this-> SourceText , $this->config['target_lang'] , $this-> config['source_lang'] ); 

       /* 如果正确转换 */

       if ( $string ) 

       {

        return $string ; 

       }

     }

     else

     {

      $string = '' ; 

      $text = $SourceText ; 

      while ( $text ) 

      {

        if ( ord ( substr ( $text , 0 , 1 )) > 127 ) 

        {

        if ( $this->config['source_lang'] ! = 'UTF-8' ) 

        {

          $char = $this->_convert_iconv_mbstring ( substr ( $text , 0 , 2 ), 'UTF-8' , $this->config ['source_lang'] ); 

        }

        else

这个函数的作用是将 UTF-8 的编码转换成 GBK,本函数调用到$this->_convert_iconv_mbstring() 函数,我们跟进去看看,代码如下:

function _convert_iconv_mbstring ( $string , $target_lang , $source_lang ) 

{

  if ( $this->iconv_enabled ) 

  {

    $return_string = @iconv ( $source_lang , $target_lang , $string ); 

    if ( $return_string ! == false ) 

    {

    return $return_string ; 

    }

  }

  if ( $this->mbstring_enabled ) 

  {

    if ( $source_lang == 'GBK' ) 

    {

    $source_lang = 'CP936' ; 

    }

    if ( $target_lang == 'GBK' ) 

    {

    $target_lang = 'CP936' ; 

    }

    $return_string = @mb_convert_encoding ( $string , $target_lang , $source_lang ); 

    if ( $return_string ! == false )

可以看到最终调用 iconv() 函数或者 mb_convert_encoding() 函数来进行转码,如果调用这个函数之后没有再次过滤,则会存在注入问题。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文