源码论坛,商业源码下载,尽在锦尚中国商业源码论坛

标题: FCKEditor漏洞大揭密 [打印本页]

作者: baidus    时间: 2009-10-29 11:42
标题: FCKEditor漏洞大揭密
milw0rm公布了FCKEditor的一个上传漏洞[1]。FCKEditor是一款有多个语
言版本的(asp,cgi,aspx,php,cfm,...)的在线编辑的class[2],很多web系统都使用了这
个class。其实这个东西的漏洞,国内早有人挖过,比如asp版(nb文章系统由于使用这个
导致的上传漏洞),这里我们看看php版本的:

\editor\filemanager\browser\default\connectors\php\config.php

行35-36:

$Config['AllowedExtensions']['File'] = array() ; //允许的上穿类型
$Config['DeniedExtensions']['File'] = array('php','php3','php5','phtml','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','dll','reg','cgi') ;//禁止上传的类型

我们看$Config['DeniedExtensions']['File']里禁止的类型显然不够,我们可以上传php2、php4、inc、pwml、asa、cer ...等等。我们在看看具体的upfile函数

\editor\filemanager\browser\default\connectors\php\commands.php

function FileUpload( $resourceType, $currentFolder )
{
         .......................

  $sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
  $sExtension = strtolower( $sExtension ) ; //得到文件的后缀(以.为标志取最后1个)

  global $Config ;

  $arAllowed = $Config['AllowedExtensions'][$resourceType] ;
  $arDenied = $Config['DeniedExtensions'][$resourceType] ;

  if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) ) //判断合法后缀
  {
   $iCounter = 0 ;

   while ( true )
   {
    $sFilePath = $sServerDir . $sFileName ;

    .......................

                            move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
//上传 注意它保存的文件直接用的$sFilePath = $sServerDir . $sFileName,而没有使用$sExtension为后缀
//导致在win下在上传文件后面加个.来突破[未测试][3]
                            ........................
}

为什么说这个漏洞为"意识漏洞"呢?如果我们把AllowedExtensions/DeniedExtensions的设置"反"一下:

$Config['AllowedExtensions']['File'] = array('rar','zip') ; //允许的上穿类型
$Config['DeniedExtensions']['File'] = array() ;//禁止上传的类型

把设置DeniedExtensions改为设置AllowedExtensions,就不会出现上面的漏洞了,不过这样在某些情况下,照样可以突破,问题还是出在这里:

move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;
//上传 注意它保存的文件直接用的$sFilePath = $sServerDir . $sFileName,而没有使用$sExtension为后缀

在apache下,因为"apache文件名解析缺陷漏洞"[3]而出现漏洞[未测试]。

小结:
   其实很多web程序员都有这个"意识漏洞",在过滤上传文件类型时,不应该‘被动’的去过滤非法后缀,应该是‘主动’过滤允许上传的类型。

参考:
[1] FCKEditor 2.0 <= 2.2 (connector.php) Remote Shell Upload Exploit
http://www.milw0rm.com/id.php?id=1484

[2] FCKEditor官方 :http://www.fckeditor.net/

[3] 《系统特性与web安全》

以前发过一个fckeditor的上传文件漏洞:http://superhei.blogbus.com/logs/2006/02/1916091.html
我们看看新版本2.4的,还是被动过滤:

config.php:

$Config['AllowedExtensions']['File']    = array() ;
$Config['DeniedExtensions']['File']        = array('html','htm','php','php2','php3','php4','php5','phtml','pwml','inc','asp','aspx','ascx','jsp','cfm','cfc','pl','bat','exe','com','dll','vbs','js','reg','cgi','htaccess','asis') ;

字典越来越大啊 :) 。我们先测试先以前的exp
上穿aa.php. 这样的文件结果变成了 aa_php. 看来还有其他变化啊:

function FileUpload( $resourceType, $currentFolder )
{
    $sErrorNumber = '0' ;
    $sFileName = '' ;

            ..........
        // Replace dots in the name with underscores (only one dot can be there... security issue).
        if ( $Config['ForceSingleExtension'] ) //多了个$Config['ForceSingleExtension']的配置 默认是ture
            $sFileName = preg_replace( '/\\.(?![^.]*$)/', '_', $sFileName ) ; //这里替换了文件名里多余的. 即:1.1.php-->1_1.php

        $sOriginalFileName = $sFileName ;

        // Get the extension.
        $sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
        $sExtension = strtolower( $sExtension ) ; //替换后取后缀,因为上面的替换所以保证了文件名里只有一个.  即:1_1.php--->php

        $arAllowed    = $Config['AllowedExtensions'][$resourceType] ;
        $arDenied    = $Config['DeniedExtensions'][$resourceType] ;

        if ( ( count($arAllowed) == 0 || in_array( $sExtension, $arAllowed ) ) && ( count($arDenied) == 0 || !in_array( $sExtension, $arDenied ) ) )//判断
        {
          .............

                if ( is_file( $sFilePath ) )

                {
                    $iCounter++ ;
                    $sFileName = RemoveExtension( $sOriginalFileName ) . '(' . $iCounter . ').' . $sExtension ;

/*
这里判断有没有相同的文件名,如果有这改为在后缀前加一个(n). 如:_phs-->(1)._phs
那么我们可以利用产生的这个(n).不呢?答案是:NO 因为我们提交_php 经过     
// Get the extension.
$sExtension = substr( $sFileName, ( strrpos($sFileName, '.') + 1 ) ) ;
$sExtension = strtolower( $sExtension ) ;
这里时strrpos($sFileName, '.')为空所以 还是:_php-->php 这个是没有办法通过上面的判断语句的
*/


                    $sErrorNumber = '201' ;

                }
                else
                {
                    move_uploaded_file( $oFile['tmp_name'], $sFilePath ) ;


通过上面的分析,好象没办法了?。呵呵 我们可以不用.嘛,在win下还有一个空格呢 :) 提交1.php+空格 就可以过去所有的拉 hoho
不过空格只支持win系统 *nix是不支持的[1.php和1.php+空格是2个不同的文件]

最后说明下,默认fckeditor是不让上传文件的:config.php:

// SECURITY: You must explicitelly enable this "connector". (Set it to "true").
$Config['Enabled'] = false  ;

最后bs下fckeditor,为了被动的过滤,费了多少事啊 最后还是有问题!意识问题!!!??
作者: a263    时间: 2009-10-29 12:46
支持
作者: mqgds    时间: 2009-10-29 14:41
没用过,学习一下!!!
作者: sogo    时间: 2009-11-3 15:31
没用过,学习一下!!!




欢迎光临 源码论坛,商业源码下载,尽在锦尚中国商业源码论坛 (https://bbs.52jscn.com/) Powered by Discuz! X3.3