文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
8.1.2 编码转换问题
本书前面第 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论